Sam Fast
Sam Fast

Reputation: 601

Client behind proxy server can't connect socket.io

I am using socket.io with my expressjs (NodeJs) application. I have a simple scenario where I have a room which allows only two persons to join in.

Whenever I connect to my website and I am not behind proxy server everything works fine. Messages get exchanged between server and client.

This does not happen when I try to connect my website when I am behind proxy server. I get the following error on my server side.

debug - client authorized
info  - handshake authorized HjRiaKY1tR0zSbrieZ4t
debug - setting request GET /socket.io/1/websocket/HjRiaKY1tR0zSbrieZ4t
debug - set heartbeat interval for client HjRiaKY1tR0zSbrieZ4t
debug - client authorized for 
debug - websocket writing 1::
debug - setting request GET /socket.io/1/websocket/HjRiaKY1tR0zSbrieZ4t
debug - set heartbeat interval for client HjRiaKY1tR0zSbrieZ4t
warn  - websocket connection invalid
info  - transport end (undefined)
debug - set close timeout for client HjRiaKY1tR0zSbrieZ4t
debug - cleared close timeout for client HjRiaKY1tR0zSbrieZ4t
debug - cleared heartbeat interval for client HjRiaKY1tR0zSbrieZ4t
debug - discarding transport
debug - cleared heartbeat interval for client HjRiaKY1tR0zSbrieZ4t
debug - setting request GET /socket.io/1/websocket/HjRiaKY1tR0zSbrieZ4t
debug - set heartbeat interval for client HjRiaKY1tR0zSbrieZ4t
warn  - websocket connection invalid
info  - transport end (undefined)
debug - set close timeout for client HjRiaKY1tR0zSbrieZ4t
debug - cleared close timeout for client HjRiaKY1tR0zSbrieZ4t
debug - cleared heartbeat interval for client HjRiaKY1tR0zSbrieZ4t
debug - setting request GET /socket.io/1/websocket/HjRiaKY1tR0zSbrieZ4t
debug - set heartbeat interval for client HjRiaKY1tR0zSbrieZ4t
warn  - websocket connection invalid
info  - transport end (undefined)
debug - set close timeout for client HjRiaKY1tR0zSbrieZ4t
debug - cleared close timeout for client HjRiaKY1tR0zSbrieZ4t
debug - cleared heartbeat interval for client HjRiaKY1tR0zSbrieZ4t

This is how my server code looks like (removed unnecessary details for simplicity)

var app = express();
require('./routes')(app);

var server = http.createServer(app)

var io = require('socket.io').listen(server);

io.set('heartbeat interval', 20);
io.set('heartbeat timeout', 60); 
io.set('close timeout', 60); 

io.enable('browser client minification');  // send minified client
io.enable('browser client etag');          // apply etag caching logic based on version number
io.enable('browser client gzip');          // gzip the file
//io.set('log level', 1);                    // reduce logging

//Commented on purpose for testing (before this it used polling but it also failed)
io.set('transports', [
    'websocket'
//  , 'htmlfile'
//  , 'xhr-polling'
//  , 'jsonp-polling'
]);

server.listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

io.sockets.on('connection', function (socket){

// convenience function to log server messages on the client
function log(){
    var array = [">>> Message from server: "];
  for (var i = 0; i < arguments.length; i++) {
    array.push(arguments[i]);
  }
    socket.emit('log', array);
}

socket.on('message', function (message) {
    log('Got message:', message);
// for a real app, would be room only (not broadcast)
    socket.broadcast.emit('message', message);
});

socket.on('create or join', function (room) {
    var numClients = io.sockets.clients(room).length;

    log('Room ' + room + ' has ' + numClients + ' client(s)');
    log('Request to create or join room ' + room);

    if (numClients === 0){
        socket.join(room);
        socket.emit('created', room);
    } else if (numClients === 1) {
        io.sockets.in(room).emit('join', room);
        socket.join(room);
        socket.emit('joined', room);
    } else { // max two clients
        socket.emit('full', room);
    }
    socket.emit('emit(): client ' + socket.id + ' joined room ' + room);
    socket.broadcast.emit('broadcast(): client ' + socket.id + ' joined room ' + room);

});

});

This is how my client looks like:

var room = prompt("Enter room name:");

var socket = io.connect();

if (room !== '') {
  console.log('Create or join room', room);
  socket.emit('create or join', room);
}

socket.on('created', function (room){
  console.log('Created room ' + room);
  isInitiator = true;
});

socket.on('full', function (room){
  console.log('Room ' + room + ' is full');
});

socket.on('join', function (room){
  console.log('Another peer made a request to join room ' + room);
  console.log('This peer is the initiator of room ' + room + '!');
  isChannelReady = true;
});

socket.on('joined', function (room){
  console.log('This peer has joined room ' + room);
  isChannelReady = true;
});

socket.on('log', function (array){
  console.log.apply(console, array);
});

I have searched a lot but could not find any solution. If anybody knows, kindly help me out. Thanks.

Upvotes: 2

Views: 3280

Answers (1)

An old question. Maybe someone needs an answer.

If you are behind a simple http(s) proxy, you can use the following, this is a node client written in typescript...

var HttpsProxyAgent = require('https-proxy-agent');

let proxy = 'http://172.18.200.182:8080';
let opts: SocketIOClient.ConnectOpts = { agent: new HttpsProxyAgent(proxy) };

var socket = require('socket.io-client').connect('http://your.socket.io.server', opts);

Upvotes: 2

Related Questions