웹 프론트엔드 JS 튜토리얼 JS 멀티스레드 런타임 라이브러리 Nexus.js 사용에 대한 자세한 설명

JS 멀티스레드 런타임 라이브러리 Nexus.js 사용에 대한 자세한 설명

Apr 14, 2018 am 09:48 AM
javascript 달리다

이번에는 JS 멀티스레드 런타임 라이브러리 Nexus.js를 사용하는 방법에 대해 자세히 설명하겠습니다. JS 멀티스레드 런타임 라이브러리 Nexus.js를 사용할 때 주의사항은 무엇인가요? 보세요.

우선, 이 프로젝트에 대해 잘 모르신다면 이전에 쓴 일련의 기사를 읽어 보시기를 권장합니다. 이 글을 읽고 싶지 않다면 걱정하지 마세요. 해당 내용도 여기에서 다루겠습니다.

이제 시작해 보겠습니다.

작년에 저는 Webkit/JavaScript 커널을 기반으로 하는 다중 스레드 서버측 JavaScript 런타임인 Nexus.js를 구현하기 시작했습니다. 나는 한동안 그 일을 포기했습니다. 제가 통제할 수 없는 이유로 여기서는 논의하지 않겠습니다. 주로: 오랫동안 일을 할 수 없었습니다.

이제 Nexus의 아키텍처와 작동 방식에 대해 논의하는 것부터 시작하겠습니다.

이벤트 루프

이벤트 루프 없음

(잠금 없는) 작업 개체가 있는 스레드 풀이 있습니다

setTimeout 또는 setImmediate가 호출되거나 Promise가 생성될 때마다 작업은 작업 대기열에 추가됩니다.

작업이 예약될 때마다 사용 가능한 첫 번째 스레드가 작업을 선택하고 실행합니다.

Promise는 CPU 코어에서 처리됩니다. Promise.all()을 호출하면 Promise가 병렬로 해결됩니다.

ES6

async/await를 지원하며 사용을 권장합니다

대기(...)

지원 해체 지원

비동기 try/catch/finally 지원

모듈

CommonJS는 지원되지 않습니다. (require(...) 및 module.exports)

모든 모듈은 ES6 가져오기/내보내기 구문을 사용합니다

import('file-or-packge').then(...)

을 통해 동적 가져오기 지원 import.meta.filename 및 import.meta.dirname 등과 같은 import.meta를 지원합니다.

추가 기능: URL에서 직접 가져오기 지원(예:

import { h } from 'https://unpkg.com/preact/dist/preact.esm.js';
로그인 후 복사

) EventEmitter

Nexus는 Promise 기반 EventEmitter 클래스를 구현합니다

이벤트 처리프로그램은 모든 스레드에서 순서대로 실행되며 병렬로 실행됩니다.

EventEmitter.emit(...)의 반환 값은 이벤트 핸들러에서 반환 값 배열로 구문 분석될 수 있는 Promise입니다.

예:

class EmitterTest extends Nexus.EventEmitter {
 constructor() {
  super();
  for(let i = 0; i < 4; i++)
   this.on(&#39;test&#39;, value => { console.log(`fired test ${i}!`); console.inspect(value); });
  for(let i = 0; i < 4; i++)
   this.on(&#39;returns-a-value&#39;, v => `${v + i}`);
 }
}
const test = new EmitterTest();
async function start() {
 await test.emit('test', { payload: 'test 1' });
 console.log('first test done!');
 await test.emit('test', { payload: 'test 2' });
 console.log('second test done!');
 const values = await test.emit('returns-a-value', 10);
 console.log('third test done, returned values are:'); console.inspect(values);
}
start().catch(console.error);
로그인 후 복사

I/O

모든 입력/출력은 Device, Filter 및 Stream의 세 가지 기본 요소를 통해 수행됩니다.

모든 입력/출력 프리미티브는 EventEmitter 클래스를 구현합니다

Device를 사용하려면 Device

위에 ReadableStream 또는 WritableStream을 생성해야 합니다. 데이터를 조작하기 위해 ReadableStream 또는 WritableStream에 필터를 추가할 수 있습니다.

마지막으로 source.pipe(...destinationStreams)를 사용하고 source.resume()이 데이터를 처리할 때까지 기다립니다.

모든 입력/출력 작업은 ArrayBuffer 개체를 사용하여 수행됩니다.

필터는 데이터 처리를 위해 process(buffer) 방식을 시도했습니다.

예: 2개의 별도 출력 파일을 사용하여 UTF-8을 UTF6으로 변환합니다.

rreee

TCP/UDP

Nexus.js는 IP 주소/포트 바인딩 및 연결 모니터링을 담당하는 Acceptor 클래스를 제공합니다

연결 요청이 수신될 때마다 연결 이벤트가 트리거되고 소켓 장치가 제공됩니다.

각 소켓 인스턴스는 전이중 I/O 장치입니다.

ReadableStream 및 WritableStream을 사용하여 소켓을 작동할 수 있습니다.

가장 기본적인 예: (클라이언트에게 "Hello World" 보내기)

const startTime = Date.now();
 try {
  const device = new Nexus.IO.FilePushDevice('enwik8');
  const stream = new Nexus.IO.ReadableStream(device);
  stream.pushFilter(new Nexus.IO.EncodingConversionFilter("UTF-8", "UTF-16LE"));
  const wstreams = [0,1,2,3]
   .map(i => new Nexus.IO.WritableStream(new Nexus.IO.FileSinkDevice('enwik16-' + i)));
  console.log('piping...');
  stream.pipe(...wstreams);
  console.log('streaming...');
  await stream.resume();
  await stream.close();
  await Promise.all(wstreams.map(stream => stream.close()));
  console.log(`finished in ${(Date.now() * startTime) / 1000} seconds!`);
 } catch (e) {
  console.error('An error occurred: ', e);
 }
}
start().catch(console.error);
로그인 후 복사

Http

Nexus는 기본적으로 TCPAcceptor

를 상속하는 Nexus.Net.HTTP.Server 클래스를 제공합니다. 몇 가지 기본 인터페이스

当服务器端完成了对传入连接的基本的Http头的解析/校验时,将使用连接和同样的信息触发connection事件

每一个连接实例都又一个request和一个response对象。这些是输入/输出设备。

你可以构造ReadableStream和WritableStream来操纵request/response。

如果你通过管道连接到一个Response对象,输入的流将会使用分块编码的模式。否者,你可以使用response.write()来写入一个常规的字符串

复杂例子:(基本的Http服务器与块编码,细节省略)

....
/**
 * Creates an input stream from a path.
 * @param path
 * @returns {Promise<ReadableStream>}
 */
async function createInputStream(path) {
 if (path.startsWith('/')) // If it starts with '/', omit it.
  path = path.substr(1);
 if (path.startsWith('.')) // If it starts with '.', reject it.
  throw new NotFoundError(path);
 if (path === '/' || !path) // If it's empty, set to index.html.
  path = 'index.html';
 /**
  * `import.meta.dirname` and `import.meta.filename` replace the old CommonJS `dirname` and `filename`.
  */
 const filePath = Nexus.FileSystem.join(import.meta.dirname, 'server_root', path);
 try {
  // Stat the target path.
  const {type} = await Nexus.FileSystem.stat(filePath);
  if (type === Nexus.FileSystem.FileType.Directory) // If it's a directory, return its 'index.html'
   return createInputStream(Nexus.FileSystem.join(filePath, 'index.html'));
  else if (type === Nexus.FileSystem.FileType.Unknown || type === Nexus.FileSystem.FileType.NotFound)
   // If it's not found, throw NotFound.
   throw new NotFoundError(path);
 } catch(e) {
  if (e.code)
   throw e;
  throw new NotFoundError(path);
 }
 try {
  // First, we create a device.
  const fileDevice = new Nexus.IO.FilePushDevice(filePath);
  // Then we return a new ReadableStream created using our source device.
  return new Nexus.IO.ReadableStream(fileDevice);
 } catch(e) {
  throw new InternalServerError(e.message);
 }
}
/**
 * Connections counter.
 */
let connections = 0;
/**
 * Create a new HTTP server.
 * @type {Nexus.Net.HTTP.Server}
 */
const server = new Nexus.Net.HTTP.Server();
// A server error means an error occurred while the server was listening to connections.
// We can mostly ignore such errors, we display them anyway.
server.on('error', e => {
 console.error(FgRed + Bright + 'Server Error: ' + e.message + '\n' + e.stack, Reset);
});
/**
 * Listen to connections.
 */
server.on('connection', async (connection, peer) => {
 // Start with a connection ID of 0, increment with every new connection.
 const connId = connections++;
 // Record the start time for this connection.
 const startTime = Date.now();
 // Destructuring is supported, why not use it?
 const { request, response } = connection;
 // Parse the URL parts.
 const { path } = parseURL(request.url);
 // Here we'll store any errors that occur during the connection.
 const errors = [];
 // inStream is our ReadableStream file source, outStream is our response (device) wrapped in a WritableStream.
 let inStream, outStream;
 try {
  // Log the request.
  console.log(`> #${FgCyan + connId + Reset} ${Bright + peer.address}:${peer.port + Reset} ${
   FgGreen + request.method + Reset} "${FgYellow}${path}${Reset}"`, Reset);
  // Set the 'Server' header.
  response.set('Server', `nexus.js/0.1.1`);
  // Create our input stream.
  inStream = await createInputStream(path);
  // Create our output stream.
  outStream = new Nexus.IO.WritableStream(response);
  // Hook all `error` events, add any errors to our `errors` array.
  inStream.on('error', e => { errors.push(e); });
  request.on('error', e => { errors.push(e); });
  response.on('error', e => { errors.push(e); });
  outStream.on('error', e => { errors.push(e); });
  // Set content type and request status.
  response
   .set('Content-Type', mimeType(path))
   .status(200);
  // Hook input to output(s).
  const disconnect = inStream.pipe(outStream);
  try {
   // Resume our file stream, this causes the stream to switch to HTTP chunked encoding.
   // This will return a promise that will only resolve after the last byte (HTTP chunk) is written.
   await inStream.resume();
  } catch (e) {
   // Capture any errors that happen during the streaming.
   errors.push(e);
  }
  // Disconnect all the callbacks created by `.pipe()`.
  return disconnect();
 } catch(e) {
  // If an error occurred, push it to the array.
  errors.push(e);
  // Set the content type, status, and write a basic message.
  response
   .set('Content-Type', 'text/plain')
   .status(e.code || 500)
   .send(e.message || 'An error has occurred.');
 } finally {
  // Close the streams manually. This is important because we may run out of file handles otherwise.
  if (inStream)
   await inStream.close();
  if (outStream)
   await outStream.close();
  // Close the connection, has no real effect with keep-alive connections.
  await connection.close();
  // Grab the response's status.
  let status = response.status();
  // Determine what colour to output to the terminal.
  const statusColors = {
   '200': Bright + FgGreen, // Green for 200 (OK),
   '404': Bright + FgYellow, // Yellow for 404 (Not Found)
   '500': Bright + FgRed // Red for 500 (Internal Server Error)
  };
  let statusColor = statusColors[status];
  if (statusColor)
   status = statusColor + status + Reset;
  // Log the connection (and time to complete) to the console.
  console.log(`< #${FgCyan + connId + Reset} ${Bright + peer.address}:${peer.port + Reset} ${
   FgGreen + request.method + Reset} "${FgYellow}${path}${Reset}" ${status} ${(Date.now() * startTime)}ms` +
   (errors.length ? " " + FgRed + Bright + errors.map(error => error.message).join(', ') + Reset : Reset));
 }
});
/**
 * IP and port to listen on.
 */
const ip = '0.0.0.0', port = 3000;
/**
 * Whether or not to set the `reuse` flag. (optional, default=false)
 */
const portReuse = true;
/**
 * Maximum allowed concurrent connections. Default is 128 on my system. (optional, system specific)
 * @type {number}
 */
const maxConcurrentConnections = 1000;
/**
 * Bind the selected address and port.
 */
server.bind(ip, port, portReuse);
/**
 * Start listening to requests.
 */
server.listen(maxConcurrentConnections);
/**
 * Happy streaming!
 */
console.log(FgGreen + `Nexus.js HTTP server listening at ${ip}:${port}` + Reset);
로그인 후 복사

基准

我想我已经涵盖了到目前为止所实现的一切。那么现在我们来谈谈性能。

这里是上诉Http服务器的当前基准,有100个并发连接和总共10000个请求:

This is ApacheBench, Version 2.3 <$Revision: 1796539 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient).....done
Server Software:    nexus.js/0.1.1
Server Hostname:    localhost
Server Port:      3000
Document Path:     /
Document Length:    8673 bytes
Concurrency Level:   100
Time taken for tests:  9.991 seconds
Complete requests:   10000
Failed requests:    0
Total transferred:   87880000 bytes
HTML transferred:    86730000 bytes
Requests per second:  1000.94 [#/sec] (mean)
Time per request:    99.906 [ms] (mean)
Time per request:    0.999 [ms] (mean, across all concurrent requests)
Transfer rate:     8590.14 [Kbytes/sec] received
Connection Times (ms)
       min mean[+/-sd] median  max
Connect:    0  0  0.1   0    1
Processing:   6  99 36.6   84   464
Waiting:    5  99 36.4   84   463
Total:     6 100 36.6   84   464
Percentage of the requests served within a certain time (ms)
 50%   84
 66%   97
 75%  105
 80%  112
 90%  134
 95%  188
 98%  233
 99%  238
 100%  464 (longest request)
로그인 후 복사

每秒1000个请求。在一个老的i7上,上面运行了包括这个基准测试软件,一个占用了5G内存的IDE,以及服务器本身。

voodooattack@voodooattack:~$ cat /proc/cpuinfo 
processor  : 0
vendor_id  : GenuineIntel
cpu family : 6
model    : 60
model name : Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
stepping  : 3
microcode  : 0x22
cpu MHz   : 3392.093
cache size : 8192 KB
physical id : 0
siblings  : 8
core id   : 0
cpu cores  : 4
apicid   : 0
initial apicid : 0
fpu   : yes
fpu_exception  : yes
cpuid level : 13
wp   : yes
flags    : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm cpuid_fault tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts
bugs    :
bogomips  : 6784.18
clflush size  : 64
cache_alignment : 64
address sizes  : 39 bits physical, 48 bits virtual
power management:
로그인 후 복사

我尝试了1000个并发请求,但是APacheBench由于许多套接字被打开而超时。我尝试了httperf,这里是结果:

voodooattack@voodooattack:~$ httperf --port=3000 --num-conns=10000 --rate=1000
httperf --client=0/1 --server=localhost --port=3000 --uri=/ --rate=1000 --send-buffer=4096 --recv-buffer=16384 --num-conns=10000 --num-calls=1
httperf: warning: open file limit > FD_SETSIZE; limiting max. # of open files to FD_SETSIZE
Maximum connect burst length: 262
Total: connections 9779 requests 9779 replies 9779 test-duration 10.029 s
Connection rate: 975.1 conn/s (1.0 ms/conn, <=1022 concurrent connections)
Connection time [ms]: min 0.5 avg 337.9 max 7191.8 median 79.5 stddev 848.1
Connection time [ms]: connect 207.3
Connection length [replies/conn]: 1.000
Request rate: 975.1 req/s (1.0 ms/req)
Request size [B]: 62.0
Reply rate [replies/s]: min 903.5 avg 974.6 max 1045.7 stddev 100.5 (2 samples)
Reply time [ms]: response 129.5 transfer 1.1
Reply size [B]: header 89.0 content 8660.0 footer 2.0 (total 8751.0)
Reply status: 1xx=0 2xx=9779 3xx=0 4xx=0 5xx=0
CPU time [s]: user 0.35 system 9.67 (user 3.5% system 96.4% total 99.9%)
Net I/O: 8389.9 KB/s (68.7*10^6 bps)
Errors: total 221 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 221 addrunavail 0 ftab-full 0 other 0
로그인 후 복사

正如你看到的,它任然能工作。尽管由于压力,有些连接会超时。我仍在研究导致这个问题的原因。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

JS做出移动端触摸轮播效果

JS怎样将json格式数组下载到excel表格里

위 내용은 JS 멀티스레드 런타임 라이브러리 Nexus.js 사용에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Linux 시스템에서 .sh 파일을 실행하는 방법은 무엇입니까? Linux 시스템에서 .sh 파일을 실행하는 방법은 무엇입니까? Mar 14, 2024 pm 06:42 PM

Linux 시스템에서 .sh 파일을 실행하는 방법은 무엇입니까? Linux 시스템에서 .sh 파일은 일련의 명령을 실행하는 데 사용되는 셸 스크립트라는 파일입니다. .sh 파일 실행은 매우 일반적인 작업입니다. 이 기사에서는 Linux 시스템에서 .sh 파일을 실행하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 방법 1: 절대 경로를 사용하여 .sh 파일을 실행합니다. Linux 시스템에서 .sh 파일을 실행하려면 절대 경로를 사용하여 파일 위치를 지정할 수 있습니다. 구체적인 단계는 다음과 같습니다. 터미널을 엽니다.

PyCharm 사용 튜토리얼: 작업 실행에 대해 자세히 안내합니다. PyCharm 사용 튜토리얼: 작업 실행에 대해 자세히 안내합니다. Feb 26, 2024 pm 05:51 PM

PyCharm은 매우 인기 있는 Python 통합 개발 환경(IDE)으로 Python 개발을 더욱 효율적이고 편리하게 만들어주는 다양한 기능과 도구를 제공합니다. 이 기사에서는 PyCharm의 기본 작동 방법을 소개하고 독자가 도구 작동을 빠르게 시작하고 능숙하게 사용할 수 있도록 구체적인 코드 예제를 제공합니다. 1. PyCharm 다운로드 및 설치 먼저 PyCharm 공식 웹사이트(https://www.jetbrains.com/pyc)로 이동해야 합니다.

WebSocket과 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법 WebSocket과 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법 Dec 17, 2023 pm 02:54 PM

WebSocket 및 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법 소개: 지속적인 기술 개발로 음성 인식 기술은 인공 지능 분야의 중요한 부분이 되었습니다. WebSocket과 JavaScript를 기반으로 한 온라인 음성 인식 시스템은 낮은 대기 시간, 실시간, 크로스 플랫폼이라는 특징을 갖고 있으며 널리 사용되는 솔루션이 되었습니다. 이 기사에서는 WebSocket과 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법을 소개합니다.

Windows 7에서 exe 파일을 실행할 수 없는 이유 Windows 7에서 exe 파일을 실행할 수 없는 이유 Feb 18, 2024 pm 08:32 PM

win7에서 exe 파일을 실행할 수 없는 이유는 무엇입니까? Windows7 운영 체제를 사용할 때 많은 사용자가 exe 파일을 실행할 수 없는 일반적인 문제에 직면할 수 있습니다. exe 파일은 Windows 운영 체제에서 일반적으로 사용되는 실행 파일로 다양한 응용 프로그램을 설치하고 실행하는 데 사용됩니다. 그러나 일부 사용자는 exe 파일을 실행하려고 할 때 시스템이 응답하지 않거나 오류 메시지를 표시하는 것을 발견할 수 있습니다. 이 문제에는 여러 가지 이유가 있습니다. 다음은 몇 가지 일반적인 원인과 해당 해결 방법입니다.

Windows 7에서 bat 파일을 실행할 수 없는 이유는 무엇입니까? Windows 7에서 bat 파일을 실행할 수 없는 이유는 무엇입니까? Feb 19, 2024 pm 03:19 PM

win7에서 bat 파일을 실행할 수 없는 이유는 무엇입니까? 최근 Windows7 운영 체제를 사용하는 많은 사용자가 .bat 파일을 실행할 수 없다고 보고했습니다. 이는 광범위한 논의와 혼란을 불러일으켰습니다. 잘 작동하는 운영 체제에서 간단한 .bat 파일을 실행할 수 없는 이유는 무엇입니까? 먼저 .bat 파일의 배경을 이해해야 합니다. 배치 파일이라고도 하는 .bat 파일은 Windows 명령 해석기(cmd.ex)에서 사용할 수 있는 일련의 명령이 포함된 일반 텍스트 파일입니다.

matlab에서 m-파일을 실행하는 방법 - matlab에서 m-파일을 실행하는 방법에 대한 튜토리얼 matlab에서 m-파일을 실행하는 방법 - matlab에서 m-파일을 실행하는 방법에 대한 튜토리얼 Mar 04, 2024 pm 02:13 PM

matlab에서 m 파일을 실행하는 방법을 아시나요? 아래에서 matlab에서 m 파일을 실행하는 방법에 대한 튜토리얼을 가져오겠습니다. 1. 먼저 matlab을 열어보세요. 소프트웨어를 선택하고 아래 그림과 같이 왼쪽 상단 모서리 "열기"를 선택합니다. 2. 그리고 아래 그림과 같이 실행할 m 파일을 선택하고 엽니다. 3. 아래 그림과 같이 창에서 F5 키를 눌러 프로그램을 실행합니다. 4. 아래 그림과 같이 명령줄 창과 작업 공간에서 실행 결과를 볼 수 있습니다. 5. 아래 그림과 같이 "실행"을 직접 클릭하여 파일을 실행할 수도 있습니다. 6. 마지막으로 아래 그림과 같이 명령줄 창과 작업 공간에서 m 파일의 실행 결과를 볼 수 있습니다. 위는 편집자가 가져온 MATLAB 방법입니다.

WebSocket 및 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 WebSocket 및 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 Dec 17, 2023 pm 05:30 PM

WebSocket과 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 서론: 인터넷 기술의 급속한 발전과 함께 실시간 모니터링 시스템이 다양한 분야에서 널리 활용되고 있다. 실시간 모니터링을 구현하는 핵심 기술 중 하나는 WebSocket과 JavaScript의 조합입니다. 이 기사에서는 실시간 모니터링 시스템에서 WebSocket 및 JavaScript의 적용을 소개하고 코드 예제를 제공하며 구현 원칙을 자세히 설명합니다. 1. 웹소켓 기술

어떤 win10 버전이 가장 빠르게 실행되나요? 어떤 win10 버전이 가장 빠르게 실행되나요? Jan 05, 2024 pm 05:29 PM

Microsoft의 새로운 시스템인 Windows 10과 관련하여 친구들은 어떤 버전의 Windows 10 운영 체제가 가장 빠르고 원활하게 실행되는지 알고 싶어합니다. 버전 업데이트는 실제로 시스템 콘텐츠 및 기능에 대한 업데이트 및 결함 수리입니다. 가장 빠르게 실행되는 win10 버전은 무엇입니까? 1. win10의 각 버전 간의 차이점은 주로 해당 기능에 있습니다. 2. 다른 기능을 제외하고 다른 측면은 동일합니다. 3. win10의 다양한 버전 간에는 큰 차이가 없습니다. 실행 속도 측면에서 가장 큰 차이점은 자신의 컴퓨터 구성을 살펴보십시오. ~ win10 Home Edition: 1. Win10 Home Edition은 보급형 시스템 버전인 win8.1의 핵심 버전과 동일합니다. 2. win10 홈 버전의 국가별 버전은 win8.1의 OEM 중국어 버전과 동일합니다.

See all articles