无法使用 graphql-ruby 订阅进行简单广播
Can't get a simple broadcast with graphql-ruby subscriptions working
我有一个准系统设置,用于通过 Action Cable 使用 graphql-ruby 进行更新广播。
- 客户端收到订阅时的初始负载。
- 客户端没有收到任何更新,订阅类型的
update
方法没有被调用。后端没有错误。触发器调用似乎被默默地忽略了。这就是我要解决的问题/正确理解它应该如何工作。
我正在查看的文档:
- https://graphql-ruby.org/subscriptions/subscription_classes.html
- https://graphql-ruby.org/subscriptions/triggers
订阅类型:
module Types
class SubscriptionType < Types::BaseObject
field :server_info, subscription: Subscriptions::ServerInfoSubscription, null: false
end
end
module Subscriptions
class ServerInfoSubscription < Subscriptions::BaseSubscription
field :date_time, GraphQL::Types::ISO8601DateTime, null: false
def subscribe
{ date_time: DateTime.now }
end
def update
puts 'UPDATE CALLED' # Nope, it's not being called
super
end
end
end
我尝试触发更新的方式:
MySchema.subscriptions.trigger(:server_info, {}, { date_time: DateTime.now })
架构定义为:
class MySchema < GraphQL::Schema
use GraphQL::Execution::Interpreter
use GraphQL::Subscriptions::ActionCableSubscriptions
subscription(Types::SubscriptionType)
end
我在config/cable.yml:
中使用开发环境的redis适配器
development:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: test-app_development
我错过了什么?有任何故障排除提示吗?
更新:
一些诊断:
Rails 初始(和成功)订阅调用的日志:
GraphqlChannel#execute({"query"=>"subscription ServerInfoSubscription {\n serverInfo {\n dateTime\n __typename\n }\n}\n", "variables"=>{}, "operationName"=>"ServerInfoSubscription"})
GraphqlChannel transmitting {"data"=>{"serverInfo"=>{"dateTime"=>"2020-10-08T10:47:08-04:00", "__typename"=>"ServerInfoSubscriptionPayload"}}}
GraphqlChannel is streaming from graphql-subscription:9087735b-9b99-4d66-8b77-ff3622c8efe7
GraphqlChannel is streaming from graphql-event::dateTime:
Started POST "/graphql" for 192.168.64.210 at 2020-10-08 10:47:08 -0400
正在检查活动的 Redis PubSub 频道:
$ redis-cli -h 192.168.64.210 -p 6379 pubsub channels
1) "test-app_development:graphql-subscription:9087735b-9b99-4d66-8b77-ff3622c8efe7"
2) "test-app_development:graphql-event::dateTime:"
3) "_action_cable_internal"
运行 Rails 控制台中触发器调用的结果:
irb(main):001:0> MySchema.subscriptions.trigger(:server_info, {}, { date_time: DateTime.now })
[ActionCable] Broadcasting to graphql-event::serverInfo:: "{\"date_time\":\"2020-10-08T10:54:18-04:00\",\"__sym_keys__\":[\"date_time\"]}"
显而易见的是,Redis PubSub 通道称为“graphql-event::dateTime:”,而触发器调用通过不存在的“graphql-event::serverInfo:”通道广播。我不明白为什么实际的 Redis 通道被称为“graphql-event::dateTime”,而订阅查询是顶级“ServerInfo”类型。
我终于让它工作了,但无法确定为什么它不起作用:
MySchema.subscriptions.trigger(:server_info, {}, { date_time: DateTime.now })
请注意,我传递了一个空散列 ({}
) 作为第二个参数。
我让它工作的方法是在我的查询中添加一个 argument
并使用匹配参数(与原始订阅查询匹配)。像这样:
module Subscriptions
class EventReceivedSubscription < Subscriptions::BaseSubscription
argument :event_name, String, required: true
field :event_name, String, null: false
field :payload, String, null: true
end
end
MySchema.subscriptions.trigger(
:event_received,
{ event_name: 'greeting' },
{ payload: 'Hello' }
)
我现在能看到的Redis频道是:
$ redis-cli -h 192.168.64.210 -p 6379 pubsub channels
1) "test-app_development:graphql-event::eventReceived:eventName:greeting"
这是因为您试图覆盖的方法需要参数,如果您查看 GraphQL::Schema::Subscription
def subscribe( attrs = {})
...
end
def update( attrs = {} )
...
end
您可以安全地删除 :argument
并使用参数定义 您的 更新方法,这将解决问题。
def update( _attrs = {} )
# your logic here
end
我有一个准系统设置,用于通过 Action Cable 使用 graphql-ruby 进行更新广播。
- 客户端收到订阅时的初始负载。
- 客户端没有收到任何更新,订阅类型的
update
方法没有被调用。后端没有错误。触发器调用似乎被默默地忽略了。这就是我要解决的问题/正确理解它应该如何工作。
我正在查看的文档:
- https://graphql-ruby.org/subscriptions/subscription_classes.html
- https://graphql-ruby.org/subscriptions/triggers
订阅类型:
module Types
class SubscriptionType < Types::BaseObject
field :server_info, subscription: Subscriptions::ServerInfoSubscription, null: false
end
end
module Subscriptions
class ServerInfoSubscription < Subscriptions::BaseSubscription
field :date_time, GraphQL::Types::ISO8601DateTime, null: false
def subscribe
{ date_time: DateTime.now }
end
def update
puts 'UPDATE CALLED' # Nope, it's not being called
super
end
end
end
我尝试触发更新的方式:
MySchema.subscriptions.trigger(:server_info, {}, { date_time: DateTime.now })
架构定义为:
class MySchema < GraphQL::Schema
use GraphQL::Execution::Interpreter
use GraphQL::Subscriptions::ActionCableSubscriptions
subscription(Types::SubscriptionType)
end
我在config/cable.yml:
中使用开发环境的redis适配器development:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: test-app_development
我错过了什么?有任何故障排除提示吗?
更新:
一些诊断:
Rails 初始(和成功)订阅调用的日志:
GraphqlChannel#execute({"query"=>"subscription ServerInfoSubscription {\n serverInfo {\n dateTime\n __typename\n }\n}\n", "variables"=>{}, "operationName"=>"ServerInfoSubscription"})
GraphqlChannel transmitting {"data"=>{"serverInfo"=>{"dateTime"=>"2020-10-08T10:47:08-04:00", "__typename"=>"ServerInfoSubscriptionPayload"}}}
GraphqlChannel is streaming from graphql-subscription:9087735b-9b99-4d66-8b77-ff3622c8efe7
GraphqlChannel is streaming from graphql-event::dateTime:
Started POST "/graphql" for 192.168.64.210 at 2020-10-08 10:47:08 -0400
正在检查活动的 Redis PubSub 频道:
$ redis-cli -h 192.168.64.210 -p 6379 pubsub channels
1) "test-app_development:graphql-subscription:9087735b-9b99-4d66-8b77-ff3622c8efe7"
2) "test-app_development:graphql-event::dateTime:"
3) "_action_cable_internal"
运行 Rails 控制台中触发器调用的结果:
irb(main):001:0> MySchema.subscriptions.trigger(:server_info, {}, { date_time: DateTime.now })
[ActionCable] Broadcasting to graphql-event::serverInfo:: "{\"date_time\":\"2020-10-08T10:54:18-04:00\",\"__sym_keys__\":[\"date_time\"]}"
显而易见的是,Redis PubSub 通道称为“graphql-event::dateTime:”,而触发器调用通过不存在的“graphql-event::serverInfo:”通道广播。我不明白为什么实际的 Redis 通道被称为“graphql-event::dateTime”,而订阅查询是顶级“ServerInfo”类型。
我终于让它工作了,但无法确定为什么它不起作用:
MySchema.subscriptions.trigger(:server_info, {}, { date_time: DateTime.now })
请注意,我传递了一个空散列 ({}
) 作为第二个参数。
我让它工作的方法是在我的查询中添加一个 argument
并使用匹配参数(与原始订阅查询匹配)。像这样:
module Subscriptions
class EventReceivedSubscription < Subscriptions::BaseSubscription
argument :event_name, String, required: true
field :event_name, String, null: false
field :payload, String, null: true
end
end
MySchema.subscriptions.trigger(
:event_received,
{ event_name: 'greeting' },
{ payload: 'Hello' }
)
我现在能看到的Redis频道是:
$ redis-cli -h 192.168.64.210 -p 6379 pubsub channels
1) "test-app_development:graphql-event::eventReceived:eventName:greeting"
这是因为您试图覆盖的方法需要参数,如果您查看 GraphQL::Schema::Subscription
def subscribe( attrs = {})
...
end
def update( attrs = {} )
...
end
您可以安全地删除 :argument
并使用参数定义 您的 更新方法,这将解决问题。
def update( _attrs = {} )
# your logic here
end