phihag
phihag

Reputation: 287755

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?

Upvotes: 15

Views: 21699

Answers (2)

Metalskin
Metalskin

Reputation: 4268

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.

Upvotes: 16

randunel
randunel

Reputation: 8945

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

Upvotes: 2

Related Questions