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