A node.js module for websocket server and client

Overview

Nodejs Websocket

Build Status Inline docs Dependency Status

A nodejs module for websocket server and client

How to use it

Install with npm install nodejs-websocket or put all files in a folder called "nodejs-websocket", and:

var ws = require("nodejs-websocket")

// Scream server example: "hi" -> "HI!!!"
var server = ws.createServer(function (conn) {
	console.log("New connection")
	conn.on("text", function (str) {
		console.log("Received "+str)
		conn.sendText(str.toUpperCase()+"!!!")
	})
	conn.on("close", function (code, reason) {
		console.log("Connection closed")
	})
}).listen(8001)

Se other examples inside the folder samples

ws

The main object, returned by require("nodejs-websocket").

ws.createServer([options], [callback])

Returns a new Server object.

The options is an optional object that will be handed to net.createServer() to create an ordinary socket. If it has a property called "secure" with value true, tls.createServer() will be used instead.

To support protocols, the options object may have either of these properties:

  • validProtocols: an array of protocol names the server accepts. The server will pick the most preferred protocol in the client's list.
  • selectProtocol: a callback to resolve the protocol negotiation. This callback will be passed two parameters: the connection handling the handshake and the array of protocol names informed by the client, ordered by preference. It should return the resolved protocol, or empty if there is no agreement.

The callback is a function which is automatically added to the "connection" event.

ws.connect(URL, [options], [callback])

Returns a new Connection object, representing a websocket client connection

URL is a string with the format "ws://localhost:8000/chat" (the port can be omitted)

options is an object that will be passed to net.connect() (or tls.connect() if the protocol is "wss:"). The properties "host" and "port" will be read from the URL. The optional property extraHeaders will be used to add more headers to the HTTP handshake request. If present, it must be an object, like {'X-My-Header': 'value'}. The optional property protocols will be used in the handshake (as "Sec-WebSocket-Protocol" header) to allow the server to choose one of those values. If present, it must be an array of strings.

callback will be added as "connect" listener

ws.setBinaryFragmentation(bytes)

Sets the minimum size of a pack of binary data to send in a single frame (default: 512kiB)

ws.setMaxBufferLength(bytes)

Set the maximum size the internal Buffer can grow (default: 2MiB) If at any time it stays bigger than this, the connection will be closed with code 1009 This is a security measure, to avoid memory attacks

Server

The class that represents a websocket server, much like a HTTP server

server.listen(port, [host], [callback])

Starts accepting connections on a given port and host.

If the host is omitted, the server will accept connections directed to any IPv4 address (INADDR_ANY).

A port value of zero will assign a random port.

callback will be added as an listener for the 'listening' event.

server.close([callback])

Stops the server from accepting new connections and keeps existing connections. This function is asynchronous, the server is finally closed when all connections are ended and the server emits a 'close' event. The optional callback will be called once the 'close' event occurs.

server.socket

The underlying socket, returned by net.createServer or tls.createServer

server.connections

An Array with all connected clients. It's useful for broadcasting a message:

function broadcast(server, msg) {
	server.connections.forEach(function (conn) {
		conn.sendText(msg)
	})
}

Event: 'listening()'

Emitted when the server has been bound after calling server.listen

Event: 'close()'

Emitted when the server closes. Note that if connections exist, this event is not emitted until all connections are completely ended.

Event: 'error(errObj)'

Emitted when an error occurs. The 'close' event will be called directly following this event.

Event: 'connection(conn)'

Emitted when a new connection is made successfully (after the handshake have been completed). conn is an instance of Connection

Connection

The class that represents a connection, either a client-created (accepted by a nodejs ws server) or client connection. The websocket protocol has two types of data frames: text and binary. Text frames are implemented as simple send function and receive event. Binary frames are implemented as streams: when you receive binary data, you get a ReadableStream; to send binary data, you must ask for a WritableStream and write into it. The binary data will be divided into frames and be sent over the socket.

You cannot send text data while sending binary data. If you try to do so, the connection will emit an "error" event

connection.sendText(str, [callback])

Sends a given string to the other side. You can't send text data in the middle of a binary transmission.

callback will be added as a listener to write operation over the socket

connection.beginBinary()

Asks the connection to begin transmitting binary data. Returns a WritableStream. The binary transmission will end when the WritableStream finishes (like when you call .end on it)

connection.sendBinary(data, [callback])

Sends a single chunk of binary data (like calling connection.beginBinary().end(data))

callback will be added as a listener to write operation over the socket

connection.send(data, [callback])

Sends a given string or Buffer to the other side. This is simply an alias for sendText() if data is a string or sendBinary() if the data is a Buffer.

callback will be added as a listener to write operation over the socket

connection.sendPing([data=''])

Sends a ping with optional payload

connection.close([code, [reason]])

Starts the closing handshake (sends a close frame)

connection.socket

The underlying net or tls socket

connection.server

If the connection was accepted by a nodejs server, a reference to it will be saved here. null otherwise

connection.readyState

One of these constants, representing the current state of the connection. Only an open connection can be used to send/receive data.

  • connection.CONNECTING (waiting for handshake completion)
  • connection.OPEN
  • connection.CLOSING (waiting for the answer to a close frame)
  • connection.CLOSED

connection.outStream

Stores the OutStream object returned by connection.beginBinary(). null if there is no current binary data beeing sent.

connection.path

For a connection accepted by a server, it is a string representing the path to which the connection was made (example: "/chat"). null otherwise

connection.headers

Read only map of header names and values. Header names are lower-cased

connection.protocols

Array of protocols requested by the client. If no protocols were requested, it will be an empty array.

Additional resources on websocket subprotocols:

connection.protocol

The protocol agreed for this connection, if any. It will be an element of connection.protocols.

Event: 'close(code, reason)'

Emitted when the connection is closed by any side

Event: 'error(err)'

Emitted in case of error (like trying to send text data while still sending binary data). In case of an invalid handshake response will also be emited.

Event: 'text(str)'

Emitted when a text is received. str is a string

Event: 'binary(inStream)'

Emitted when the beginning of binary data is received. inStream is a ReadableStream:

var server = ws.createServer(function (conn) {
	console.log("New connection")
	conn.on("binary", function (inStream) {
		// Empty buffer for collecting binary data
		var data = Buffer.alloc(0)
		// Read chunks of binary data and add to the buffer
		inStream.on("readable", function () {
		    var newData = inStream.read()
		    if (newData)
		        data = Buffer.concat([data, newData], data.length+newData.length)
		})
		inStream.on("end", function () {
			console.log("Received " + data.length + " bytes of binary data")
		    process_my_data(data)
		})
	})
	conn.on("close", function (code, reason) {
		console.log("Connection closed")
	})
}).listen(8001)

Event: 'connect()'

Emitted when the connection is fully established (after the handshake)

Event: 'pong(data)'

Emitted when a pong is received, usually after a ping was sent. data is the pong payload, as a string

Comments
  • Suggestion: alias 'send' to 'sendText'

    Suggestion: alias 'send' to 'sendText'

    Love the simplicity - Zen style - of this solution. I would like to suggest to create an alias to 'sendText' so to be in line with other libraries - they use 'send' as the default for text messages.

    It is a minor request but well, I thought to make this suggestion

    enhancement 
    opened by itpmngt 5
  • The client doesn't recognise server response when the text from the server is immediate

    The client doesn't recognise server response when the text from the server is immediate

    I've tried to implement some simple scenario when the server sends some text to the client immediately after the connection.

    The (simplified) server looks like:

    var ws = require("nodejs-websocket");
    var wserver = ws.createServer(function (conn) {
        console.log("New connection");
        setTimeout(function(){
            conn.sendText(JSON.stringify({
                type:'hello'
            }));
        },0);
        conn.on("close", function (code, reason) {
            console.log("Connection closed");
        })
    })
    
    wserver.listen(8001);
    

    The (simplified) client looks like:

    var ws = require("nodejs-websocket");
    
    var conn = ws.connect("ws:127.0.0.1:8001",function() {
        console.log("New connection");
    
        conn.on("close", function (code, reason) {
            console.log("Connection closed")
        })
        conn.on("error", function (err) {
            console.log("Connection ERROR!",err)
        })
    });
    

    When the first client connects to the server it looks fine, the client prints "New connection"

    But when the second (and all following) client connects to the server, the client doesn't recognise a connection readyness (i.e. doesn't print "New connection" message).

    The server recognises and reports the both connections. The network traffic grabbed by the wireshark looks the same (except security cookies).

    The only difference is a time between last server handshake packet and the text packet sent from the server after the handshake.

    To check the problem, I've tried two cases:

    1. I've removed immediate text send from the server code. The bug disappeared.
    2. I've changed timeout from 0 to 100 to delay a text send. The bug disappeared.

    From my point of view it might be caused by some inconsistency in the client code, when the client doesn't separate a server handshake packet from the next packet if it follows immediately to the last websockets handshake packet and concatenated by the TCP layer to one piece of data sent to the user layer.

    bug 
    opened by nnseva 5
  • Problems with secure websockets

    Problems with secure websockets

    Changed default ports to be 443 for SSL and 80 for non-SSL (they were switched). Passed the whole URL to the connection, since it needed both the host and the path. Updated the package by bumping the version number. Updated the README to make ws.connect()'s callback non-optional, since it wasn't optional (at least, not in my experience).

    opened by asciimike 5
  • Adding an extra Authorization header

    Adding an extra Authorization header

    I'll have to connect to a secure Websocket that uses Basic http authorization. The only way to do so is to add Authorization to the request header.

    'Authorization: Basic ' + new Buffer('name'+ ':' + 'password').toString('base64')
    

    As for now I changed the header string in the startHandshake function.

    Would be nice if we could add extra header properties to the ws.connect option?

    enhancement 
    opened by Cinezaster 4
  • wss:// and SSL Issues

    wss:// and SSL Issues

    If I try to connect via wss://url, the code fails with the following error:

    Error: 140735134868240:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:../deps/openssl/openssl/ssl/s23_clnt.c:787:
    
    at SlabBuffer.use (tls.js:232:18)
    at CleartextStream.read [as _read] (tls.js:452:29)
    at CleartextStream.Readable.read (_stream_readable.js:320:10)
    at EncryptedStream.write [as _write] (tls.js:366:25)
    at doWrite (_stream_writable.js:226:10)
    at writeOrBuffer (_stream_writable.js:216:5)
    at EncryptedStream.Writable.write (_stream_writable.js:183:11)
    at write (_stream_readable.js:582:24)
    at flow (_stream_readable.js:591:7)
    at Socket.pipeOnReadable (_stream_readable.js:623:5)
    

    Pretty sure this error is related to the fact that this line has the ports backwards in the ternary operator. It should be (secure ? 443 : 80) rather than the way it currently is, correct? That being said, when I switch it and run it, it fails to connect and keeps trying to reconnect (but at least it doesn't error out). I wanted to get some confirmation on this before I do a PR (especially since it doesn't work when I switch it).

    bug 
    opened by asciimike 4
  • not clear on how server can receive binary from client

    not clear on how server can receive binary from client

    I would like to use your library to allow my browser client side to send to node-js server side binary data in form of a typed array such as Uint8Array. I am successfully sending normal text from client to server. When attemping binary, here is my client side send

    socket.binaryType = 'arraybuffer'; socket.send(big_monster_data);

    and here is my nodejs-websocket server side which is NOT correctly receiving the client sent data

    var server = ws.createServer(function (connection_request) {

    // here is text which is received just fine
    connection_request.on("text", function (received_data) {
            console.log("Received text format : " + received_data);
            connection_request.sendText(received_data.toUpperCase()+" OK");
        });
    
    // here is attempt at binary which is not working
    connection_request.on("binary", function (received_data) {
    
    // below gets printed YET length is undefined
    console.log("Received binary format of length ", received_data.length);
    
        if (received_data instanceof ArrayBuffer) {
    
            // this is NOT getting reached
            console.log("OK instanceof ArrayBuffer");
        }
    
        // HERE I want to do something with received arraybuffer
    }
    

    }

    thank you for your time

    cheers, Scott Stensland

    question 
    opened by scottstensland 4
  • Keep Alive?

    Keep Alive?

    Hi there,

    I am currently using this for a work project, I am struggling to see why I keep getting this issue: 'This socket has been ended by the other party', I assume it needs some kind of keep alive? or is this already included with this?

    Thanks, Danny

    opened by dannysmc95 3
  • [+] Subprotocols support (Sec-WebSocket-Protocol header), fix #24

    [+] Subprotocols support (Sec-WebSocket-Protocol header), fix #24

    Subprotocol support fro server and client. Server: conn.protocols now contain array of protocols requested by client Client: options.protocols - array of protocols for requesting

    Fix for #24

    opened by VoidVolker 3
  • connection.readyState is always 1

    connection.readyState is always 1

    Hi there, My websock server runs well but when I check readyState of my disconnected devices they are still assigned as 1.

    What am I missing to do?

    Thanks pal.

    opened by cagdasdoner 3
  • connection send can running function many time never stop

    connection send can running function many time never stop

    I firing connection.send with button clik when I clik button with double clik, it process a function in connection.on("text, function(){ myfuntion })many times n never stop, how to prevent that case. sorh bad english..

    invalid 
    opened by sabardotnet 3
  • trying to send typed array : Float32Array - how reassemble back once received

    trying to send typed array : Float32Array - how reassemble back once received

    Your library works fine when sending typed arrays like Uint8Array, however when I try to send a float typed array like Float32Array, the data comes across from client to server however it arrives with BYTES_PER_ELEMENT of 1 instead of desired BYTES_PER_ELEMENT of 4. Do I need to roll my own logic to reassemble my float array from the underlying single byte size data element array ? or can I use your library for this reassembly final step ?

    opened by scottstensland 3
  • Use websocket along with REST api routes

    Use websocket along with REST api routes

    I have built a project with REST api routes like post,get, etc. Some applications in the project require realtime communication, so I am planning to include websockets in my project. Is there a way to use websockets routes and REST api routes from a websocket server?

    opened by rahulv07 0
  • New SSL Cert without stopping server?

    New SSL Cert without stopping server?

    Sorry, not really an issue but a question: am I correct that there is no way of hot-swapping the SSL cert used when creating a new server, hence the server has to be destroyed and re-created?

    opened by resle 0
  • Run paired with a Node http/https server?

    Run paired with a Node http/https server?

    Is there a way to hand ws an http.createServer() / https.createServer() instance, so that a server can handle (limited) HTTP traffic in addition to upgrading a connection to a websocket connection on a specific route?

    For instance:

    const https = require('https');
    const ws = require('node-websocket');
    const routes = require('./routes.js');
    const server = https.createServer(routes);
    ws.setUpgradePath(server, 'join', connection => {
      connection.on( ... )
      ...
    });
    server.listen(80);
    

    So we have a simple secure http server, with a route that clients can use when creating websockets in order to set up the two way persistent connection, while also being able to load up (for example) a lobby page on the / route that gives them information on who else is already connected, a button that starts their own websocket client code, etc.

    Especially for debugging and administration, being able to generate a webpage that shows the current server state on the same address and port (but not path), rather than using a separate server entirely, is fairly crucial.

    opened by Pomax 0
  • connection.socket.remoteAddress returns ::1 even when client has another IP

    connection.socket.remoteAddress returns ::1 even when client has another IP

    I'm trying to use "connection.socket.remoteAddress" to get the clients IP in the server part of my game to make a ban-by-IP system, but it is returning "::1" even if client and Server have different IPs

    Is that a bug in the library? Are there other ways to get the client's IP?

    opened by peq42 0
  • Max call stack size exceeded on Connection.close

    Max call stack size exceeded on Connection.close

    I have a periodic service in nodejs that tries to create 30-40 socket connections and close it in case (it gets connected successfully or some error occurs while connecting) but every now an then I get Maxmimum call stack size exceeded error at line connection.close()

    My Code structure

    const connection = ws.connect(socketServerUrl, (err) => {
        if (err) {
            // console.log the error
        }
        else {
            connection.sendPing();
        }
    });
    
    connection.on('error', (err) => {
        const reason = err && err.message ? err.message : err;
    
        // THIS IS WHERE I GET THAT MAX CALL STACK SIZE REACHED EXCEPTION
        connection.close(); // release the connection
    });
    
    connection.on('pong', (data) => {
        connection.close(); // release the connection
    });
    

    Error Screenshot image

    bug 
    opened by NishantDesai1306 3
Releases(v1.1.1)
Owner
Guilherme Souza
Guilherme Souza
Standards-compliant WebSocket client and server

faye-websocket This is a general-purpose WebSocket implementation extracted from the Faye project. It provides classes for easily building WebSocket s

null 588 Dec 23, 2022
WebSocket emulation - Node.js server

SockJS-node SockJS for enterprise Available as part of the Tidelift Subscription. The maintainers of SockJS and thousands of other packages are workin

SockJS 2.1k Dec 29, 2022
This Repository implements an Authenticated Websocket Server built in Node Js along ws library.

websockets-authentication-server This Repository implements an Authenticated Websocket Server built in Node Js along ws library. Features Authenticate

M.Abdullah Ch 7 May 5, 2023
A tiny Nuxt.js module for WebSocket interactions

@deepsource/nuxt-websocket A tiny Nuxt.js module for WebSocket interactions. This module is only compatible with Nuxt v2 at the moment. Setup Add @dee

DeepSource 23 Dec 6, 2022
A WebSocket Implementation for Node.JS (Draft -08 through the final RFC 6455)

WebSocket Client & Server Implementation for Node Overview This is a (mostly) pure JavaScript implementation of the WebSocket protocol versions 8 and

Brian McKelvey 3.6k Dec 30, 2022
Mini Projeto de um chat-app usando o protocolo WebSocket através da lib 'ws' do node.js

CHAT-APP-WEBSOCKET Mini Projeto de um chat-app usando o protocolo WebSocket através da lib 'ws' do node.js Obs o intuito deste projeto não é o fronten

Vinicius dos Santos Rodrigues 4 Jul 14, 2022
Lightweight WebSocket lib with socket.io-like event handling, requests, and channels

ws-wrapper Lightweight and isomorphic Web Socket lib with socket.io-like event handling, Promise-based requests, and channels. What? Much like Socket.

Blake Miner 70 Dec 23, 2022
The cutest little WebSocket wrapper! 🧦

Sockette The cutest little WebSocket wrapper! ?? Sockette is a tiny (367 bytes) wrapper around WebSocket that will automatically reconnect if the conn

Luke Edwards 2.4k Jan 2, 2023
A Develop Tool to Test WebSocket, Socket.IO, Stomp, Bayeux, HTTP, TCP, UDP, WebRTC, DNS API.

A Develop Tool to Test WebSocket, Socket.IO, Stomp, Bayeux, HTTP, TCP, UDP, WebRTC, DNS API.

York Yao 24 Sep 6, 2022
WebSocket cat

WebSocket cat

WebSockets 1.6k Jan 2, 2023
How to build a chat using Lambda + WebSocket + API Gateway? (nodejs)

Description Source code for the lambda function from the screencast How to build a chat using Lambda + WebSocket + API Gateway? (nodejs) The reactjs c

Alex 21 Dec 28, 2022
A websocket-based reverse shell for XSS attacks.

CrossSiteShell A javascript/nodejs "reverse shell" that makes it easier to interact with the victim's browser during XSS attacks. Usage Run the follow

Rafael 13 Oct 7, 2022
Um bot feito utilizando a API baileys em WebSocket para o Whatsapp Multi-Devices.

Informação ?? O BaileysBot foi feito utilzando a API Baileys Caso encontre algum BUG, faça um Novo Issue! Requisitos ?? NodeJS Git Instalação ?? Para

null 12 Dec 3, 2022
🚀🚀🚀 Nuxt3 client and server communication

Nuxt 3 Minimal Starter Look at the nuxt 3 documentation to learn more. Setup Make sure to install the dependencies: # yarn yarn install # npm npm ins

HomWang 4 Dec 19, 2022
Sse-example - SSE (server-sent events) example using Node.js

sse-example SSE (server-sent events) example using Node.js SSE is a easy way to commutate with the client side in a single direction. it has loss cost

Jack 2 Mar 11, 2022
🔄 iola: Socket client with REST API

?? iola: Socket client with REST API

Pavel Varentsov 113 Jan 3, 2023
soketi is your simple, fast, and resilient open-source WebSockets server

soketi soketi is your simple, fast, and resilient open-source WebSockets server. ?? Blazing fast speed ⚡ The server is built on top of uWebSockets.js

Soketi 3.2k Jan 4, 2023
This server is made to serve the MSN-Messenger app develop by Gabriel Godoy. This applications is capable to register users and messages in order implements a real time chat.

?? MSN-Messenger-Server Node.js server for real time chat About | Installations | How to Use | Documentation | Technologies | License ?? About This se

Guilherme Feitosa 7 Dec 20, 2022
Super-Resolution-CNN - web server for super-resolution CNN

Web Server for Image Super-Resolution This project showcases the Super-Resolution CNN (SRCNN). The model is pretrained following this tutorial. The or

Daniel O'Sullivan 1 Jan 3, 2022