【问题标题】:ruby-graphql and/or actioncable dumping "core" on subscriptionruby-graphql 和/或 actioncable 转储“核心”订阅
【发布时间】:2021-06-26 20:54:52
【问题描述】:

这里远射,但想知道是否有人可以解释为什么从 react (17.1) 到 Rails (6.1.1) 和 graphql (1.12) API 订阅 @apollo/client (3.3.11) 会导致 rails to,我只能形容为“转储核心”(对不起,我是一个老家伙)。

外部症状是当客户端连接时,我得到页面和页面的日志以:

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 控制台进行调试吗?

【问题讨论】:

    标签: ruby-on-rails graphql apollo-client react-apollo


    【解决方案1】:

    好的,回答我自己的问题,这是按照 graphql 订阅 rails 的顶级分步操作的结果,该步骤将保持无名。建议设置频道如下:

    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
        )
    

    “小心你在网上读到的东西。”——苏格拉底

    【讨论】:

    • 旁注:它转储的“核心”是上下文对象。
    猜你喜欢
    • 2019-05-23
    • 2019-03-19
    • 2017-03-28
    • 2019-03-22
    • 1970-01-01
    • 2018-08-06
    • 2017-09-01
    • 2017-09-19
    • 2019-12-02
    相关资源
    最近更新 更多