AWS API Gateway WebSocket API:如何将其与 React / NodeJS / 本机 WebSocket 一起使用?
AWS API Gateway WebSocket API: how to use it with React / NodeJS / native WebSocket?
我正在构建我的应用程序:
前端:ReactJS / Javascript 本机 Websocket:
在我使用 websocket 的组件中:
useEffect(() => {
const orgId = localData.get('currentOrganizationId');
const username = localData.get('username');
let socket = new WebSocket(process.env.REACT_APP_WEBSOCKET_URL); // this is the AWS WebSocket URL after I have deployed it.
// let socket = new WebSocket("ws://127.0.0.1:3001");
socket.onopen = function(e) {
console.log('socket on onopen');
const info = JSON.stringify({orgId:orgId, username: username, action: "message"});
socket.send(info);
};
socket.onmessage = function(event) {
console.log(`[message] Data received from server: ${event.data}`);
};
socket.onclose = function(event) {
if (event.wasClean) {
console.log(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
} else {
console.log(`[close] Connection died; code=${event.code}`);
}
};
socket.onerror = function(error) {
console.log(`[error] ${error.message}`);
};
}, [])
后端:NodeJS / ExpressJS / ws websocket 库:
./utils/websocket
:
import WebSocket from "ws";
import queryString from "query-string";
import { StateManager } from '../state';
import logger from '../logger';
export default async (expressServer) => {
StateManager.addToState('sockets', {});
const websocketServer = new WebSocket.Server({
noServer: true,
// path: "/websockets",
path: "/",
});
expressServer.on("upgrade", (request, socket, head) => {
logger.info(`on upgrade: ${JSON.stringify(head)}`);
websocketServer.handleUpgrade(request, socket, head, (websocket) => {
websocketServer.emit("connection", websocket, request);
});
});
websocketServer.on("connection", function connection(websocketConnection, connectionRequest) {
logger.info(`on connection`);
websocketConnection.on("message", (message) => {
const info = JSON.parse(message);
logger.info(`info: ${typeof info} ${info}`);
const sockets = StateManager.readFromState('sockets');
sockets[info.username] = websocketConnection;
});
});
return websocketServer;
};
并在 index.ts
中:
import websocket from './utils/websocket';
...other code
const app = express();
...other code
const server = app.listen(parseInt(process.env.PORT) || 3001);
websocket(server);
虽然这在本地开发环境中运行良好,但我真的很困惑如何像这样将其移动到 AWS:
前端 WebSocket 客户端 ---> AWS API 网关 Websocket API ----> EC2 实例中的后端
我是这样配置的:
我已经阅读了文档,但我仍然不知道从哪里开始。我应该如何配置 $connect
、$disconnect
、$default
路由?
它们与我当前在 EC2 中的 websocket 客户端和 nodejs 服务器有什么关系 运行?
我应该如何更改代码以将其与 AWS API Gateway Websocket API 集成?
目前根本没有回复:
不过我提供的 Websocket URL 确实是正确的。
即使阅读了文档,我仍然不知道从哪里开始解决这个问题。
连接到 websocket 时没有响应的原因是您的后端 express 应用程序中没有设置 HTTP 端点。
当您连接到 AWS API 网关 WebSocket API 时,WebSocket API 会执行您的 $connect 集成设置的操作。在您当前的配置中,您已在目标 url 上设置 VPC Link 与 HTTP Method Any 的集成。因此,要调用您的后端端点,您需要创建一个 HTTP 端点并将端点的地址设置为“Endpoint URL”。“=11=]
例如,假设您设置了以下路线。
app.get('/connect', function(req, res) {
res.send('success');
});
如果您将 'Endpoint URL' 设置为“/connect”,您将在连接到 WebSocket 时收到 'success'。
简而言之,您不需要 运行 在后端连接 websocket 服务器,因为 WebSocket API 会处理它。通过路由集成,您只需要设置如何根据通过 WebSocket 发送的消息调用不同的方法(由后端 Node.js 服务器的 HTTP 端点提供)。
作为旁注,我建议使用以下选项之一。
- 如果您需要 运行 自己的后端,请不要使用 AWS API Gateway WebSocket API 因为没有必要。您可以改用 AWS ALB。
- 如果您不需要 运行 自己的后端并且功能不是太复杂,请使用 AWS Lambda 与 WebSocket 的集成 API 并采用无服务器实时功能。
-- 编辑(基于评论的另一个建议)--
- 如果您需要使用 API 网关,您可以在 Node.js 后端设置 HTTP 端点,并将其集成到 WebSocket API $connect 集成中。然后,您集成的 HTTP 端点将在连接时被调用。
我正在构建我的应用程序:
前端:ReactJS / Javascript 本机 Websocket: 在我使用 websocket 的组件中:
useEffect(() => {
const orgId = localData.get('currentOrganizationId');
const username = localData.get('username');
let socket = new WebSocket(process.env.REACT_APP_WEBSOCKET_URL); // this is the AWS WebSocket URL after I have deployed it.
// let socket = new WebSocket("ws://127.0.0.1:3001");
socket.onopen = function(e) {
console.log('socket on onopen');
const info = JSON.stringify({orgId:orgId, username: username, action: "message"});
socket.send(info);
};
socket.onmessage = function(event) {
console.log(`[message] Data received from server: ${event.data}`);
};
socket.onclose = function(event) {
if (event.wasClean) {
console.log(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
} else {
console.log(`[close] Connection died; code=${event.code}`);
}
};
socket.onerror = function(error) {
console.log(`[error] ${error.message}`);
};
}, [])
后端:NodeJS / ExpressJS / ws websocket 库:
./utils/websocket
:
import WebSocket from "ws";
import queryString from "query-string";
import { StateManager } from '../state';
import logger from '../logger';
export default async (expressServer) => {
StateManager.addToState('sockets', {});
const websocketServer = new WebSocket.Server({
noServer: true,
// path: "/websockets",
path: "/",
});
expressServer.on("upgrade", (request, socket, head) => {
logger.info(`on upgrade: ${JSON.stringify(head)}`);
websocketServer.handleUpgrade(request, socket, head, (websocket) => {
websocketServer.emit("connection", websocket, request);
});
});
websocketServer.on("connection", function connection(websocketConnection, connectionRequest) {
logger.info(`on connection`);
websocketConnection.on("message", (message) => {
const info = JSON.parse(message);
logger.info(`info: ${typeof info} ${info}`);
const sockets = StateManager.readFromState('sockets');
sockets[info.username] = websocketConnection;
});
});
return websocketServer;
};
并在 index.ts
中:
import websocket from './utils/websocket';
...other code
const app = express();
...other code
const server = app.listen(parseInt(process.env.PORT) || 3001);
websocket(server);
虽然这在本地开发环境中运行良好,但我真的很困惑如何像这样将其移动到 AWS:
前端 WebSocket 客户端 ---> AWS API 网关 Websocket API ----> EC2 实例中的后端
我是这样配置的:
我已经阅读了文档,但我仍然不知道从哪里开始。我应该如何配置 $connect
、$disconnect
、$default
路由?
它们与我当前在 EC2 中的 websocket 客户端和 nodejs 服务器有什么关系 运行?
我应该如何更改代码以将其与 AWS API Gateway Websocket API 集成?
目前根本没有回复:
不过我提供的 Websocket URL 确实是正确的。
即使阅读了文档,我仍然不知道从哪里开始解决这个问题。
连接到 websocket 时没有响应的原因是您的后端 express 应用程序中没有设置 HTTP 端点。
当您连接到 AWS API 网关 WebSocket API 时,WebSocket API 会执行您的 $connect 集成设置的操作。在您当前的配置中,您已在目标 url 上设置 VPC Link 与 HTTP Method Any 的集成。因此,要调用您的后端端点,您需要创建一个 HTTP 端点并将端点的地址设置为“Endpoint URL”。“=11=]
例如,假设您设置了以下路线。
app.get('/connect', function(req, res) {
res.send('success');
});
如果您将 'Endpoint URL' 设置为“
简而言之,您不需要 运行 在后端连接 websocket 服务器,因为 WebSocket API 会处理它。通过路由集成,您只需要设置如何根据通过 WebSocket 发送的消息调用不同的方法(由后端 Node.js 服务器的 HTTP 端点提供)。
作为旁注,我建议使用以下选项之一。
- 如果您需要 运行 自己的后端,请不要使用 AWS API Gateway WebSocket API 因为没有必要。您可以改用 AWS ALB。
- 如果您不需要 运行 自己的后端并且功能不是太复杂,请使用 AWS Lambda 与 WebSocket 的集成 API 并采用无服务器实时功能。 -- 编辑(基于评论的另一个建议)--
- 如果您需要使用 API 网关,您可以在 Node.js 后端设置 HTTP 端点,并将其集成到 WebSocket API $connect 集成中。然后,您集成的 HTTP 端点将在连接时被调用。