Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using socket.io with nodejs on a server with apache as a reverse proxy

I'm attempting to use Node.js with Socket.IO to faciliate messaging between the browser and client, following the guide.

However, I had to setup Node reverse-proxied behind Apache. So, instead of example.com:8080 for node, I'm using example.com/nodejs/.

This seems to cause Socket.IO to lose sense of itself. Here's my node app

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

// this has to be here, otherwise the client tries to 
// send events to example.com/socket.io instead of example.com/nodejs/socket.io
io.set( 'resource', '/nodejs/socket.io' );

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

  socket.emit('bar', { one: '1'});

  socket.on('foo', function( data )
  {
    console.log( data );
  });

});

And here's what my client file looks like

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Socket.IO test</title>

  <script src="http://example.com/nodejs/socket.io/socket.io.js"></script>

  <script>

  var socket = io.connect('http://example.com/nodejs/');

  console.log( socket );

  socket.on( 'bar', function (data)
  {
    console.log(data);
    socket.emit( 'foo', {bar:'baz'} );
  });

  socket.emit('foo',{bar:'baz'});

  </script>
</head>
<body>
  <p id="hello">Hello World</p>
</body>
</html>

The problem here is the script reference to http://example.com/nodejs/socket.io/socket.io.js. It doesn't return the expected javasscript content - instead it returns "Welcome to socket.io" as if I hit http://example.com/nodejs/.

Any idea how I can make this work?

like image 483
Peter Bailey Avatar asked May 03 '12 23:05

Peter Bailey


People also ask

How does the Socket.IO work in Nodejs?

The bidirectional channel between the Socket.IO server (Node. js) and the Socket.IO client (browser, Node. js, or another programming language) is established with a WebSocket connection whenever possible, and will use HTTP long-polling as fallback.

What is reverse proxy in node JS?

Reverse proxy is a proxy server which retrieve resources on behalf of client from one or more servers. Client end need not to know about all those servers. They request to proxy server on specific URL with over HTTP and proxy server finds out where to look ( in Servers ) to serve that request.

Does Socket.IO use WebRTC?

Socket.IO P2P provides an easy and reliable way to setup a WebRTC connection between peers and communicate using the socket. io-protocol. Socket.IO is used to transport signaling data and as a fallback for clients where the WebRTC PeerConnection is not supported.


2 Answers

This ended up being a multi-pronged solutions.

First, on the server end of things, I had to set up the endpoints like this

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

var rootSockets = io.of('/nodejs').on('connection', function(socket)
{
  // stuff
});

var otherSockets = io.of('nodejs/other').on('connection', function(socket)
{
  // stuff
});

Then, on the client-side, to properly connect looks like this

var socket = io.connect(
    'http://example.com/nodejs/'
  , {resource: 'nodejs/socket.io'}
);

// The usage of .of() is important
socket.of('/nodejs').on( 'event', function(){} );
socket.of('/nodejs/other').on( 'event', function(){} );

After this, it all worked. Remember, on this server Apache is proxying example.com/nodejs to port 8080 internally.

like image 168
Peter Bailey Avatar answered Sep 26 '22 01:09

Peter Bailey


I don't think this has anything to do with your apache proxy, but some 'quirks' with how socket.io handles requests on a sub-directory. See my answer here. NGINX configuration to work with Socket.IO

Basically, you need to use this connect statement instead:

var socket = io.connect('http://example.com', {resource:'nodejs/socket.io'});

like image 34
Timothy Strimple Avatar answered Sep 24 '22 01:09

Timothy Strimple