外部 WebSocket 服务器上的 Apollo-Server GraphQL 订阅

Posted

技术标签:

【中文标题】外部 WebSocket 服务器上的 Apollo-Server GraphQL 订阅【英文标题】:Apollo-Server GraphQL Subscription on External WebSocket Server 【发布时间】:2020-12-03 18:25:07 【问题描述】:

所以我有一个问题,因为我很难理解它。目前我有一个使用 Apollo-Server 创建并使用本地 sqlite 数据库持久化的 GraphQL API 服务器。我的查询和突变工作正常。

我还有一个外部 WebSocket 服务器,它不断地在ws://localhost:8000/websocket 处生成消息(与我的 GraphQL/数据库模式匹配)。是否可以让我的 GraphQL Server 订阅该 websocket 地址并不断解析这些消息并使用适当的突变插入后端数据库?

然后我会有一个 Vue 前端,它会不断显示结果(也许通过 Vue Apollo Clients WS 订阅?)

【问题讨论】:

我可以从技术上解析来自 WebSocket 的恒定数据流,并不断调用将插入数据库的突变。然后我猜想为 Apollo 服务器和 Apollo 客户端添加一个 PubSub,但最终会成为一个额外的 WebSocket 服务器。带有传入数据流的原始服务器和另一个用于订阅以监视更改的 WebSocket 服务器?一定有更好的方法来实现我的想象? 【参考方案1】:

让我的 GraphQL 服务器订阅该 websocket 地址并不断解析这些消息

通常不会,反之亦然 - 您可以让 ws 服务器调用 graphql 服务器来进行突变。也就是说,如果您想将 WS 用作所有内容(查询、突变和订阅)的主要传输层。

但通常架构将查询和突变分开,因为它们与更有状态的订阅(持久连接)更加无状态和关键

client -> queries & mutations -> graphql server --> redis pubsub -+
                                                                  |
client <--> subscriptions <-- graphql subscription server <-------+

(在不需要高负载的简单情况下,可以将两个服务器结合起来使用内存中的 pubsub)

但是,如果你非常想,你可以编写自定义代码来连接 graphql 服务器 -> 在后台监听 ws 服务器。例如见https://github.com/enisdenjo/graphql-ws#node-client 如果您有一些用户上下文,则可能会出现问题。您需要在所有用户发生更改的情况下进行自定义连接。或者为每个用户建立一个专用连接

【讨论】:

谢谢。 Apollo 文档让这有点令人困惑。他们给出了一个内存示例,然后链接到 graphql-ws。我无法弄清楚这一切是如何联系在一起的。我认为正如你所说,websocket 与 GQL 服务器通信是有意义的。【参考方案2】:

是的,这很容易完成,只需编写一个服务工作者或工作线程来不断检查新消息 可以在node js中使用worker_threads来完成

如果您需要实时实施 确保您的工作线程启动一个套接字连接并不断连接到您发布消息的端口

你可以使用 socket.io 库来做到这一点

【讨论】:

以上是关于外部 WebSocket 服务器上的 Apollo-Server GraphQL 订阅的主要内容,如果未能解决你的问题,请参考以下文章

Apollo 2.x 客户端和服务器设置:WebSocket 握手期间出错?

与 apollo-server 的 Websocket 连接为 connectionParams 返回乱码

使用 Apollo Express、Nginx 和 docker-compose 保护 websocket

如何在 react-apollo 中根据上下文使用两个不同的 websocket url?

如何在 apollo 客户端中检测订阅(websocket)的断开和重新连接

如何使用另一种编程语言连接到 apollo graphql-websocket?