问题描述
为了做好准备,我有一个 Apollo GraphQL 服务器,它使用 inversify 进行 IoC/DI。我拥有的每个 Apollo 数据源都标有 @injectable(),每个解析器、util 等都是如此。
Inversify 和 Apollo 似乎在每个用例中都相处融洽,除了 ApolloServer 提供的 onConnect 和 ondisconnect 钩子。这里的用例是,我希望能够在 onConnect 挂钩中通过位于数据库前面的 DataSource 将连接设备设置为在线(设备 ID 存在于请求标头中),我在其中存储设备的连接信息,然后再次通过相同的数据源在 ondisconnect 挂钩中脱机。这是我的代码的样子:
import container from "./inversify.config";
const handleDeviceIsConnected = async (context: ConnectionContext,isConnected: boolean): Promise<void> => {
const userAgent: string | undefined = context.request.headers["user-agent"];
if (!userAgent) {
console.log("No user agent present. Assuming connection from a human");
return;
}
const deviceDataSource: DataSources.DeviceDataSource = container.resolve(DataSources.DeviceDataSource);
const deviceItem: DataSources.DeviceItem = await deviceDataSource.getDeviceItem(userAgent);
if (!deviceItem) {
console.log(`No device with ID ${userAgent} found. Assuming connection is from a human`);
return;
}
await deviceDataSource.updateConnectionStatus(userAgent,{
isConnected
});
console.log(`${userAgent} has been set to ${isConnected ? "online" : "offline"}`);
};
const bootstrap = () => {
...
const apollo = new ApolloServer({
...
subscriptions: {
onConnect: async (connectionParams: Object,websocket: WebSocket,context: ConnectionContext) => {
await handleDeviceIsConnected(context,true);
},ondisconnect: async (connectionParams: Object,false);
},}
});
...
}
bootstrap().catch((error) => console.log(error));
我看到的行为是有时服务器会进入此代码完美运行的状态。其他时候,我看到服务器抛出错误 Cannot read property 'getItem' of undefined
。 这是指 DeviceDataSource 中的代码行:
public async getDeviceItem(deviceid: string): Promise<DeviceItem> {
return await this.getItem(deviceid);
}
getItem
调用是对 DynamoDB 的,但这无关紧要(DeviceDataSource 正在扩展 https://github.com/cmwhited/apollo-datasource-dynamodb/blob/main/src/DynamoDBDataSource.ts)。使用此数据源的解析器将完全正常工作 - 只是 onConnect 和 ondisconnect 挂钩似乎在使用数据源时遇到问题...有时。我尝试在数据源的构造函数中将 this
绑定到 getDeviceItem
,我尝试将其修改为箭头函数,但都没有运气。在我看来,inversify 正在从容器提供数据源,但我无法弄清楚这种非确定性行为的来源。有什么想法吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)