HoneyWine
HoneyWine

Reputation: 187

NodeJS and socket.io app on Heroku with 2 ports

My app has an express server listening on one port (process.env.PORT) and I also want a web socket using another port. I used to use Express 3 with this set-up:

var express         = require('express'),
    http             = require('http'),
    io              = require('socket.io'),
    app             = express();
    server          = http.Server(app);
    ioServer        = io(server);

ioServer.on('connection', callback);
server.listen(process.env.PORT || 3000, function () {
    console.log('App listening on ' + server.address().port);
});

The above code worked fine, as when creating ioServer, no specific port is required. However, after I switched to Express 4 and started using Heroku's WebSocket service, I had to specify a port like this:

var WebSocketServer = require('ws').Server,
    port = 5000,
    server = http.createServer(app);
    server.listen(port);

var wss = new WebSocketServer({server: server});

wss.on('connection', callback);

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

This new set-up never works because when I run the app on Heroku, I get an error complaining that the same port can't be used twice:

Error: listen EADDRINUSE :::40854

The set-up logic is essentially the same except for explicitly assigning a port in Express 4, so why did my code work with Express 3 but not Express 4? How should I fix this?

Upvotes: 0

Views: 714

Answers (1)

jfriend00
jfriend00

Reputation: 707148

In your second code block, you can't call .listen() on both your server and on your app object. In this particular case (the way you've structured your code), you only want to call it on the server object, not on app.

This is the code from Heroku's dev page on this topic:

var WebSocketServer = require("ws").Server
var http = require("http")
var express = require("express")
var app = express()
var port = process.env.PORT || 5000

app.use(express.static(__dirname + "/"))

var server = http.createServer(app)
server.listen(port)

console.log("http server listening on %d", port)

var wss = new WebSocketServer({server: server})
console.log("websocket server created")

Also, your first code block is not running on two ports. As is usually the design for webSockets, a single port is used for both your web requests and your webSocket connections. The web server itself splits out the two types of connections based on the initial connection.

Upvotes: 2

Related Questions