ruby-on-rails - ruby-graphql 和/或 actioncable 转储“核心”订阅
问题描述
在这里远射,但想知道是否有人可以解释为什么从 react (17.1) 到 Rails (6.1.1) 和 graphql (1.12) API 订阅 @apollo/client (3.3.11) 会导致 Rails 发生什么我只能形容为“转储核心”(对不起,我是一个老家伙)。
外部症状是,当客户端连接时,我会得到以以下开头的页面和日志页面:
Started GET "/cable/" [WebSocket] for 172.27.0.1 at 2021-03-30 19:30:45 +0000
api_1 | Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
api_1 | GraphqlChannel is transmitting the subscription confirmation
api_1 | GraphqlChannel is transmitting the subscription confirmation
api_1 | GraphqlChannel#execute({"query"=>"subscription {\n commentAdded {\n id\n title\n __typename\n }\n}\n", "variables"=>{}})
api_1 | GraphqlChannel#execute({"query"=>"subscription {\n commentAdded {\n id\n title\n __typename\n }\n}\n", "variables"=>{}})
api_1 | Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"GraphqlChannel\",\"channelId\":\"1788483aa6e\"}", "data"=>"{\"query\":\"subscription {\\n commentAdded {\\n id\\n title\\n __typename\\n }\\n}\\n\",\"variables\":{},\"action\":\"execute\"}"})
[NoMethodError - undefined method `unpack' for {:query=>"subscription {\n commentAdded {\n id\n title\n __typename\n }\n}\n", :context=>{:channel=>#<GraphqlChannel:0x000055b35c0503b0 @connection=#<ApplicationCable::Connection:0x000055b35c1b1308 @coder=ActiveSupport::JSON,
@env={"rack.version"=>[1, 6], "rack.errors"=>#<IO:<STDERR>>, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false,
"SCRIPT_NAME"=>"/cable", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"puma 5.2.2 Fettisdagsbulle", "GATEWAY_INTERFACE"=>"CGI/1.2", "REQUEST_METHOD"=>"GET", "REQUEST_PATH"=>"/cable",
"REQUEST_URI"=>"/cable", "HTTP_VERSION"=>"HTTP/1.1", "HTTP_HOST"=>"localhost:3001"...
然后继续列出与我的计算机、文件、应用程序的状态有关的任何事情,重复……很多。
因此,正常的查询和突变工作正常。订阅在 graphiql 中是可见的,事实上,鉴于我看到的事实:
[ActionCable] Broadcasting to graphql-event::commentAdded:: "{\"__gid__\":\"Z2lkOi8va29hbGEtYXBpL0NvbW1lbnQvZjQzNWQyOWUtODMxOC00YWY0LTg5ODktZDJiZDhkOTljYmQ4\"}"
在我的 Rails 日志中,我认为大部分工作都在 Rails 内部进行。(例如,如果我更改订阅名称,则会出错。电缆连接似乎在某种程度上已经建立,因为我在 Chrome 开发工具中看到了 ping。)
但是,更新永远不会发送到客户端。
gql 看起来像:
const COMMENTS_SUBSCRIPTION = gql`
subscription {
commentAdded {
id
title
}
}
`;
像这样设置 Apollo 客户端(相关部分,如可用的几个文档中所示):
const link = ApolloLink.split(
hasSubscriptionOperation,
new ActionCableLink({cable}) as any,
stdLink
);
并且订阅在 Rails 中设置,如下所示:
module Types
class SubscriptionType < GraphQL::Schema::Object
field :comment_added, type: Types::CommentType,
null: false,
description: "Subscription to push new comments as added"
def comment_added
object
end
end
end
一旦发生了 Big Barf,它就会接受突变,添加东西,记录它正在广播,然后……什么都没有。客户端上没有任何迹象。这让我相信订阅实际上并没有注册。
关于寻找什么的任何指示?我应该能够以某种方式从 Rails 控制台进行调试吗?
解决方案
好的,为了回答我自己的问题,这是按照最重要的一步一步列出的graphql 订阅栏的结果,这些栏将保持无名。它建议按如下方式设置频道:
result = GraphqlRailsApiSchema.execute({
query: query,
context: context,
variables: variables,
operation_name: operation_name
})
现在我知道了。不要那样做。注意整个参数是一个哈希。深入研究 graphql gem 源代码,我看到它需要一个查询字符串和**kwargs
. 简而言之,它采用该哈希并将其视为查询字符串参数(因此,尝试使用unpack
它)。
相反,您可以这样做:
result = GraphqlRailsApiSchema.execute(
query,
context: context,
variables: variables,
operation_name: operation_name
)
“小心你在网上看到的内容。” ——苏格拉底
推荐阅读
- scala - 如何在 Spark 中创建 Schema 文件
- .htaccess - .htaccess - 删除一个变量和 301 重定向,但不影响其他变量?
- python - Numpy:关于 numpy.ufunc.reduceat 的第二条规则?
- routing - Istio / Kuberentes 中的用户特定路由
- c++ - 具有伪继承设计 C++ 的模板
- python - 如何在不更改字节的情况下将字符串转换为浮点数?
- angular - 表单的复选标记验证
- android - 如何查看数据库中的数据 (REST)
- c# - FTD2xx_NET DLL 是托管代码还是非托管代码?
- solr - 使用 bin/post 和托管模式突出显示 Solr 搜索结果