websocket-node

repository·master·Indexed 26 days ago

https://github.com/theturtle32/websocket-node

A pure JavaScript implementation of the WebSocket protocol (versions 8 and 13) for Node.js, implementing RFC 6455. It provides both client and server roles for real-time bidirectional communication, including a W3C WebSocket API implementation for browser compatibility. The library includes modules for servers, clients, frames, and routing.

Tokens
8.4K
Snippets
11
Records
46
Agent score
87%

What's inside websocket

  1. Overview of WebSocket-Node Client and Server functionality

    master

    WebSocket-Node provides both client and server implementations for WebSockets in Node.js.

    • Use WebSocketClient to implement client-side functionality.
    • Use WebSocketServer to implement server-side functionality.

    Once a connection is established, the API for sending and receiving messages is identical for both clients and servers, managed through the connection object.

  2. Use WebSocketConnection to communicate with peers

    master
    The WebSocketConnection object is the primary interface for communicating with connected peers in both WebSocketServer and WebSocketClient scenarios. It provides methods for sending data (UTF-8 or Binary), managing connection lifecycle (close/drop), and handling control frames (ping/pong).
  3. Manually handle WebSocket connection upgrades using WebSocketRequest

    master

    If you are not mounting WebSocketServer directly to an HTTP server, you can manually handle the upgrade event from a Node.js HTTP server. To do this, instantiate WebSocketRequest with the socket, the HTTP request, and a complete set of configuration options (the only non-required option in this context is httpServer).

    Important: The constructor does not automatically parse the handshake. You must call readHandshake() within a try/catch block, as it will throw an error if the client's handshake is invalid.

    new WebSocketRequest(socket, httpRequest, config);
  4. Handle UTF-8 Text Frames and fragmentation

    master

    When working with Text Frames via WebSocketFrame:

    1. Sending: You must serialize your UTF-8 string into a Buffer object before assigning it to binaryPayload.
    2. Receiving: You must deserialize the binaryPayload (which is a Buffer) into a string.
    3. Fragmentation Warning: Do not attempt to read UTF-8 data from fragmented Text Frames. A fragment might split a UTF-8 encoded character in the middle. You should buffer all fragments of a text message before attempting to decode the UTF-8 data.
  5. Use W3CWebSocket for browser-compatible WebSocket implementation

    master

    The W3CWebSocket class provides an implementation of the W3C WebSocket API for Node.js. This allows developers to write code that is compatible with both Node.js and the browser (e.g., when using tools like browserify), as the API surface matches the native window.WebSocket found in browsers.

    var WS = require('websocket').w3cwebsocket;
    
    var ws = new WS('ws://example.com/resource', 'foo', 'http://example.com');
    
    ws.onopen = function() {
      console.log('ws open');
    };
  6. Configure WebSocketServer options

    master

    When initializing or mounting a WebSocketServer, you can provide a serverConfig object. Key options include:

    OptionTypeDefaultDescription
    httpServerhttp.ServerRequiredThe Node http/https server instance(s) to attach to. Can be a single instance or an array.
    maxReceivedFrameSizeuint64KiBMaximum allowed received frame size in bytes.
    maxReceivedMessageSizeuint1MiBMaximum allowed aggregate message size (for fragmented messages) in bytes.
    fragmentOutgoingMessagesbooleantrueWhether to automatically fragment outgoing messages.
    fragmentationThresholduint16KiBMax size of a frame in bytes before automatic fragmentation.
    keepalivebooleantrueIf true, server sends pings to clients every keepaliveInterval ms.
    keepaliveIntervaluint20000Interval in ms to send keepalive pings.
    dropConnectionOnKeepaliveTimeoutbooleantrueIf true, drops connections that don't respond within keepaliveGracePeriod after a ping.
    keepaliveGracePerioduint10000Time to wait after a ping before closing the connection if no response.
    assembleFragmentsbooleantrueIf true, fragmented messages are assembled and emitted via message event.
    autoAcceptConnectionsbooleanfalseIf true, accepts all connections regardless of path/protocol. Use with caution.
    closeTimeoutuint5000Ms to wait for close frame acknowledgement before forcing socket closure.
    disableNagleAlgorithmbooleantrueDisables Nagle Algorithm to reduce latency.
    ignoreXForwardedForbooleanfalseIf true, ignores X-Forwarded-For header (recommended for untrusted clients).
    parseExtensionsbooleantrueWhether to parse sec-websocket-extension headers.
    parseCookiesbooleantrueWhether to parse cookie headers.
  7. Configure WebSocketClient options

    master

    The WebSocketClient constructor accepts a configuration object with the following properties:

    OptionTypeDefaultDescription
    webSocketVersionuint13Protocol version (supported: 8 or 13). Affects the Origin header name.
    maxReceivedFrameSizeuint1MiBMaximum allowed size for a single received frame in bytes.
    maxReceivedMessageSizeuint8MiBMaximum allowed aggregate size for fragmented messages in bytes.
    fragmentOutgoingMessagesBooleantrueWhether to automatically fragment outgoing messages.
    fragmentationThresholduint16KiBMaximum frame size in bytes before automatic fragmentation occurs.
    assembleFragmentsbooleantrueIf true, fragmented messages are assembled and emitted via message event. If false, use the frame event on the connection object.
    closeTimeoutuint5000Milliseconds to wait for a close frame acknowledgement before forcing the socket closed.
    tlsOptionsobject{}Options passed to https.request when connecting via TLS.
  8. Run the Whiteboard Example

    master

    To run the whiteboard example, you must install specific versions of express and ejs within the whiteboard directory, start the server, and then access it via a web browser.

    Prerequisites:

    • A browser supporting draft-09 of the WebSockets specification.

    Steps:

    1. Navigate to the whiteboard folder.
    2. Install the required dependencies: express@2.3.11 and ejs@0.4.3.
    3. Start the server using node ./whiteboard.js.
    4. Open http://localhost:8080 in your browser.
    # From within the 'whiteboard' folder
    npm install "express@2.3.11" "ejs@0.4.3"
    node ./whiteboard.js
  9. Implement a WebSocket Echo Server

    master

    This example demonstrates how to set up a WebSocket server using Node's http module. It listens for requests, validates the origin (recommended for production), and echoes back any received UTF-8 or binary messages.

    Note: For production, do not use autoAcceptConnections: true as it bypasses cross-origin protection. Always verify the connection's origin manually.

    #!/usr/bin/env node
    var WebSocketServer = require('websocket').server;
    var http = require('http');
    
    var server = http.createServer(function(request, response) {
        console.log((new Date()) + ' Received request for ' + request.url);
        response.writeHead(404);
        response.end();
    });
    server.listen(8080, function() {
        console.log((new Date()) + ' Server is listening on port 8080');
    });
    
    wsServer = new WebSocketServer({
        httpServer: server,
        // You should not use autoAcceptConnections for production
        // applications, as it defeats all standard cross-origin protection
        // facilities built into the protocol and the browser.  You should
        // *always* verify the connection's origin and decide whether or not
        // to accept it.
        autoAcceptConnections: false
    });
    
    function originIsAllowed(origin) {
      // put logic here to detect whether the specified origin is allowed.
      return true;
    }
    
    wsServer.on('request', function(request) {
        if (!originIsAllowed(request.origin)) {
          // Make sure we only accept requests from an allowed origin
          request.reject();
          console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
          return;
        }
        
        var connection = request.accept('echo-protocol', request.origin);
        console.log((new Date()) + ' Connection accepted.');
        connection.on('message', function(message) {
            if (message.type === 'utf8') {
                console.log('Received Message: ' + message.utf8Data);
                connection.sendUTF(message.utf8Data);
            }
            else if (message.type === 'binary') {
                console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
                connection.sendBytes(message.binaryData);
            }
        });
        connection.on('close', function(reasonCode, description) {
            console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
        });
    });
  10. Use the W3C WebSocket API in Node.js

    master

    If you want your code to be compatible with both Node.js and browsers, use the W3CWebSocket class. This implementation follows the W3C WebSocket API standard.

    var W3CWebSocket = require('websocket').w3cwebsocket;
    
    var client = new W3CWebSocket('ws://localhost:8080/', 'echo-protocol');
    
    client.onerror = function() {
        console.log('Connection Error');
    };
    
    client.onopen = function() {
        console.log('WebSocket Client Connected');
    
        function sendNumber() {
            if (client.readyState === client.OPEN) {
                var number = Math.round(Math.random() * 0xFFFFFF);
                client.send(number.toString());
                setTimeout(sendNumber, 1000);
            }
        }
        sendNumber();
    };
    
    client.onclose = function() {
        console.log('echo-protocol Client Closed');
    };
    
    client.onmessage = function(e) {
        if (typeof e.data === 'string') {
            console.log("Received: '" + e.data + "'");
        }
    };
  11. Implement a WebSocket Client in Node.js

    master

    This example shows how to use the websocket.client module in a Node.js environment. It connects to a server, handles connection errors, and listens for incoming UTF-8 messages. It also demonstrates sending data periodically.

    #!/usr/bin/env node
    var WebSocketClient = require('websocket').client;
    
    var client = new WebSocketClient();
    
    client.on('connectFailed', function(error) {
        console.log('Connect Error: ' + error.toString());
    });
    
    client.on('connect', function(connection) {
        console.log('WebSocket Client Connected');
        connection.on('error', function(error) {
            console.log("Connection Error: " + error.toString());
        });
        connection.on('close', function() {
            console.log('echo-protocol Connection Closed');
        });
        connection.on('message', function(message) {
            if (message.type === 'utf8') {
                console.log("Received: '" + message.utf8Data + "'");
            }
        });
        
        function sendNumber() {
            if (connection.connected) {
                var number = Math.round(Math.random() * 0xFFFFFF);
                connection.sendUTF(number.toString());
                setTimeout(sendNumber, 1000);
            }
        }
        sendNumber();
    });
    
    client.connect('ws://localhost:8080/', 'echo-protocol');