0

I have a Nginx Serving my ember build as follows:

server {
  listen 80;
  root /home/ubuntu/my-app/dist;
  index index.html;

  location /api {
    proxy_pass http://127.0.0.1:3000;
  }

  location / {
    try_files $uri $uri/ /index.html;
  }
}

I want to add a chat using socket.io, but I already have REST api on port 3000. I'm wondering what the best way to architect this.

I thought I could add another location as follows:

  location /socket.io {
    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;
    proxy_pass http://socket_nodes;
  }

But it's not working. If someone could point me in the right direction, that'd be really great.

thanks in advance.

imahungry
  • 126
  • 8
  • 2
    Have you studied the specific nginx doc for socket.io: http://nginx.com/blog/nginx-nodejs-websockets-socketio/? – jfriend00 Dec 13 '14 at 07:17
  • I have, but I'm unclear. Because already have a node api listening on port 3000. I want to use a socket also and was thinking to add another proxy on another port. But I'm pretty sure there's a better way to do this. – imahungry Dec 13 '14 at 08:42
  • 1
    Nginx as reverse-proxy is the most well known scenario. It means you can proxy any local/remote resource via same port. Share Nginx logs so we can help you quickly – Anatoly Dec 13 '14 at 10:25
  • This is what I was looking for. How to build a rest API along with socket.io. http://stackoverflow.com/a/21813645/3957625 Ty for comments. – imahungry Dec 13 '14 at 14:42

2 Answers2

0

If you're using node as your web server, then socket.io shares the same port and IP as the web server and your REST API.

A socket.io connection starts out as a regular http request to the /socket.io path. The socket.io library hooks into your web server to handle that specific http request. After a couple back and forth, the two ends agree to "upgrade" the protocol from http to webSocket and then the conversation continues as the webSocket protocol but still on the same IP and port as your webServer operates on.

All this can work fine with nginx as a proxy if you configure nginx as specified in the configuration link I gave you earlier so that it proxies all the right things and if socket.io is configured properly with your nodejs server to hook into it properly.

There's really no architectural changes to make as the web requests and socket.io connections both operate through the same web server without you having to do anything. The socket.io connection just makes an http request to the /socket.io path with some special HTTP headers set. The socket.io server code just hooks into your web server to handle that specific request and take it from there. The rest of your REST API calls are just handled by the same mechanism you already have. So, as long as you don't try to define an API call for /socket.io, the two will happily stay out of each other's way, just like the handlers for two different routes on your web server stay out of each other's way. You can see a lot more about how incoming socket.io calls work in this answer.

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

So I finally got this to work and thought I'd share my findings.

Nginx: For my api proxy, I can actually share the same port as my node API. I just needed to add version and headers.

location /api {
  proxy_pass http://127.0.0.1:3000;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
}

server.js

var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res) {
  res.sendFile(__dirname + '/index.html');
});


io.on('connection', function(socket) {
    console.log("[NOTIFICATION] - New connection");
    io.sockets.emit("message", { message: "New connection" });
    socket.on("send", function(data) {
    io.sockets.emit("message", { message: data.message });
});

http.listen(3000);

Ember: https://github.com/keydunov/emberjs-socketio-chat is a pretty good example, and use of socket.io

imahungry
  • 126
  • 8