0

I had built an application using Node JS and socket.io. It was working fine. Since I had to move the application over a secure connection, I changed the code to support SSL.

But, now I am unable to do a socket.emit. Neither server, nor the client is able to emit the messages.

The connections are made successfully, but nothing gets emitted afterwards.

Here is the code.

Server Side

var fs = require( 'fs' );

var options = {
       key:  fs.readFileSync('/etc/httpd/conf.d/ssl/*.xyz.in.key'),
       cert: fs.readFileSync('/etc/httpd/conf.d/ssl/xyz.in.crt'),
       requestCert:        true,
       rejectUnauthorized: false  // Tried both, with and without this line.
  };

var io = require( 'socket.io' ).listen( 8888, options );

io.sockets.on('connection', OnConnection );

io.set("origins", "*:*"); // Tried with and without this line.

// Called when a connection is made with a new Client.
function OnConnection ( socket )
{
    console.log( socket.id + " connected" ); // This line gets printed.
    socket.on('ev_SendMsgForApproval', OnMsgReceivedForModApproval );
}

function OnMsgReceivedForModApproval( data )
{
     console.log( data ); //This does not get executed. :(
}

Client Side

var socket = io.connect("https://xyz.com:8888", {secure : true} );

// This message get called for sure.
function OnMsgSendClick()
{
    console.log( "Hi" );  // This gets printed on browser's console.
    socket.emit( 'ev_SendMsgForApproval', { chatMsg: "Hi" } );
    return false;
}

I have also tried to do emit from server, but that data, does not reach the client either. In debug I am able to see that server has emitted something, but that does not reach the client.

All this was working fine without the SSL.

What could be the issue? Stuck with this from a long time. Please help.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
Manu
  • 901
  • 1
  • 8
  • 28

2 Answers2

1

I always leave the ssl burden to stunnel, an ssl proxy that listens on a secure port defined by you (such as 443) and forwards all incoming traffic, already decrypted, to another port where your non-ssl application is listening (usually 80).

Here you have a gist with a simple stunnel configuration: https://gist.github.com/mbenedettini/5911415

MrTorture
  • 810
  • 6
  • 8
  • Ok.. But none of the clients would be connecting to the http of socket. Since I have already written in the html code to connect to `https`. Hope you got the question right. :D – Manu Jul 04 '13 at 16:53
  • Your clients will still be connecting to https port (443), where stunnel is listening. Stunnel will decrypt all the incoming traffic and forward it to port 80. – MrTorture Jul 05 '13 at 14:59
  • Its the main `https` site that is running on 443 port and main `http` site on 80. As you can see from the code in the question I am have specified the port to be 8888, so that's the port that will be used, no matter what. – Manu Jul 05 '13 at 19:39
  • Anyways, thanks for your help, I found the answer to my question. I will be posting it in some time. – Manu Jul 05 '13 at 19:39
  • Just make io listen in another port, such as 8887, without ssl: `var io = require( 'socket.io' ).listen(8887)` And change the ports in the example stunnel configuration: `accept = 8888 connect = 8887` – MrTorture Jul 05 '13 at 20:42
0

I solved the problem after a few days.

The problem was in the following line on the client side.

var socket = io.connect("https://xyz.com:8888", {secure : true} );

We are not supposed to add {secure : true}, so the line simply becomes

var socket = io.connect("https://xyz.com:8888" );

How I came to know about this solution? I learnt how to analyse the Web Socket data traffic using Chrome Dev tools

Very soon I found out that the client was emitting {secure : true} as the 1st element of the array. This changed the structure of the entire object. As a result of all this server was not able to resolve the Event Name, since the first array element was not containing the event name.

I removed {secure : true} and it worked. :)

Manu
  • 901
  • 1
  • 8
  • 28