node.js - 在使用 Express 服务器的同时使用 Websocket 服务器;在对我的某个路由进行 POST 请求后,我如何触发 Websocket 发送事件?
我目前正在用 TypeScript 构建一个使用 Express 和 Websockets 的后端服务器。从高层次来看,我的问题是我希望当我收到对某个路由的 POST 请求时,该路由的处理程序能够向客户端的 websocket 发送消息。我目前有三个文件:app.ts、conversationController.ts 和 server.ts。
我安排的方式是 conversationController.ts 处理我的路由的 http 和 websocket 逻辑,app.ts 使用该控制器并导出我的 express 应用,server.ts 则创建 HTTP 服务器和 Websocket 服务器。下面是我的代码,这样你可以了解正在发生的事情以及我想要做的事情。正如你会看到的,我的做法有点奇怪;我很想获得关于如何更好地结构化代码/最佳实践的反馈,但无论如何,我的代码目前是可用的。底部有更多解释。
这是 conversationController.ts 中的重要内容
import { NextFunction, Response, Request, Router, } from "express";
export class ConversationController {
public router: Router;
constructor() {
this.router = Router();
this.setupRoutes();
}
private handleMessageFromAndroid(req: Request, res: Response, next: NextFunction) {
const message = {
phoneNumber: req.body.phoneNumber,
textMessageBody: req.body.textMessageBody,
};
/* here is where I would somehow try to have access to the websocket connection that is made below in socketLogic(), so that I can tell the client of the socket that the backend has received data */
/* ideally it would look something like this: */
// ws.send("Received a POST call to the server, sending the data upstream to you, the client websocket on the front-end.");
res.sendStatus(200);
}
private setupRoutes(): void {
this.router.post("/", this.handleMessageFromAndroid.bind(this));
}
public socketLogic(wss: Server): void {
wss.on("connection", (ws) => {
console.log("Connection made to client websocket.");
/* once again, I would like to somehow have access to this "ws" object up in handleMessageFromAndroid*/
ws.on("message", (data: string) => {
const message = JSON.parse(data);
console.log("Received message from client: ", message);
ws.send("Thanks for sending a message to the server.");
});
});
}
}
这是 app.ts 中的重要内容
import * as express from "express";
import { ConversationController } from "./controllers/conversation";
export const app = express();
app.use("/texts", new ConversationController().router);
最后,这里是server.ts
import * as http from "http";
import * as WebSocket from "ws";
import { app } from "./app";
import { ConversationController } from "./controllers/conversation";
const server = app.listen(app.get("port"), () => {
console.log("App is running at http://localhost:%d in %s mode", app.get("port"), app.get("env"));
});
export const wss = new WebSocket.Server({ server });
new ConversationController().socketLogic(wss);
现在,让我说得非常清楚。这段代码确实可用。我可以在前端连接到 WebSocket 服务器;我收到连接成功的消息,并且可以通过套接字来回发送消息。然而,我的问题是,我希望能够以某种方式使打开的套接字连接(在 socketLogic() 方法中;该套接字名为“ws”)可用于conversationController.ts中的handleMessageFromAndroid方法。
起初,我在考虑将 WebSocket 服务器(在 server.ts 中创建的那个)导入到 conversationController.ts 中,并只是把它作为一个实例变量,这样整个类都可以使用该服务器,这本可以解决我所有的问题,但这让我发现了 循环依赖。基本上,当我尝试这样做时,来自 server.ts 的 WebSocket 服务器是 undefined,因为 conversationController.ts 的编译是在 server.ts 之前 进行的。
我不太确定具体如何解决这个问题,或者是否甚至可以解决。但我肯定会很感激一些帮助,因为我已经研究这个问题几天了,并且查阅了许多 Stack Overflow 问题,也在谷歌上搜索了很多。谢谢。