我的应用程序有一个快速服务器侦听一个端口(process.env.PORT),我还想要一个使用另一个端口的Web套接字。我过去常常使用Express 3进行此设置:
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);
});
上面的代码运行正常,因为在创建ioServer时,不需要特定的端口。但是,在我切换到Express 4并开始使用Heroku的WebSocket服务之后,我不得不指定一个这样的端口:
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.'));
});
这个新的设置永远不会起作用,因为当我在Heroku上运行应用程序时,我收到一个错误,抱怨同一个端口不能使用两次:
Error: listen EADDRINUSE :::40854
除了在Express 4中明确指定一个端口外,设置逻辑基本相同,那么为什么我的代码适用于Express 3但不适用于Express 4?我该如何解决这个问题?
答案 0 :(得分:2)
在第二个代码块中,您无法在服务器和应用对象上调用.listen()
。在这种特殊情况下(您构建代码的方式),您只想在server
对象上调用它,而不是在app
上调用它。
这是Heroku's dev page关于此主题的代码:
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")
此外,您的第一个代码块未在两个端口上运行。通常是webSockets的设计,单个端口用于Web请求和webSocket连接。 Web服务器本身根据初始连接拆分两种类型的连接。