Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WS on sencha connect #3

Closed
rumkin opened this issue Mar 6, 2014 · 3 comments
Closed

WS on sencha connect #3

rumkin opened this issue Mar 6, 2014 · 3 comments
Labels

Comments

@rumkin
Copy link

rumkin commented Mar 6, 2014

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

@scottstensland
Copy link

@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

@sitegui
Copy link
Owner

sitegui commented Aug 8, 2014

@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 :)

@rndmania
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants