6

I'm trying to run a socket.io chat app with nginx as proxy. It works fine when I connect to the server via http+port, but it doesn't work with https. I see user connected/disconnected events pass through, but no emit reach client or server.

Here's my server .conf (nginx/1.4.6 Ubuntu)

upstream websocket {
    server 127.0.0.1:8090;
}

server {
    listen 80;
    return 301 https://example.com$request_uri;
}

server {
    listen   443 ssl;

    ssl_certificate    /home/andrew/example.com/nginx/certs/example.com.cer;
    ssl_certificate_key    /home/andrew/example.com/nginx/certs/example.com.private.key;

    root /home/andrew/example.com/public;
    index index.html index.htm;

    server_name example.com;

    location /chat/ {
        rewrite ^/chat/?(.*)$ /$1 break;
        proxy_pass http://websocket;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
    }

    location / {
        try_files $uri $uri/ =404;
    }
}

Server (Node v0.12.1, Socket.io v1.3.5)

var express = require('express');
var app = express();
var server = require('http').createServer( app );
var io = require("socket.io").listen( server );

server.listen(8090);
console.log('listening on port 8090');

io.sockets.on( 'connection', function( socket ){
    console.log( 'user connected' );

    var msg = "user connected!!!";
    socket.emit( 'message', msg );

    socket.on('disconnect', function(){
        console.log('user disconnected');
    });

    socket.on('message', function( msg ){
        socket.emit( 'message', msg );
        console.log('message: ' + msg);
    });

});

Client

<ul id="messages"></ul>
<form action="">
  <input id="m" autocomplete="off" /><button>Send</button>
</form>

<script src="https://example.com/chat/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
  var socket = io( "https://example.com/chat", {path: '/chat/socket.io'} );
  $('form').submit(function(){
    socket.emit('message', $('#m').val());
    $('#m').val('');
    return false;
  });

  socket.emit('message', "sup");

  socket.on('message', function(msg){
    $('#messages').append($('<li>').text(msg));
  });      
</script>
1

1 Answer 1

5

Ok, it turned out it was an issue with socket.io's namespaces in node.js code. More info here: http://socket.io/docs/rooms-and-namespaces

Here's a working example of the server

var app = require( 'express' )();
var http = require( 'http' ).Server( app );
var io = require( 'socket.io' )( http );
var nsp = io.of('/chat');  // this is what needs to happen


// and then we're listening to communication in the proper namespace
nsp.on( 'connection', function( socket ){
    console.log( 'user connected' );

    socket.on('disconnect', function(){
        console.log('user disconnected');
    });

    socket.on('message', function(msg){
        nsp.emit( 'message', msg );     // this will broadcast message to everybody connected within the same namespace
        console.log('message: ' + msg);
    });

});


http.listen( 8090, function(){
    console.log( "listening on :8090" );
});
Sign up to request clarification or add additional context in comments.

2 Comments

Can you help me with this issue stackoverflow.com/questions/45467169/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.