sitegui / nodejs-websocket

A node.js module for websocket server and client

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

WS on sencha connect

rumkin opened this issue · comments

Is it possible to integrate nodejs-websocket with connect (or express) https server to run on the same port?

@rumkin this is a very valid question - I too am interested in hearing the answer and seeing some example usage if possible this this lib - the existing chat sample code uses two ports - evidently one port is possible if only one server uses it - which then forwards the traffic based on whether its a web socket or http

@rumkin nice question! The nodejs-websocket was built on top of TCP, not HTTP (express).

This means this module expects to read the handshake headers on bare TCP and this would conflict a lot with connect/express.

I wonder why this would be needed, I believe it's better to keep them separated.

In any case, a solution that I can think of is proxing from express to another port. Something like:

// app is an express instance
// this will proxy all data from /ws to your local ws server
app.use('/ws', function (req, res) {
    net.connect(WS_PORT, 'localhost', function (conn) {
        // Send the handshake again (see bellow)
        conn.write(recreateWSHandshake(req))
        // Proxy
        conn.pipe(req.socket)
        req.socket.pipe(conn)
    })
    // TODO: handle errors
})

(I have not tested this code!)

The idea is to create the WS on a diferent port (it can be a virtual port in this case) and proxy the underlying TCP captured from express to a new bare connection to WS server.

The recreateWSHandshake would be something like:

function recreateWSHandshake(req) {
    return "GET "+req.url+" HTTP/1.1\r\n"+
        "Host: "+req.headers.host+"\r\n"+
        "Upgrade: websocket\r\n"+
        "Connection: Upgrade\r\n"+
        "Sec-WebSocket-Key: "+req.headers["sec-websocket-accept"]+"\r\n"+
        "Sec-WebSocket-Version: 13\r\n\r\n"
}

Tell me if it works :)

i have changed some part of your example.

// "sec-websocket-accept" -> "sec-websocket-key"
function recreateWSHandshake(req) {
return "GET "+req.url+" HTTP/1.1\r\n"+
"Host: "+req.headers.host+"\r\n"+
"Upgrade: websocket\r\n"+
"Connection: Upgrade\r\n"+
"Sec-WebSocket-Key: "+req.headers["sec-websocket-key"]+"\r\n"+
"Sec-WebSocket-Version: 13\r\n\r\n"
}

// 'server' is 'http' module`s instance can used with express
server.on('upgrade', function(req, socket, head) {
var client = net.connect({port: 4000}, function () {
// Send the handshake again (see bellow)
client.write(recreateWSHandshake(req))
// Proxy
client.pipe(req.socket)
req.socket.pipe(client)
});
socket.once('close', function(e) {
client.destroy();
});
});

It works well. but this approach needs so many ports