Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integrating websockets with a standard http.Server

I have a simple webserver like

var http = require('http'),
    url = require('url');
var server = http.createServer(function (req, res) {
  var uri = url.parse(req.url).pathname;
  if (uri == '/') {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
    return;
  }

  res.writeHead(404, {'Content-Type': 'text/plain'});
  res.end('File not found');
});
server.listen(0, '127.0.0.1');

I would now like to connect a single path (say, /ws) to a websocket, but leave the rest of the server unmodified.

However, ws seems to require me to set up a dedicated server (with everything that that entails, like SSL termination, security configuration, and port allocation).

How can I terminate just the path /ws to a websocket implementation?

like image 829
phihag Avatar asked Jan 11 '13 08:01

phihag


People also ask

Can I use WebSockets and HTTP?

WebSockets effectively run as a transport layer over the TCP. Once connected through an HTTP request/response pair, the clients can use an HTTP/1.1 mechanism called an upgrade header to switch their connection from HTTP over to WebSockets.

How do you integrate a WebSocket?

To open a websocket connection, we need to create new WebSocket using the special protocol ws in the url: let socket = new WebSocket("ws://javascript.info"); There's also encrypted wss:// protocol. It's like HTTPS for websockets.

Can WebSocket and HTTP run on same port?

Yes it can run on the same port, in fact it must run on the same port; the raison d'etre of websocket handshake is so that the websocket can run on the same connection without confusing intermediaries that doesn't understand websocket.

Why is WebSockets not used?

Avoid using WebSockets if only a small number of messages will be sent or if the messaging is very infrequent. Unless the client must quickly receive or act upon updates, maintaining the open connection may be an unnecessary waste of resources.


2 Answers

You may add the socket.io on the same port with your app. If you want the /ws path, then use:

var io = require('socket.io').listen(httpServer, { resource: '/ws/socket.io' });

Or have /ws point to /ws/socket.io

like image 119
randunel Avatar answered Sep 16 '22 12:09

randunel


I would recommend using the websocket package, it is a

Websocket Client & Server Library implementing the WebSocket protocol as specified in RFC 6455.

Which is what I wanted so it's why I use it. It's incredibly painless to use and I'm actually doing both wss and ws connections to node.js from html clients using pure javascript websockets.

The git project is active, when I've posted issues I've had a response on the same day. An example from the link above shows how simple it is:

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,
    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.');
    });
});

I should note, however, that the subprotocols is not obvious, as there is no example. There are some questions on the git site for the project that lead you in the right direction though.

like image 27
Metalskin Avatar answered Sep 18 '22 12:09

Metalskin