Simple websocket server nodejs

Simple websocket server nodejs DEFAULT

Join the Data in Motion newsletter

A header graphic showing the WebSockets logo and the node.js logo and a browser with cursors moving around it

This post will look at implementing a couple of low-level WebSockets libraries with Node.js as the WebSocket server. We’ll look at how each library is used, and why one might choose it for their project. Then we’ll talk about the reasons one might choose a third-party service to manage their WebSockets connections.

WebSockets and Node.js

WebSockets let developers build realtime functionality into their apps by enabling the sending of small chunks of data over a single persistent connection, in both directions. Using WebSockets in the front end is fairly straightforward, as there is a WebSocket API built into all modern browsers. To use them on the server, a backend application is required.

This is where Node.js comes in. Node.js can maintain many hundreds of WebSockets connections simultaneously. WebSockets on the server can become complicated as the connection upgrade from HTTP to WebSockets requires handling. This is why developers commonly use a library to manage this for them. There are a few common WebSocket server libraries that make managing WebSockets easier – notably WS, SockJS and Socket.io.

WS – A Node.js WebSocket library

WS is a WebSockets server for Node.js. It's quite low level: you listen to incoming connection requests and respond to raw messages as either strings or byte buffers. Since WebSockets are natively supported in all modern browsers, it is possible to work with WS on the server and the browser's WebSocket API on the client.

In order to demonstrate how to set up WebSockets with Node and WS, we have built a demo app which shares users' cursor positions in realtime. We walk through building it below.

Building an interactive cursor position-sharing demo with WS

This is a demo to create a colored cursor icon for every connected user. When they move their mouse around, their cursor icon moves on the screen and is also shown as moving on the screen of every connected user. This happens in realtime, as the mouse is being moved.

The WebSockets Server

First, require the WS library and use the method to create a new WebSocket server on port 7071 (no significance, any port is fine!).

Note: For brevity’s sake we call it in our code. Any resemblance to WebSocket Secure (often referred to as WSS) is a coincidence.

Next, create a Map to store a client's metadata (any data we wish to associate with a WebSocket client):

Subscribe to the WSS event using the function, providing a callback. This will be called whenever a new WebSocket client connects to the server:

Every time a client connects, we generate a new unique ID, which is used to identify them. Clients are also assigned a cursor color by using ; this generates a number between 0 and 360, which corresponds to the hue value of an HSV color. The ID and cursor color are then added to an object that we'll call and we're using the Map to associate them with our WebSocket instance.

The map is a dictionary – we can retrieve this metadata by calling and providing a WebSocket instance later on.

Using the newly connected WebSocket instance, we subscribe to that instance's event, and provide a callback function that will be triggered whenever this specific client sends a message to the server.

Note: This event is on the WebSocket instance () itself, and not on the WebSocketServer instance ().

Whenever our server receives a message, we use JSON.parse to get the message contents, and load our client metadata for this socket from our Map using .

We're going to add our two metadata properties to the message as and ...

Then we our message again, and send it out to every connected client.

Finally, when a client closes its connection, we remove its from our .

At the bottom we have a function to generate a unique ID.

This server implementation , sending any message it has received to all connected clients.

We now need to write some client-side code to connect to the WebSocket server, and transmit the user’s cursor position as it moves.

We're going to start with some standard HTML5 boilerplate:

Next we add a reference to a style sheet, and an file that we're adding as an ES Module (using ).

The body contains a single which contains an of a pointer. We're going to use JavaScript to clone this template whenever a new user connects to our server.

Next, we need to use JavaScript to connect to the .

We call the function, which resolves a promise containing the connected .

(The function definition will be written later.)

Once connected, we add a handler for to the . The is very simple: it consists of the current and properties from the mouse movement event (the horizontal and vertical coordinates of the cursor within the application's viewport).

We stringify this object, and send it down our now connected instance as the message text:

Now we need to add another handler, this time for an event to the WebSocket instance . Remember that every time the receives a message, it'll forward it to all connected clients.

You might notice that the syntax here is slightly different from the server-side code. That's because we're using the browser’s native class, rather than the library .

When we receive a message over the , we parse the property of the message, which contains the stringified data that the handler sent to the , along with the additional and properties that the server side code adds to the message.

Using the parsed , we call . This function returns an HTML element that is part of the DOM, and we'll look at how it works later.

We then use the x and y values from the to adjust the cursor position using a .

Our code relies on two utility functions. The first is which opens a connection to our and then returns a that resolves when the property is .

This means that we can just this function, and we'll know that we have a connected and working connection.

We also use our function.

This function first attempts to find any existing element with the HTML data attribute where the value is the same as the property in our message. If it finds one, we know that we've already created a cursor for this user, and we just need to return it so the calling code can adjust its position.

If we can't find an existing element, we our , add the data-attribute with the current ID to it, and append it to the before returning it.

Now when you run the web application, each user viewing the page will have a cursor that appears on everyone's screens because we are sending the data to all the clients using .

Running the demo

If you’ve been following along with the tutorial, then you can run:

If not, you can clone a working version of the demo

This demo includes two applications: a web app that we serve through Snowpack, and a Node.js web server. The NPM start task will spin up both the API and the web server.

This should look as follows:

Gif showing the cursor movement when messages are sent over WebSockets

However, if you are running the demo in a browser that does not support WebSockets (eg IE9 or below), or if you are restricted by particularly tight corporate proxies, you will get an error saying that the browser can’t establish a connection:

Image showing the error message when a WebSockets connection can’t be established

This is because the WS library offers no fallback transfer protocols if WebSockets are unavailable. If this is a requirement for your project, or you want to have a higher level of reliability of delivery for your messages, then you will need a library that offers multiple transfer protocols, such as SockJS.

SockJS – A JavaScript library to provide WebSocket-like communication between the client and server

SockJS is a library that mimics the native WebSockets API. Additionally, it will fall back to HTTP whenever a WebSocket fails to connect, or if the browser being used doesn’t support WebSockets. Like WS, SockJS requires a server counterpart; its maintainers provide both a JavaScript client library and a Node.js server library.

Using SockJS in the client is similar to the native WebSockets API, with a few small differences. We can swap out WS in the demo built previously and use SockJS instead to include fallback support.

Updating the Interactive Cursor Position Sharing Demo to use SockJS

To use SockJS in the client, we first need to load the SockJS JavaScript library from their CDN. In the head of the index.html document we built earlier, add the following line above the script include of index.js:

Note the keyword – it ensures that the SockJS library is loaded before index.js runs.

In the app/script.js file, we then update the JavaScript to use SockJS. Instead of the object, we’ll now use a object. Inside the function, we’ll establish the connection with the SockJS server:

Note: SockJS requires a prefix path on the server URL. The rest of the app/script.js file requires no change.

Now to update the API/script.js file to make our server use SockJS. This means changing the names of a few event hooks, but the API is very similar to WS.

First, we need to install In your terminal run:

Then we need to require the module and the built-in HTTP module from Node. Delete the line that requires ws and replace it with the following:

We then change the declaration of to become:

At the very bottom of the API/index.js file we’ll create the HTTPS server and add the SockJS HTTP handlers: \

We map the handlers to a prefix supplied in a configuration object (. We tell the HTTP server to listen on port 7071 (arbitrarily chosen) on all the network interfaces on the machine.

The final job is to update the event names to work with SockJS:

And that’s it, the demo will now run with WebSockets where they are supported; and where they aren’t, it will degrade to use comet long polling over HTTP. This latter fallback option will show a slightly less smooth cursor movement, but it is more functional than no connection at all!

Running the demo

If you’ve been following along with the tutorial, then you can run:

If not, you can clone a working version of the demo:

This demo includes two applications: a web app that we serve through Snowpack, and a Node.js web server. The NPM start task spins up both the API and the web server.

Does this scale?

You might notice that in both examples we're storing the state in the Node.js – there is a Map that keeps track of connected WebSockets and their associated metadata. This means that for the solution to work, and for every user to see one another, they have to be connected to the exact same .

The number of active users you can support is thus directly related to how much hardware your server has. Node.js is pretty good at managing concurrency, but once you reach a few hundred to a few thousand users, you're going to need to scale your hardware vertically to keep all the users in sync.

Scaling vertically is often an expensive proposition, and you'll always be faced with a performance ceiling of the most powerful piece of hardware you can procure. (It’s also not elastic and you have to do it ahead of time.) Once you've run out of vertical scaling options, you'll be forced to consider horizontal scaling – and horizontally scaling WebSockets is significantly more difficult.

What makes WebSockets hard to scale?

To scale regular application servers that don't require persistent connections, the standard approach is to introduce a load balancer in front of them. Load balancers route traffic to whichever node is currently available (either by measuring node performance, or using a round-robin system).

WebSockets are fundamentally harder to scale, because connections to your need to be persistent. And even once you've scaled out your nodes both vertically and horizontally, you also need to provide a solution for sharing data between the nodes. Any state needs to be stored out-of-process – this usually involves using something like Redis, or a traditional database, to ensure that all the nodes have the same view of state.

In addition to having to share state using additional technology, broadcasting to all subscribed clients becomes difficult, because any given node knows only about the clients connected to itself.

There are multiple ways to solve this: either by using some form of direct connection between the cluster nodes that are handling the traffic, or by using an external pub/sub mechanism (like Redis). This is sometimes called "adding a backplane" to your infrastructure, and is yet another moving part that makes scaling WebSockets difficult.

WebSockets in Node.js perform very well, but growing them becomes more and more difficult as your traffic profiles increase. This is where Ably comes in!

Take our APIs for a spin


Using Ably to Scale WebSockets

If you’re building an app that needs reliable, scalable realtime data exchange, then a third-party platform could be the answer you’re looking for. Ably handles all the infrastructure and hard engineering challenges for you, such as dependably scaling WebSockets, while significantly reducing the development load on your team. Ably provides fallback protocols, and load balancing for you, as well as having global coverage, meaning that region-by-region scale is possible.

In addition, Ably comes with features like:

  • Connection IDs out of the box – no need to assign our own UUID in the demo above
  • Easy creation and management of multiple stateful channels to publish and receive data
  • Presence data to provide notification of who else is connected
  • Automatic reconnection if a device momentarily drops offline
  • History and rewind to receive missed messages when a connection is lost

All of these are extra factors have to be hand-rolled by a development team working with a low-level library like WS or SockJS. It all requires specialized engineering knowledge, making the proposition both expensive and time-consuming. Curious to find out more? Take our APIs for a spin.

Resources

Sours: https://ably.com/blog/web-app-websockets-nodejs

Simple Websocket Example with Nodejs

Today topic is WebSocket example with nodejs. WebSocket help to communicate the servers with clients in async manner.The server and client can communicate and exchange data at the same time. WebSocket help to create real-time communication between web servers and clients.

The jQuery AJAX also can use to communicate with server, which is only one-way communication and only client can ask data from the server.

Whereas, Websocket provide two-way communication between server and client.The WebSocket connection is a persistent connection between a browser(client app) and the server. The server can send messages to the browser and the browser can respond back via the same connection.

Getting Started With Web Socket With Nodejs

nodejs-websocket-example

The Web Socket API is cross platform standard for real-time communication between a client and the server.Web socket protocol has two type(ws:// and wss://) like http and https.

The client application must be have ability to connect web socket and establish connection.We will create two file –

  • server.js :This file will create server that send response to client app.
  • client.js :This file will use for client app and listen response from server .

Let’s install ws

We will install ws libs into nodejs application using following command.

Create websocket server

We will create file and add below code into this file.

constWebSocket=require('ws')
constwss=newWebSocket.Server({port:8080})
wss.on('connection',ws=>{
ws.on('message',message=>{
console.log(`Received message=>${message}`)
ws.send('Hello! Message From Server!!')

First, we will create ws connection object and open connection on port.Now, open command line and run server by the following command –

Create Client Application For WebSocket

We will create file and add below code into this file –

constWebSocket=require('ws')
consturl='ws://localhost:8080'
constconnection=newWebSocket(url)
connection.onopen=()=>{
connection.send('Message From Client')
connection.onerror=(error)=>{
console.log(`WebSocket error:${error}`)
connection.onmessage=(e)=>{

Okay, Now we will start a client-side server by the following command.

After the successfully connected client to server, the server start to send the message to client application.

Sours: https://www.js-tutorials.com/nodejs-tutorial/simple-websocket-example-with-nodejs/
  1. Boeing tour tripadvisor
  2. 3d rose wallpapers free download
  3. Pottery barn daybed mattress cover
  4. Embers hd

npm

Simple, EventEmitter API for WebSockets

Sauce Test Status

features

  • super simple API for working with WebSockets in the browser
  • supports text and binary data
  • node.js duplex stream interface
  • client & server implementations

This package is used by WebTorrent.

install

This package works in the browser with browserify. If you do not use a bundler, you can use the standalone script directly in a tag. This exports a constructor on . Wherever you see in the examples below, substitute that with .

real-world applications that use simple-websocket

  • Virus Cafe - Make a friend in 2 minutes
  • WebTorrent - The streaming torrent app
  • StudyNotes - Helping students learn faster and better
  • bittorrent-tracker - Simple, robust, BitTorrent tracker (client & server) implementation
  • instant.io - Secure, anonymous, streaming file transfer
  • lxjs-chat - Omegle chat clone
  • Metastream - Watch streaming media with friends.
  • [ your application here - send a PR ]

usage

varSocket=require('simple-websocket')varsocket=newSocket('wss://echo.websocket.org')socket.on('connect',function(){// socket is connected!socket.send('sup!')})socket.on('data',function(data){console.log('got message: '+data)})

api

Create a new WebSocket connection to the server at . This usage is a shorthand for

If is specified as a string, then a WebSocket connection will be created to the server at .

If is specified as an instance of a raw WebSocket object, then the given WebSocket object will be used and one will not be automatically be created internally. (This is for advanced users.)

Other properties on will be passed through to the underlying superclass, .

Send text/binary data to the WebSocket server. can be any of several types: , (see buffer), (, etc.), , or (in browsers that support it).

Note: If this method is called before the event has fired, then data will be buffered.

Destroy and cleanup this websocket connection.

If the optional parameter is passed, then it will be emitted as an event on the stream.

Detect WebSocket support in the javascript environment.

varSocket=require('simple-websocket')if(Socket.WEBSOCKET_SUPPORT){// websocket support!}else{// fallback}

events

Fired when the websocket connection is ready to use.

Received a message from the websocket server.

will be either a or a (see buffer). JSON strings will be parsed and the resulting emitted.

Called when the websocket connection has closed.

is an object.

Fired when a fatal error occurs.

server

The server implementation is basically but the event provides sockets that are instances of , i.e. they are duplex streams.

varServer=require('simple-websocket/server')varserver=newServer({port: port})// see `ws` docs for other optionsserver.on('connection',function(socket){socket.write('pong')socket.on('data',function(data){})socket.on('close',function(){})socket.on('error',function(err){})})server.close()

license

MIT. Copyright (c) Feross Aboukhadijeh.

Sours: https://www.npmjs.com/package/simple-websocket
Node.js WebSocket Programming Tutorial with JavaScript

How to Set Up a Websocket Server with Node.js and Express

Getting started

For this tutorial, we're going to be using the CheatCode Node.js Boilerplate. This will give us access to an existing Express server that we can attach our websocket server to:

After you've cloned the project, into it and install its dependencies:

Finally, for this tutorial, we need to install two additional dependencies: for creating our websocket server and for parsing query params from our websocket connections:

After this, start up the development server:

Creating a websocket server

To begin, we need to set up a new websocket server that can handle inbound websocket requests from clients. First, in the file of the project we just cloned, let's add a call to the function that will setup our websocket server:

Here, we've imported a hypothetical function from which is anticipating an file at that path (Node.js interprets this as ). Inside of the callback for our server function, we've added a call to this function just beneath our call to . To it, we pass which is the HTTP server returned by Express when the HTTP server is opened on the passed (in this case ).

Once is available, we call to our function, passing in the HTTP (this is what we'll attach the websocket server to that we'll create in the next section).

Attaching a websocket server to an express server

Next, we need to create the file that we assumed will exist above. To keep our code clean, we're going to create a separate directory at the root of the project we cloned and create an file inside of that:

Here, we export a function that takes in a single argument of which contains the Express instance that we intend to pass in when we call the function from at the root of the project.

Just inside that function, we create our websocket server using the constructor from the package that we installed above. To that constructor, we pass the option as to say "do not set up an HTTP server alongside this websocket server." The advantage to doing this is that we can share a single HTTP server (i.e., our Express server) across multiple websocket connections. We also pass a option to specify the path on our HTTP server where our websocket server will be accessible (ultimately, ).

Extending our code, next, we need to handle the attachment of the websocket server to the existing . To do it, on the we listen for an event. This event is fired whenever our Express server—a plain HTTP server—receives a request for an endpoint using the websockets protocol. "Upgrade" here is saying, "we need to upgrade this request to handle websockets."

Passed to the callback for the event handler—the part—we have three arguments , , and . represents the inbound HTTP request that was made from a websocket client, represents the network connection between the browser (client) and the server, and represents the first packet/chunk of data for the inbound request.

Next, inside the callback for the event handler, we make a call to , passing along with the , , and . What we're saying with this is "we're being asked to upgrade this HTTP request to a websocket request, so perform the upgrade and then return the upgraded connection to us."

That upgraded connection, then, is passed to the callback we've added as the fourth argument to . With that upgraded connection, we need to handle the connection—to be clear, this is the now-connected websocket client connection. To do it, we "hand off" the upgraded connection and the original by emitting an event on the with the name .

Handling inbound websocket connections

At this point, we've upgraded our existing Express HTTP server, however, we haven't completely handled the inbound request. In the last section, we got up to the point where we're able to upgrade the inbound HTTP request from a websocket client into a true websocket connection, however, we haven't handled that connection.

To handle that connection, we need to listen for the event that we emitted in the last section. To do it, we make a call to passing it a callback function that will handle the inbound websocket connection and the accompanying request.

To clarify, the difference between the and the is that the former represents the open, long-running network connection between the browser and the server, while the represents the original request to open that connection.

Focusing on the callback we've passed to our handler, we do something special. Per the implementation for websockets, there is no way to pass data (e.g., a user's ID or some other identifying information) in the body of a websocket request (similar to how you can pass a body with an HTTP POST request).

Instead, we need to include any identifying information in the query params of the URL of our websocket server when connecting to the server via a websocket client (more on this in the next section). Unfortunately, these query params are not parsed by our websocket server and so we need to do this manually.

To extract the query params into a JavaScript object, from the , we grab the URL the request was made for (this is the URL the websocket client makes the connection request to) and split it at the . We do this because we don't care about any part of the URL before and up to the , or, our query params in URL form.

Using JavaScript array destructuring, we take the result of our and assume that it returns an array with two values: the path portion of the URL and the query params in URL form. Here, we label the path as to suggest that we're not using that value (prefixing an underscore to a variable name is a common way to denote this across programming languages). Then, we "pluck off" the value that was split off from the URL. To be clear, assuming the URL in the request looks like we expect something like this to be in the array:

As they exist, the (in the example above ) are unusable in our code. To make them usable, we pull in the method from the package that we installed earlier. This method takes a URL-formatted query string and converts it into a JavaScript object. The end result considering the example URL above would be:

With this, now we can reference our query params in our code via the variable. We don't do anything with those here, but this information is included because frankly, it's frustrating to figure that part out.

Above, we have our completed websocket server implementation. What we've added is an event handler for when our receives an inbound message (the idea of websockets is to keep a long-running connection open between the browser and the server across which messages can be sent back and forth).

Here, when a message event comes in, in the callback passed to the event handler, we take in a single property as a string. Here, we're assuming that our is a stringified JavaScript object, so we use to convert that string into a JavaScript object that we can interact with in our code.

Finally, to showcase responding to a message from the server, we call to , passing a stringified object back (we'll assume the client is also anticipating a stringified JavaScript object being passed in its inbound messages).

Testing out the websocket server

Because we're not showcasing how to set up a websocket client in a front-end in this tutorial, we're going to use a Chrome/Brave browser extension called Smart Websocket Client that gives us a pseudo front-end that we can use to test things out.

HZhEqF3ZCMTYsMtH/OG5Iw6vTqKGsfWxy.0

On top, we have our running HTTP/websocket server running in a terminal (this is the development server of the projet we cloned at the beginning of this project) and on the bottom, we have the Smart Websocket Client extension opened up in the browser (Brave).

First, we enter the URL where we expect our websocket server to exist. Notice that instead of the usual that we prefix to a URL when connecting to a server, because we want to open a websocket connection, we prefix our URL with (similarly, in production, if we have SSL enabled we'd want to use for "websockets secure").

Because we expect our server to be running on port (the default port for the project we're building this on top of and where our HTTP server is accepting requests), we use , followed by to say "on this server, navigate to the path where our websocket server is attached and include the query param set to the value ."

When we click the "Connect" button in the extension, we get an open connection to our websocket server. Next, to test it out, in the text area beneath the "Send" button, we enter a pre-written stringified object (created by running in the browser console) and then click the "Send" button to send that stringified object up to the server.

If we watch the server terminal at the top, we can see the query param being parsed from the URL when we connect and when we send a message, we see that message logged out on the server and get the expected message in return on the client.

Wrapping up

In this tutorial, we learned how to set up a websocket server and attach it to an existing Express HTTP server. We learned how to initialize the websocket server and then use the event on inbound connection requests to support the websockets protocol.

Finally, we looked at how to send and receive messages to our connected clients and how to use and to send objects via websockets.

Get the latest free JavaScript and Node.js tutorials, course announcements, and updates from CheatCode in your inbox.

No spam. Just new tutorials, course announcements, and updates from CheatCode.

Sours: https://cheatcode.co/tutorials/how-to-set-up-a-websocket-server-with-node-js-and-express

Server simple nodejs websocket

ws: a Node.js WebSocket library

Version npmCICoverage Status

ws is a simple to use, blazing fast, and thoroughly tested WebSocket client and server implementation.

Passes the quite extensive Autobahn test suite: server, client.

Note: This module does not work in the browser. The client in the docs is a reference to a back end with the role of a client in the WebSocket communication. Browser clients must use the native object. To make the same code work seamlessly on Node.js and the browser, you can use one of the many wrappers available on npm, like isomorphic-ws.

Table of Contents

Protocol support

  • HyBi drafts 07-12 (Use the option )
  • HyBi drafts 13-17 (Current default, alternatively option )

Installing

Opt-in for performance

There are 2 optional modules that can be installed along side with the ws module. These modules are binary addons which improve certain operations. Prebuilt binaries are available for the most popular platforms so you don't necessarily need to have a C++ compiler installed on your machine.

  • : Allows to efficiently perform operations such as masking and unmasking the data payload of the WebSocket frames.
  • : Allows to efficiently check if a message contains valid UTF-8.

API docs

See for Node.js-like documentation of ws classes and utility functions.

WebSocket compression

ws supports the permessage-deflate extension which enables the client and server to negotiate a compression algorithm and its parameters, and then selectively apply it to the data payloads of each WebSocket message.

The extension is disabled by default on the server and enabled by default on the client. It adds a significant overhead in terms of performance and memory consumption so we suggest to enable it only if it is really needed.

Note that Node.js has a variety of issues with high-performance compression, where increased concurrency, especially on Linux, can lead to catastrophic memory fragmentation and slow performance. If you intend to use permessage-deflate in production, it is worthwhile to set up a test representative of your workload and ensure Node.js/zlib will handle it with acceptable performance and memory usage.

Tuning of permessage-deflate can be done via the options defined below. You can also use and , which is passed directly into the creation of raw deflate/inflate streams.

See the docs for more options.

importWebSocket,{WebSocketServer}from'ws';constwss=newWebSocketServer({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 if context takeover is disabled.}});

The client will only use the extension if it is supported and enabled on the server. To always disable the extension on the client set the option to .

importWebSocketfrom'ws';constws=newWebSocket('ws://www.host.com/path',{perMessageDeflate: false});

Usage examples

Sending and receiving text data

importWebSocketfrom'ws';constws=newWebSocket('ws://www.host.com/path');ws.on('open',functionopen(){ws.send('something');});ws.on('message',functionincoming(message){console.log('received: %s',message);});

Sending binary data

importWebSocketfrom'ws';constws=newWebSocket('ws://www.host.com/path');ws.on('open',functionopen(){constarray=newFloat32Array(5);for(vari=0;i<array.length;++i){array[i]=i/2;}ws.send(array);});

Simple server

import{WebSocketServer}from'ws';constwss=newWebSocketServer({port: 8080});wss.on('connection',functionconnection(ws){ws.on('message',functionincoming(message){console.log('received: %s',message);});ws.send('something');});

External HTTP/S server

import{createServer}from'https';import{readFileSync}from'fs';import{WebSocketServer}from'ws';constserver=createServer({cert: readFileSync('/path/to/cert.pem'),key: readFileSync('/path/to/key.pem')});constwss=newWebSocketServer({ server });wss.on('connection',functionconnection(ws){ws.on('message',functionincoming(message){console.log('received: %s',message);});ws.send('something');});server.listen(8080);

Multiple servers sharing a single HTTP/S server

import{createServer}from'http';import{parse}from'url';import{WebSocketServer}from'ws';constserver=createServer();constwss1=newWebSocketServer({noServer: true});constwss2=newWebSocketServer({noServer: true});wss1.on('connection',functionconnection(ws){// ...});wss2.on('connection',functionconnection(ws){// ...});server.on('upgrade',functionupgrade(request,socket,head){const{ pathname }=parse(request.url);if(pathname==='/foo'){wss1.handleUpgrade(request,socket,head,functiondone(ws){wss1.emit('connection',ws,request);});}elseif(pathname==='/bar'){wss2.handleUpgrade(request,socket,head,functiondone(ws){wss2.emit('connection',ws,request);});}else{socket.destroy();}});server.listen(8080);

Client authentication

importWebSocketfrom'ws';import{createServer}from'http';constserver=createServer();constwss=newWebSocketServer({noServer: true});wss.on('connection',functionconnection(ws,request,client){ws.on('message',functionmessage(msg){console.log(`Received message ${msg} from user ${client}`);});});server.on('upgrade',functionupgrade(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,functiondone(ws){wss.emit('connection',ws,request,client);});});});server.listen(8080);

Also see the provided example using .

Server broadcast

A client WebSocket broadcasting to all connected WebSocket clients, including itself.

importWebSocket,{WebSocketServer}from'ws';constwss=newWebSocketServer({port: 8080});wss.on('connection',functionconnection(ws){ws.on('message',functionincoming(data,isBinary){wss.clients.forEach(functioneach(client){if(client.readyState===WebSocket.OPEN){client.send(data,{binary: isBinary});}});});});

A client WebSocket broadcasting to every other connected WebSocket clients, excluding itself.

importWebSocket,{WebSocketServer}from'ws';constwss=newWebSocketServer({port: 8080});wss.on('connection',functionconnection(ws){ws.on('message',functionincoming(data,isBinary){wss.clients.forEach(functioneach(client){if(client!==ws&&client.readyState===WebSocket.OPEN){client.send(data,{binary: isBinary});}});});});

echo.websocket.org demo

importWebSocketfrom'ws';constws=newWebSocket('wss://echo.websocket.org/',{origin: 'https://websocket.org'});ws.on('open',functionopen(){console.log('connected');ws.send(Date.now());});ws.on('close',functionclose(){console.log('disconnected');});ws.on('message',functionincoming(data){console.log(`Roundtrip time: ${Date.now()-data} ms`);setTimeout(functiontimeout(){ws.send(Date.now());},500);});

Use the Node.js streams API

importWebSocket,{createWebSocketStream}from'ws';constws=newWebSocket('wss://echo.websocket.org/',{origin: 'https://websocket.org'});constduplex=createWebSocketStream(ws,{encoding: 'utf8'});duplex.pipe(process.stdout);process.stdin.pipe(duplex);

Other examples

For a full example with a browser client communicating with a ws server, see the examples folder.

Otherwise, see the test cases.

FAQ

How to get the IP address of the client?

The remote IP address can be obtained from the raw socket.

import{WebSocketServer}from'ws';constwss=newWebSocketServer({port: 8080});wss.on('connection',functionconnection(ws,req){constip=req.socket.remoteAddress;});

When the server runs behind a proxy like NGINX, the de-facto standard is to use the header.

wss.on('connection',functionconnection(ws,req){constip=req.headers['x-forwarded-for'].split(',')[0].trim();});

How to detect and close broken connections?

Sometimes the link between the server and the client can be interrupted in a way that keeps both the server and the client unaware of the broken state of the connection (e.g. when pulling the cord).

In these cases ping messages can be used as a means to verify that the remote endpoint is still responsive.

import{WebSocketServer}from'ws';functionheartbeat(){this.isAlive=true;}constwss=newWebSocketServer({port: 8080});wss.on('connection',functionconnection(ws){ws.isAlive=true;ws.on('pong',heartbeat);});constinterval=setInterval(functionping(){wss.clients.forEach(functioneach(ws){if(ws.isAlive===false)returnws.terminate();ws.isAlive=false;ws.ping();});},30000);wss.on('close',functionclose(){clearInterval(interval);});

Pong messages are automatically sent in response to ping messages as required by the spec.

Just like the server example above your clients might as well lose connection without knowing it. You might want to add a ping listener on your clients to prevent that. A simple implementation would be:

Sours: https://github.com/websockets/ws
WebSockets with NodeJS (Express) and WebSocket API

Node.js WebSocket Programming Examples

An overview and examples of basic socket and WebSocket programming with Node.js.


WebSockets are an excellent technology selection when you are designing your real-time app. Imagine an app user interface where you see real-time stock prices. The faster a user learns about a stock price’s change, the faster they can react, and execute a buy or sell order. Money is on the line.

Stock Ticker with PubNub and Golang

 

What is a WebSocket?

WebSocket is its own layer 7 protocol, similar to HTTP. WebSockets create a full-duplex connection for sending messages from client to server, or server to client at any instant. This pattern is far superior to HTTP request-response when an application requires systems to get the latest data ASAP.

When Should I Write WebSocket Code?

Besides a real-time stock or cryptocurrency tracker app, other common real-time use cases for WebSockets are:

WebSockets create a TCP socket connection between multiple devices or processes. Similar functionality can be implemented using HTTP Long Polling or using a service like PubNub. Let’s go over some basic socket and WebSocket programming with Node.js.

Node.js Socket Example

Let’s say you need to write a server application, and you chose Node.js as your programming language. Your users can be any type of client, like a web browser, mobile app, IoT device, Node.js client, or anything that knows TCP.

You need to serve assets to your users over HTTP, but you also need to provide them with streams for bi-directional messaging. We can accomplish this in a single Node.js server app!

The code from the video, and also this article is available in my Node.js WebSocket Examples GitHub Repository.

First we’ll go over some plain socket code, followed by WebSocket code. If you already serve assets with something like Express.js, Hapi, or the native Node.js HTTP library, we can jump into the socket code.

Socket Server JavaScript Code

// Node.js socket server script const net = require('net'); // Create a server object const server = net.createServer((socket) => { socket.on('data', (data) => { console.log(data.toString()); }); socket.write('SERVER: Hello! This is server speaking.
'); socket.end('SERVER: Closing connection now.
'); }).on('error', (err) => { console.error(err); }); // Open server on port 9898 server.listen(9898, () => { console.log('opened server on', server.address().port); });

This script runs a Node.js socket server on port 9898. Whenever a client connects to this server app (IP_ADDRESS:9898) the server sends the client a string over the open socket. It says “SERVER: Hello! This is server speaking.” Whenever the client sends some data to the server, the Node.js script logs the contents in the ‘data’ event handler.

Socket Client JavaScript Code

Here we have our Node.js socket client script, which can connect to the Node.js socket server above.

// Node.js socket client script const net = require('net'); // Connect to a server @ port 9898 const client = net.createConnection({ port: 9898 }, () => { console.log('CLIENT: I connected to the server.'); client.write('CLIENT: Hello this is client!'); }); client.on('data', (data) => { console.log(data.toString()); client.end(); }); client.on('end', () => { console.log('CLIENT: I disconnected from the server.'); });

The client script attempts to connect to localhost:9898. If the connection succeeds, then the client sends a string to the server over the open socket. It says “CLIENT: Hello this is client!” Whenever the server sends some data to the client, the client logs it in the ‘data’ event handler.

This is what the output looks like for client and server Node.js socket scripts running on the command line.

Node.js Socket Server and Client Interaction on the Command Line

Node.js WebSocket Example

Writing socket code is fun, but when you’re trying to implement it in a web browser, it’s kind of complicated. This issue has been addressed by all major browsers in their action to support the WebSocket protocol out of the box! This way, web pages that use sockets can load really fast because the front end libraries for handling the protocol are already in the browser applications. No need to fetch big JS libraries whenever a user visits your real-time app web page.

Node.js WebSocket Server

Let’s swap out our Node.js socket server code for WebSocket server code! This way, we will be able to easily serve our web browser users. We’ll go over some vanilla JS for WebSockets that can be implemented in something like a React.js application.

This code uses the Node.js native “http” library and a 3rd party WebSocket NPM package to create a WebSocket server. It has the same functionality as the socket script we wrote earlier. This time, we are using the official WebSocket protocol to bi-directionally send our data between client and server.

// Node.js WebSocket server script const http = require('http'); const WebSocketServer = require('websocket').server; const server = http.createServer(); server.listen(9898); const wsServer = new WebSocketServer({ httpServer: server }); wsServer.on('request', function(request) { const connection = request.accept(null, request.origin); connection.on('message', function(message) { console.log('Received Message:', message.utf8Data); connection.sendUTF('Hi this is WebSocket server!'); }); connection.on('close', function(reasonCode, description) { console.log('Client has disconnected.'); }); });

Node.js WebSocket Browser Client

Next, we have our HTML file that loads up in client web browsers. Notice that the WebSocket class in the browser JS has no declaration. This is because modern browsers give developers automatic access to this class in their front-end JavaScript!

<!DOCTYPE html> <html> <head> <title>WebSocket Playground</title> </head> <body> </body> <script> const ws = new WebSocket('ws://localhost:9898/'); ws.onopen = function() { console.log('WebSocket Client Connected'); ws.send('Hi this is web client.'); }; ws.onmessage = function(e) { console.log("Received: '" + e.data + "'"); }; </script> </html>

We can get our fun client-server handshake example going fast! Here’s what the output for the server script and the web browser JS console look like:

Node.js WebSocket Full Stack App

Peer-to-Peer Message Passing

The above samples are intuitive code implementations for real-time application development. What if we want to stream data from user to user? What if we want to do this without implementing the complicated routing logic on our server to connect two or more users? We can accomplish all of this cheaply, securely, and without having to spin-up expensive infrastructure.

We have access to awesome, hosted, real-time infrastructure with PubNub. We can infinitely scale to any user volume. PubNub offers low cost, transaction-based pricing with easy to use messaging APIs. Let’s take a look at an example for peer-to-peer messaging. By the way, this can also be implemented to stream data from client to server, or server to client, in addition to peer-to-peer.

Before you try the following scripts you must get your free PubNub API keys. They work for up to 1 million free transactions per month, forever. Use this form to get free API keys right now.

PubNub Data Streaming

We can bi-directionally send data between services, clients, or server apps using the PubNub global data stream network. There is an SDK for every popular language and device. Here is the basic browser JS or Node.js code for utilizing the Pub/Sub network. This publishes a message whenever the user hits the return key.

const PubNub = require('pubnub'); // or in browser: <script src="https://cdn.pubnub.com/sdk/javascript/pubnub.4.24.4.js"></script> const pubnub = new PubNub({ publishKey: 'your_pubnub_publish_api_key_here', subscribeKey: 'your_pubnub_subscribe_api_key_here' }); pubnub.subscribe({ channels: ['my_channel'] }); pubnub.addListener({ message: (pubnubMessage) => { console.log('New Message:', pubnubMessage.message); } }); // Use Control + C to end the program process.stdin.on('data', (key) => { // When the user presses the return key if (key.toString() === '
') { pubnub.publish({ message: 'Hello from client 1!', channel: 'my_channel' }); } });

Note that the “process” object cannot be accessed in web browser JS, but a similar key press event handler can accomplish the same functionality.

object.addEventListener('keypress',(event) => {});

PubNub Node.js SDK

Here is the documentation for the PubNub JavaScript SDK.

When we execute the above script in 2 terminal windows, we can see real-time Pub/Sub in action. I made a second script with the same code, except the published message indicates that it comes from client number “2.” Be sure to install the PubNub Node.js SDK before you try executing the scripts on your command line.

npm install pubnub

PubNub Node.js Pub/Sub API Example Screenshot

That’s all there is to it. I hope you were able to glean some valuable insights from this peer-to-peer, client-to-server, and server-to-client WebSocket data streaming tutorial. Please reach out to us at [email protected] if you need assistance or have some questions about building a real-time application. We love hearing your ideas!

For more on implementing JavaScript with PubNub, take a look at our React Native blog post tutorials for real-time geolocation tracking, a real-time chat app, and more! There is also a blog post about socket programming in Python. Thanks for reading! If you liked this post, subscribe to our newsletter!

Sours: https://www.pubnub.com/blog/nodejs-websocket-programming-examples/

You will also like:

Create a Node Websocket Server in Five Minutes

Node.js Logo - node websocket serverLeveraging Express.js and the ws NPM module, it is possible to create a Node Websocket Server in less than ten lines of code.

The Websocket protocol provides full-duplex communication channels over a single TCP connection. In the past, web clients had to employ long-polling or the repeated pinging of a server in order to achieve this kind of “push” functionality. Now, Websocket technology eliminates the need for such outdated techniques. So, when a Websocket client connects to the server, a persistent connection is created, and the Websocket server can then push notifications to all connected clients. It is possible for the clients to send messages to the Websocket server as well, but I’ll cover that in a later article.

In this article, I’ll explain the bare-minimum code needed to create a Node Websocket server that can broadcast all incoming messages to connected clients. This should take us about five minutes, and less than ten lines of code. The beauty of Express.js is that it takes care of the heavy lifting with regard to the actual web server. The ws NPM module also plays a starring role in that it handles the Websocket communication layer, allowing us to expose an endpoint that accepts connections and messages from clients. Plus, we can broadcast messages to connected clients.

package.json

Above is the contents of package.json. There are only two dependencies: the Express.js framework and the ws module.

The Node Websocket Server – Example # 1

So, here in Example # 1 we have the entire working application. On line #s 3 through 9 we create our dependencies. I’ve grouped things in a way that I hope makes sense, but I’ll just point out that on a high level there are two things happening here. We require the modules that we need as constants: http, express, and WebSocket. Also, we create the constants app, server and websocketServer. These constants are the results of expressions. Now if you’ve ever worked with Express.js before, the app constant should be familiar to you; it’s simply an instance of the Express framework. The server constant is the result of calling http.createServer(), passing it our express.js instance (ie. “app”). And finally, the constant websocketServer represents our Websocket server.

Now let’s jump ahead for a moment to line # 30, where we start our web server. It’s not that there’s much going on here; it’s just that I wanted to point out that the server is started by calling the server.listen method, passing it the port to listen on (i.e. 3000). The second argument (the anonymous function) is optional.

Now let’s go back up to the top of the file. As you can see, the rest of the code is surprisingly simple. We create two event handlers, the first of which takes care of each Websocket client connection, and the second one processes each message that it receives from that client. On line # 12, we have the first event handler. We use the “on” method of the websocketServer instance to handler an incoming connection. This is somewhat similar to creating a handler for a GET or POST request in Express.js.

We pass the event as the first argument (i.e. “connection”), and then a function as the 2nd argument. The anonymous function that we provide contains the code that we want executed for each new Websocket client connection. This function also receives a Websocket client as its first argument. We have named this variable: “webSocketClient”. On line # 14 we provide some feedback to the Websocket client by sending it the first Websocket message: { “connection” : “ok”}. This is for demonstration purposes only, just so that we can see right away that the connection has been established.

Now inside of the anonymous callback, we set up the second event handler, which will process each message that this client receives. And similar to the connection event handler, we use the “on” method of the webSocketClient variable to handler an incoming message. We pass the event as the first argument (i.e. “message”), and then a function as the 2nd argument. The anonymous function that we provide contains the code that we want executed for each message received by this Websocket client.

Broadcasting the Message to All Websocket Clients

On line # 20, we start the process of broadcasting the incoming message to all Websocket clients. Using the forEach method of the Websocket.clients list, we iterate the list of websocket clients. And for each iteration, we provide a callback function. This callback function receives the currently iterated Websocket client as its first argument. So, we then use the send method of that client object, and send the incoming message (i.e. by sending one message to many recipients, we are “broadcasting” that message).

Testing the Websocket Server

Now if you copy all of the code from Example # 1 into a file and then execute it, you’ll have a running Websocket server on port # 3000. But that isn’t enough. Now we want to test our websocket server, and an easy way to do this is to use the Smart Websocket Client plugin for Google Chrome.

So go ahead and click this link to install the plugin, and once you’ve installed it, start the plugin by clicking the icon in the upper-right-hand corner of your Chrome browser.

smart-websocket-client-icon
smart-websocket-client-1

Once the Smart Websocket Client is running, enter http://localhost:3000 in the address bar and then click the “Connect” button. You should see { “connection” : “ok”} in the lower window, indicating that a Websocket connection was successfully established (see example # 2).

smart-websocket-client-2
smart-websocket-client-3

Example # 2

In the top window, enter any text, click the “Send” button, then you’ll see your message appear in the lower window. Now open a few more instances of the Smart Websocket Client and follow the same steps. If you place your Chrome browser tabs side by side, you’ll see that every message you’ve sent has been broadcast to every Websocket client. Congratulations!  You’ve just built a working Node Websocket server.

Example # 3

Now earlier in this article, I promised that we could create our Websocket server in less than ten lines of code. Example # 1 clocks in at 32 lines of code, but this is because I used whitespace and comments to make the code as readable as possible. So, in Example # 3, I’ve provided the condensed version of our Node Websocket server. This code is not very pretty, but as promised, it is a fully functional Node Websocket server that’s set up in less than ten lines

Sours: https://blog.kevinchisholm.com/javascript/node-js/websocket-server-five-minutes/


584 585 586 587 588