适用于 Socket.IO 的 Web PubSub 是基于 Socket.IO 库生成的。 使用 Azure 服务时,问题可能在于服务或库。
要查找问题的根源,可以通过暂时从应用程序中移除适用于 Socket.IO 的 Web PubSub 来隔离 Socket.IO 库。 如果应用程序在移除后按预期工作,则根本原因可能在于 Azure 服务。
使用本文查找服务常见问题的解决方案。 此外,还可以 在服务器端启用日志记录,以检查 Socket.IO 应用的行为(如果列出的解决方案都无济于事)。
如果怀疑 Socket.IO 库出现问题,请参阅 Socket.IO 库的文档。
服务器端
包导入不正确
可能的错误
TypeError: (intermediate value).useAzureSocketIO is not a function
根本原因
如果在项目中使用 TypeScript,则可能会看到此错误。 这是由于包导入不正确造成的。
// Bad example
import * as wpsExt from "@azure/web-pubsub-socket.io"
如果在导入后未使用或引用包,则 TypeScript 编译器的默认行为将不是发出已编译的 .js 文件中的包。
解决方案
请改用 import "@azure/web-pubsub-socket.io"。 此导入语句可强制 TypeScript 编译器在编译后的 .js 文件中包含包,即使未在源代码中的任何位置引用该包也是如此。 在 TypeScript 社区中详细了解此常见问题。
// Good example.
// It forces TypeScript to include the package in compiled .js file.
import "@azure/web-pubsub-socket.io"
客户端
路径选项不正确
可能的错误
GET <web-pubsub-endpoint>/socket.io/?EIO=4&transport=polling&t=OcmE4Ni 404 未找到
根本原因
Socket.IO 客户端是在没有正确 path 选项的情况下创建的。
// Bad example
const socket = io(endpoint)
解决方案
添加值为 /clients/socketio/hubs/eio_hub 的正确的 path 选项。
// Good example
const socket = io(endpoint, {
path: "/clients/socketio/hubs/eio_hub",
});
Socket.IO 终结点的 Web PubSub 不正确
可能的错误
GET <non-web-pubsub-endpoint>/socket.io/?EIO=4&transport=polling&t=OcmE4Ni 404 未找到
根本原因
Socket.IO 客户端是在没有适用于 Socket.IO 终结点的正确 Web PubSub 的情况下创建的。 例如:
// Bad example.
// This example uses the original Socket.IO server endpoint.
const endpoint = "socketio-server.com";
const socket = io(endpoint, {
path: "/clients/socketio/hubs/<Your hub name>",
});
在使用适用于 Socket.IO 的 Web PubSub 时,客户端会与 Azure 服务建立连接。 创建 Socket.IO 客户端时,需要使用适用于 Socket.IO 资源的 Web Pubsub 的终结点。
解决方案
允许 Socket.IO 客户端将终结点用于适用于 Socket.IO 资源的 Web PubSub。
// Good example.
const webPubSubEndpoint = "<web-pubsub-endpoint>";
const socket = io(webPubSubEndpoint, {
path: "/clients/socketio/hubs/<Your hub name>",
});
为同一包安装了多个版本
可能的错误
服务器抛出错误:
const io = await require('socket.io')(server).useAzureSocketIO(wpsOptions);
^
TypeError: require(...)(...).useAzureSocketIO is not a function
根本原因
将 socket.io 或 engine.io 包添加到依赖项字段下的 package.json,而 SDK 包 @azure/web-pubsub-socket.io 在内部指定其他版本。 例如:
"dependencies": {
"@azure/web-pubsub-socket.io": "1.0.1-beta.6",
"socket.io": "4.6.1"
},
yarn install 后,将安装两个不同的版本。 可以通过运行 npm list socket.io 进行验证。
此命令应显示两个版本的 socket.io 包:
demo@0.0.0 G:\demo
├─┬ @azure/web-pubsub-socket.io@1.0.0-beta.6
│ └── socket.io@4.7.1
└── socket.io@4.6.1
解决方案
解决方案取决于是否需要自定义版本的 socket.io 或 engine.io 包。
- 不需要自定义版本的
socket.io/engine.io包,只需删除package.json依赖项中的socket.io/engine.io即可。 例如:
"dependencies": {
"@azure/web-pubsub-socket.io": "1.0.1-beta.6",
},
socket.io/engine.io包的自定义版本是必需的,在这种情况下,package.json可以是:
"dependencies": {
"@azure/web-pubsub-socket.io": "1.0.1-beta.6",
"socket.io": "4.6.1"
},
然后,应运行 yarn install --flat。 它安装所有依赖项,但每个包只允许一个版本。 在第一次运行时,它会提示你为每个依赖于多个版本范围的包选择一个版本。
对于我们的情况,它可能会提示你选择 socket.io、engine.io、engine.io-parser 版本等。 根据 socket.io 包 和 engine.io 包的本机实现,确保版本彼此匹配。
最终版本将添加到“resolutions”字段下的“package.json”。
"resolutions": {
"package-a": "a.b.c",
"package-b": "d.e.f",
"package-c": "g.h.i"
}