我正在构建我的应用程序:
前端:ReactJS/Javascript native 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 Gateway Websocket API ----> EC2 实例中的后端
我已经阅读了该文档,但我仍然对从哪里开始感到困惑。我应该如何配置 $connect
、$disconnect
、$default
路由?
它们与我当前在 EC2 中运行的 websocket 客户端和 Nodejs 服务器有何关系?
我应该如何更改代码以将其与 AWS API Gateway Websocket API 集成?
我提供的 Websocket URL 确实是正确的。
即使读完文档后,我仍然对从哪里开始解决这个问题感到困惑。
最佳答案
连接 Websocket 时没有响应的原因是您的后端 Express 应用中没有设置 HTTP 端点。
当您连接到 AWS API Gateway WebSocket API 时,WebSocket API 会执行 $connect 集成设置的操作。在当前配置中,您已在目标 URL 上设置 VPC 链接与 HTTP 方法 Any 的集成。因此,为了调用您的后端端点,您需要创建一个 HTTP 端点并将端点地址设置为“端点 URL”。
例如,假设您设置了以下路由。
app.get('/connect', function(req, res) {
res.send('success');
});
如果您将“端点 URL”设置为“
简而言之,您不需要在后端运行 websocket 服务器,因为 WebSocket API 会处理它。通过路由集成,您只需设置如何根据通过 WebSocket 发送的消息调用不同的方法(由后端 Node.js 服务器的 HTTP 端点提供)。
作为旁注,我建议使用以下选项之一。
- 如果您需要运行自己的后端,请不要使用 AWS API Gateway WebSocket API,因为没有必要。您可以改用 AWS ALB。
- 如果您不必运行自己的后端并且功能不太复杂,请使用 AWS Lambda 与 WebSocket API 集成并采用无服务器实时功能。 -- 编辑(根据评论提出另一个建议) --
- 如果您需要使用 API Gateway,您可以在 Node.js 后端设置 HTTP 端点,并将其集成到 WebSocket API $connect 集成中。然后,您集成的 HTTP 端点将在连接时被调用。
关于node.js - AWS API网关WebSocket API : how to use it with React/NodeJS/native WebSocket?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70679996/