Versie npmBuildWindows x86 BuildBedekkingsstatus

ws is een eenvoudig te gebruiken, razendsnelle en grondig geteste WebSocket-client en -serverimplementatie.

Slaagt voor de vrij uitgebreide Autobahn testsuite: server, client.

Note: deze module werkt niet in de browser. De client in de docs is een verwijzing naar een back end met de rol van een client in de WebSocket communicatie. Browser clients moeten het nativeWebSocketobject gebruiken. Om dezelfde code naadloos te laten werken op Node.js en de browser, kun je een van de vele wrappers gebruiken die beschikbaar zijn op npm, zoalsisomorphic-ws.

Inhoudsopgave

  • Protocolondersteuning
  • Installatie
    • Opt-in voor performance en spec compliance
  • API docs
  • WebSocket compressie
  • Gebruiksvoorbeelden
    • Versturen en ontvangen van tekstgegevens
    • Versturen van binaire data
    • Eenvoudige server
    • Externe HTTP/S server
    • Meerdere servers die één HTTP/S server delen
    • Client authenticatie
    • Server broadcast
    • echo.websocket.org demo
    • Gebruik de Node.js streams API
    • Andere voorbeelden
  • FAQ
    • Hoe krijg ik het IP adres van de client?
    • Hoe detecteer en sluit ik verbroken verbindingen?
    • Hoe maak ik verbinding via een proxy?
  • Changelog
  • Licentie

Protocol ondersteuning

  • HyBi drafts 07-12 (Gebruik de optie protocolVersion: 8)
  • HyBi drafts 13-17 (Huidige standaard, alternatief optieprotocolVersion: 13)

Installeren

npm install ws

Opt-in voor performance en spec compliance

Er zijn 2 optionele modules die samen met de wsmodule geïnstalleerd kunnen worden. Deze modules zijn binaire addons die bepaalde operaties verbeteren.Voorgebouwde binaries zijn beschikbaar voor de meest populaire platformen zodat u niet per se een C++ compiler op uw machine geïnstalleerd hoeft te hebben.

  • npm install --save-optional bufferutil: Maakt het mogelijk om efficiënt operaties uit te voeren zoals het maskeren en unmasken van de data payload van de WebSocketframes.
  • npm install --save-optional utf-8-validate: Hiermee kan efficiënt worden gecontroleerd of een bericht geldige UTF-8 bevat, zoals vereist door de spec.

API docs

Zie /doc/ws.md voor Node.js achtige documentatie van ws classes enutility functions.

WebSocket compressie

ws ondersteunt de permessage-deflate extensie die de client en server in staat stelt om te onderhandelen over een compressie algoritme en de bijbehorende parameters, en deze vervolgens selectief toe te passen op de data payloads van elk WebSocket bericht.

De extensie is standaard uitgeschakeld op de server en standaard ingeschakeld op de client. Het voegt een aanzienlijke overhead in termen van prestaties en geheugengebruik toe, dus we raden aan om het alleen in te schakelen als het echt nodig is.

Merk op dat Node.js een aantal problemen heeft met high-performance compressie, waar verhoogde concurrency, vooral op Linux, kan leiden tot catastrofale geheugenfragmentatie en trage prestaties. Als u van plan bent om permessage-deflate in productie te gebruiken, is het de moeite waard om een test op te zetten die representatief is voor uw werklast en ervoor te zorgen dat Node.js/zlib dit aankan met acceptabele prestaties en geheugengebruik.

Het afstellen van permessage-deflate kan worden gedaan via de hieronder gedefinieerde opties. U kunt ook zlibDeflateOptions en zlibInflateOptions gebruiken, die direct worden doorgegeven aan de creatie van ruwe deflate/inflate streams.

Zie de docs voor meer opties.

const WebSocket = require('ws');const wss = new WebSocket.Server({ port: 8080, perMessageDeflate: { zlibDeflateOptions: { // See zlib defaults. chunkSize: 1024, memLevel: 7, level: 3 }, zlibInflateOptions: { chunkSize: 10 * 1024 }, // Other options settable: clientNoContextTakeover: true, // Defaults to negotiated value. serverNoContextTakeover: true, // Defaults to negotiated value. serverMaxWindowBits: 10, // Defaults to negotiated value. // Below options specified as default values. concurrencyLimit: 10, // Limits zlib concurrency for perf. threshold: 1024 // Size (in bytes) below which messages // should not be compressed. }});

De client gebruikt de extensie alleen als deze wordt ondersteund en is ingeschakeld op de server. Als u de extensie op de client altijd wilt uitschakelen, stelt u de optieperMessageDeflate in op false.

const WebSocket = require('ws');const ws = new WebSocket('ws://www.host.com/path', { perMessageDeflate: false});

Gebruiksvoorbeelden

Tekstgegevens verzenden en ontvangen

const WebSocket = require('ws');const ws = new WebSocket('ws://www.host.com/path');ws.on('open', function open() { ws.send('something');});ws.on('message', function incoming(data) { console.log(data);});

Versturen van binaire data

const WebSocket = require('ws');const ws = new WebSocket('ws://www.host.com/path');ws.on('open', function open() { const array = new Float32Array(5); for (var i = 0; i < array.length; ++i) { array = i / 2; } ws.send(array);});

Eenvoudige server

const WebSocket = require('ws');const wss = new WebSocket.Server({ port: 8080 });wss.on('connection', function connection(ws) { ws.on('message', function incoming(message) { console.log('received: %s', message); }); ws.send('something');});

Externe HTTP/S-server

const fs = require('fs');const https = require('https');const WebSocket = require('ws');const server = https.createServer({ cert: fs.readFileSync('/path/to/cert.pem'), key: fs.readFileSync('/path/to/key.pem')});const wss = new WebSocket.Server({ server });wss.on('connection', function connection(ws) { ws.on('message', function incoming(message) { console.log('received: %s', message); }); ws.send('something');});server.listen(8080);

Meerdere servers delen één HTTP/S-server

const http = require('http');const WebSocket = require('ws');const url = require('url');const server = http.createServer();const wss1 = new WebSocket.Server({ noServer: true });const wss2 = new WebSocket.Server({ noServer: true });wss1.on('connection', function connection(ws) { // ...});wss2.on('connection', function connection(ws) { // ...});server.on('upgrade', function upgrade(request, socket, head) { const pathname = url.parse(request.url).pathname; if (pathname === '/foo') { wss1.handleUpgrade(request, socket, head, function done(ws) { wss1.emit('connection', ws, request); }); } else if (pathname === '/bar') { wss2.handleUpgrade(request, socket, head, function done(ws) { wss2.emit('connection', ws, request); }); } else { socket.destroy(); }});server.listen(8080);

Client authenticatie

const http = require('http');const WebSocket = require('ws');const server = http.createServer();const wss = new WebSocket.Server({ noServer: true });wss.on('connection', function connection(ws, request, client) { ws.on('message', function message(msg) { console.log(`Received message ${msg} from user ${client}`); });});server.on('upgrade', function upgrade(request, socket, head) { // This function is not defined on purpose. Implement it with your own logic. authenticate(request, (err, client) => { if (err || !client) { socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n'); socket.destroy(); return; } wss.handleUpgrade(request, socket, head, function done(ws) { wss.emit('connection', ws, request, client); }); });});server.listen(8080);

Zie ook het gegeven voorbeeld met express-session.

Server broadcast

Een client WebSocket die uitzendt naar alle verbonden WebSocket-clients, inclusief zichzelf.

const WebSocket = require('ws');const wss = new WebSocket.Server({ port: 8080 });wss.on('connection', function connection(ws) { ws.on('message', function incoming(data) { wss.clients.forEach(function each(client) { if (client.readyState === WebSocket.OPEN) { client.send(data); } }); });});

Een client WebSocket die uitzendt naar alle andere verbonden WebSocket-clients, behalve naar zichzelf.

const WebSocket = require('ws');const wss = new WebSocket.Server({ port: 8080 });wss.on('connection', function connection(ws) { ws.on('message', function incoming(data) { wss.clients.forEach(function each(client) { if (client !== ws && client.readyState === WebSocket.OPEN) { client.send(data); } }); });});

echo.websocket.org demo

const WebSocket = require('ws');const ws = new WebSocket('wss://echo.websocket.org/', { origin: 'https://websocket.org'});ws.on('open', function open() { console.log('connected'); ws.send(Date.now());});ws.on('close', function close() { console.log('disconnected');});ws.on('message', function incoming(data) { console.log(`Roundtrip time: ${Date.now() - data} ms`); setTimeout(function timeout() { ws.send(Date.now()); }, 500);});

Gebruik de Node.js streams API

const WebSocket = require('ws');const ws = new WebSocket('wss://echo.websocket.org/', { origin: 'https://websocket.org'});const duplex = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' });duplex.pipe(process.stdout);process.stdin.pipe(duplex);

Andere voorbeelden

Voor een volledig voorbeeld met een browser client die communiceert met een ws server, zie de mapexamples.

Anders, zie de test cases.

FAQ

Hoe krijg ik het IP adres van de client?

Het IP-adres van de client kan worden verkregen uit de raw socket.

const WebSocket = require('ws');const wss = new WebSocket.Server({ port: 8080 });wss.on('connection', function connection(ws, req) { const ip = req.socket.remoteAddress;});

Wanneer de server achter een proxy zoals NGINX draait, is de de-facto standaard om de X-Forwarded-For header te gebruiken.

wss.on('connection', function connection(ws, req) { const ip = req.headers.split(/\s*,\s*/);});

Hoe kan ik verbroken verbindingen detecteren en sluiten?

Soms kan de verbinding tussen de server en de client zodanig worden onderbroken dat zowel de server als de client zich niet bewust zijn van de verbroken status van de verbinding (bijv. door aan het snoer te trekken).

In deze gevallen kunnen ping-berichten worden gebruikt als middel om te verifiëren of het externe eindpunt nog steeds responsief is.

const WebSocket = require('ws');function noop() {}function heartbeat() { this.isAlive = true;}const wss = new WebSocket.Server({ port: 8080 });wss.on('connection', function connection(ws) { ws.isAlive = true; ws.on('pong', heartbeat);});const interval = setInterval(function ping() { wss.clients.forEach(function each(ws) { if (ws.isAlive === false) return ws.terminate(); ws.isAlive = false; ws.ping(noop); });}, 30000);wss.on('close', function close() { clearInterval(interval);});

Pong-berichten worden automatisch verzonden als reactie op ping-berichten, zoals de spec voorschrijft.

Net als bij het servervoorbeeld hierboven is het mogelijk dat uw clients de verbinding verliezen zonder dat ze dat weten. Je zou een ping listener kunnen toevoegen aan je clients om dat te voorkomen. Een eenvoudige implementatie zou zijn:

const WebSocket = require('ws');function heartbeat() { clearTimeout(this.pingTimeout); // Use `WebSocket#terminate()`, which immediately destroys the connection, // instead of `WebSocket#close()`, which waits for the close timer. // Delay should be equal to the interval at which your server // sends out pings plus a conservative assumption of the latency. this.pingTimeout = setTimeout(() => { this.terminate(); }, 30000 + 1000);}const client = new WebSocket('wss://echo.websocket.org/');client.on('open', heartbeat);client.on('ping', heartbeat);client.on('close', function clear() { clearTimeout(this.pingTimeout);});

Hoe maak je verbinding via een proxy?

Gebruik een aangepaste http.Agent implementatie zoals https-proxy-agent ofsocks-proxy-agent.

Changelog

We gebruiken de GitHub releases voor changelog entries.

Licentie

MIT

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *