问题描述
我在项目中使用 express 来处理客户端的 http 请求,完成涉及数据库操作的业务逻辑,如用户认证、群组管理等;另外还使用了 socket.io 来管理 websocket 长连接,处理客户端和服务端之间的实时消息传递,如信令交互、状态同步等。
这里的 http 请求与 websocket 连接使用的都是同一个 url 前缀 https://localhost:3000,那么它们之间会不会出现冲突呢?
app.get('/', (req: Request, res: Response, next: NextFunction) => {
res.status(200).send('ok!');
});
比如说,如果我在 express 中设置了上述路径和请求处理函数,此时如果直接访问 https://localhost:3000,这个请求按道理会被 express 接收处理,因此如果 websocket 不配置特定的访问路径,那么它是否会出现连接异常?又或者 http 请求是否会出现异常?
经过验证发现似乎没有发生冲突,通过阅读 socket.io 的官方文档我找到了一些原因。
socket.io 在进行 websocket 连接的时候有一个默认的路径为/socket.io/
,也就是服务端与客户端进行 websocket 连接的实际路径为 https://localhost:3000/socket.io/ 。
我们也可以通过 path 参数来修改这个默认的路径,如图所示,我们在服务端配置 socket.io 的 path 参数为 "/my-custom-path/",那么服务端与客户端进行 websocket 连接的实际路径就变成了 https://localhost:3000/my-custom-path/ 。
此时客户端也应该将 socket.io 的 path 参数配置为相同的值,这样才能正常建立连接。注意不是直接修改连接服务端的 url,因为如果我们不修改客户端 socket.io 的 path 参数,而是将 url 改成 https://localhost:3000/my-custom-path/ 传给它,那么最终客户端发起连接的实际路径为 https://localhost:3000/my-custom-path//socket.io/ ,这样自然不可能与服务端正确建立连接。
另外,我也验证了在 express 中配置/socket.io/
这个路径的请求处理,然后通过 postman 发起请求,结果冲突果然发生了。服务端无法正确收到这个 http 请求,报错信息信息为 Transport unknow。
app.post('/socket.io/', (req, res, next) => {
res.status(200).send("post ok!");
});
app.get('/socket.io/', (req, res, next) => {
res.status(200).send("get ok!");
});
总结
因此,我们在使用 express 处理请求的过程中,注意路径不要与 socket.io 的 path 参数值重复,同理如果我们要修改 socket.io 的 path 参数也应该检查 express 中已有的路径,避免冲突的发生。