node.js 服务器在 elastic beanstalk ALB 上有 websockets 没有 socket.io
node.js server with websockets on elastic beanstalk ALB without socket.io
我正在尝试让 node.js 服务器(使用 express)使用应用程序负载均衡器(ALB)在弹性 beanstalk(EB)中使用 websockets,但不使用 socket.io(因为 peerjs- server 是我要获取的服务器 运行 而不是用 socket.io).
写的
我看过几篇文章建议您必须使用 socket.io(或另一个不依赖于 websockets 的库),但亚马逊说 ALB 直接支持 websockets。
我的服务器既是 create-react-app 服务器又是 peerjs-server。对于 Web UI 和 peerjs ws 连接,它在端口 9000 上的开发中运行良好。
我已经尝试了我发现的所有不同方法,但我还没有得到它的工作,我什至看到了一些暗示它无法完成的东西,但看起来快到了。有没有人让这个工作,如果是的话,怎么做?
好的,我让它工作了。以下是我为使一切在端口 9000 上正常工作所做的工作。
在 EB 中,创建应用程序,然后开始创建环境。
在环境配置中,进入 Software 部分并告诉它您将使用 npm run prod
来启动您的服务器。:
现在,进入 负载均衡器 部分,如下图所示:
- 在端口 9000 上添加监听器
- 在端口 9000 上创建一个进程并启用粘性(我调用了我的 peerjsServer)
- 为您要用于访问服务器的每个 URL 路径添加规则,并将每个规则分配给您创建的进程 (peerjsServer)。还将默认值指向该进程,以便 80 上的健康检查成功通过您的服务器
您可能需要跳转到 AWS UI 中的 EC2 仪表板,以确保必要的安全组 在那里定义。我想我在 上创建了前两个,后两个是默认创建的,但我不记得了。无论如何,他们需要为入站和出站打开端口 9000(默认情况下始终存在端口 80):
返回 EB 配置,转到 实例 部分并确保您的实例已分配给它的安全组:
我 运行 react-scripts build
使 /build
目录包含服务器的生产版本 UI(这是我创建的 create-react-apps 东西这里不涉及)。
在我的代码中,我使用 server.js
启动服务器,它使服务器成为 运行 peerjs-server ws 服务器和 http 服务器。
const express = require("express");
const bodyParser = require("body-parser");
const path = require('path');
const passport = require("passport");
const users = require("./routes/api/users");
const games = require("./routes/api/games");
const Game = require("./src/models/Game");
const WebSocket = require('ws');
const ExpressPeerServer = require('peerjs-server').ExpressPeerServer;
const app = express();
const url = require('url');
const port = process.env.PEERSERVERPORT || 9000;
// WebSocket for making db updates to client.
const wsserver = require('./wsserver').wsserver
// Server that gets all requests: lobby UI, peerserver, db websocket
const server = require('http').createServer(app);
wsserver.on('connection', function connection(ws) {
ws.on('message', msg => {
ws.send(msg)
})
ws.on('close', () => {
console.log('WebSocket was closed')
})
});
server.on('upgrade', function upgrade(request, socket, head) {
const pathname = url.parse(request.url).pathname;
if (pathname === '/ws') {
wsserver.handleUpgrade(request, socket, head, function done(ws) {
wsserver.emit('connection', ws, request);
});
}
});
// Bodyparser middleware
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
// Passport middleware
app.use(passport.initialize());
// Passport config
require("./config/passport")(passport);
// Routes -- the /api/* path is defined in the EB load balancer
app.use("/api/users", users);
app.use("/api/games", games);
// This is the create-react-apps /build directory of UI code
app.use(express.static(path.join(__dirname, 'build')));
app.get('/login', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
// These are the paths that are defined in the EB load balancer
app.get('/logout', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.get('/register', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.get('/dashboard', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
// Peer server for making WebRTC connections between game clients.
const options = {
debug: true
}
const peerserver = ExpressPeerServer(server, options);
app.use('/peerserver', peerserver);
app.use(express.static(path.join(__dirname, 'src')));
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'src', 'index.html'));
});
peerserver.on('disconnect', (client) => {
console.log('Delete the game if the host client disconnects');
Game.deleteMany({ hostPeerId: client })
.then(() => {
wsserver.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send("refreshGames");
}
})
})
.catch(err => console.log(err));
});
server.listen( port, () => console.log(`Server is up and running on port ${port} !`))
然后在我的package.json
中,我将prod的脚本设置为运行上面的server.js来启动服务器,npm 运行 prod我把在前面的 Software 部分中,调用它来使服务器运行:
...
"scripts": {
"start": "set PORT=8081&& react-scripts start",
"prod": "node server.js",
...
完成所有这些之后,我现在有一个使用 ALB 并处理端口 9000 上的 websocket (ws) 和 UI (http) 流量的 运行ning EB 服务器。
我正在尝试让 node.js 服务器(使用 express)使用应用程序负载均衡器(ALB)在弹性 beanstalk(EB)中使用 websockets,但不使用 socket.io(因为 peerjs- server 是我要获取的服务器 运行 而不是用 socket.io).
写的我看过几篇文章建议您必须使用 socket.io(或另一个不依赖于 websockets 的库),但亚马逊说 ALB 直接支持 websockets。
我的服务器既是 create-react-app 服务器又是 peerjs-server。对于 Web UI 和 peerjs ws 连接,它在端口 9000 上的开发中运行良好。
我已经尝试了我发现的所有不同方法,但我还没有得到它的工作,我什至看到了一些暗示它无法完成的东西,但看起来快到了。有没有人让这个工作,如果是的话,怎么做?
好的,我让它工作了。以下是我为使一切在端口 9000 上正常工作所做的工作。
在 EB 中,创建应用程序,然后开始创建环境。
在环境配置中,进入 Software 部分并告诉它您将使用 npm run prod
来启动您的服务器。:
现在,进入 负载均衡器 部分,如下图所示:
- 在端口 9000 上添加监听器
- 在端口 9000 上创建一个进程并启用粘性(我调用了我的 peerjsServer)
- 为您要用于访问服务器的每个 URL 路径添加规则,并将每个规则分配给您创建的进程 (peerjsServer)。还将默认值指向该进程,以便 80 上的健康检查成功通过您的服务器
您可能需要跳转到 AWS UI 中的 EC2 仪表板,以确保必要的安全组 在那里定义。我想我在 上创建了前两个,后两个是默认创建的,但我不记得了。无论如何,他们需要为入站和出站打开端口 9000(默认情况下始终存在端口 80):
返回 EB 配置,转到 实例 部分并确保您的实例已分配给它的安全组:
我 运行 react-scripts build
使 /build
目录包含服务器的生产版本 UI(这是我创建的 create-react-apps 东西这里不涉及)。
在我的代码中,我使用 server.js
启动服务器,它使服务器成为 运行 peerjs-server ws 服务器和 http 服务器。
const express = require("express");
const bodyParser = require("body-parser");
const path = require('path');
const passport = require("passport");
const users = require("./routes/api/users");
const games = require("./routes/api/games");
const Game = require("./src/models/Game");
const WebSocket = require('ws');
const ExpressPeerServer = require('peerjs-server').ExpressPeerServer;
const app = express();
const url = require('url');
const port = process.env.PEERSERVERPORT || 9000;
// WebSocket for making db updates to client.
const wsserver = require('./wsserver').wsserver
// Server that gets all requests: lobby UI, peerserver, db websocket
const server = require('http').createServer(app);
wsserver.on('connection', function connection(ws) {
ws.on('message', msg => {
ws.send(msg)
})
ws.on('close', () => {
console.log('WebSocket was closed')
})
});
server.on('upgrade', function upgrade(request, socket, head) {
const pathname = url.parse(request.url).pathname;
if (pathname === '/ws') {
wsserver.handleUpgrade(request, socket, head, function done(ws) {
wsserver.emit('connection', ws, request);
});
}
});
// Bodyparser middleware
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
// Passport middleware
app.use(passport.initialize());
// Passport config
require("./config/passport")(passport);
// Routes -- the /api/* path is defined in the EB load balancer
app.use("/api/users", users);
app.use("/api/games", games);
// This is the create-react-apps /build directory of UI code
app.use(express.static(path.join(__dirname, 'build')));
app.get('/login', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
// These are the paths that are defined in the EB load balancer
app.get('/logout', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.get('/register', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.get('/dashboard', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
// Peer server for making WebRTC connections between game clients.
const options = {
debug: true
}
const peerserver = ExpressPeerServer(server, options);
app.use('/peerserver', peerserver);
app.use(express.static(path.join(__dirname, 'src')));
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'src', 'index.html'));
});
peerserver.on('disconnect', (client) => {
console.log('Delete the game if the host client disconnects');
Game.deleteMany({ hostPeerId: client })
.then(() => {
wsserver.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send("refreshGames");
}
})
})
.catch(err => console.log(err));
});
server.listen( port, () => console.log(`Server is up and running on port ${port} !`))
然后在我的package.json
中,我将prod的脚本设置为运行上面的server.js来启动服务器,npm 运行 prod我把在前面的 Software 部分中,调用它来使服务器运行:
...
"scripts": {
"start": "set PORT=8081&& react-scripts start",
"prod": "node server.js",
...
完成所有这些之后,我现在有一个使用 ALB 并处理端口 9000 上的 websocket (ws) 和 UI (http) 流量的 运行ning EB 服务器。