远程iOS客户端成功连接到我,发送订阅命令(它工作正常),但在"取消订阅"命令我得到下一个错误:
Unsubscribing from channel: {"channel":"Assessor::StationChannel", "station_id": 1} Could not execute command from {"command"=>"unsubscribe", "identifier"=>"{\"channel\":\"Assessor::StationChannel\", \"station_id\": 1}"}) [NoMethodError - undefined method `unsubscribe_from_channel' for nil:NilClass]: /app/vendor/bundle/ruby/2.2.0/gems/actioncable-5.0.0/lib/action_cable/connection/subscriptions.rb:44:in `remove_subscription' | /app/vendor/bundle/ruby/2.2.0/gems/actioncable-5.0.0/lib/action_cable/connection/subscriptions.rb:40:in `remove' | /app/vendor/bundle/ruby/2.2.0/gems/actioncable-5.0.0/lib/action_cable/connection/subscriptions.rb:16:in `execute_command' | /app/vendor/bundle/ruby/2.2.0/gems/actioncable-5.0.0/lib/action_cable/connection/base.rb:88:in `dispatch_websocket_message' | /app/vendor/bundle/ruby/2.2.0/gems/actioncable-5.0.0/lib/action_cable/server/worker.rb:58:in `block in invoke'
订阅邮件格式:
{"command": "subscribe", "identifier": "{\"channel\":\"Assessor::StationChannel\", \"station_id\": 1}"}
取消订阅邮件格式:
{"command": "unsubscribe", "identifier": "{\"channel\":\"Assessor::StationChannel\", \"station_id\": 1}"}
我无法在localhost上重现此问题,所以也许有人可以帮助我?
答案 0 :(得分:2)
我看到了类似的错误。我试图通过客户端(JS)取消订阅。我最终发现这是因为javascript to .remove(subscription)接受订阅而不是订阅标识符。
这就是我无误地工作的方式。也许它可以帮助您找出从服务器端获取错误的原因。
subscription = App.cable.subscriptions.subscriptions[0]
App.cable.subscriptions.remove(subscription);
(注意,我只是从数组中提取第一个订阅,TODO:搜索我要删除的订阅)
这是我看到的错误以及我最终如何找到源代码/答案。我从webclient控制台运行了这些:
App.cable.subscriptions.create({channel: "RoomChannel", room_id: 2})
这条线有效,我得到一个" ...正在传输订阅确认"在stdout for rails s
App.cable.subscriptions.remove({channel: "RoomChannel", room_id: 2})
那条线爆炸了,对我的孩子大吼大叫,侮辱我的妻子,看起来像是:
[NoMethodError - undefined method `unsubscribe_from_channel' for nil:NilClass]: /usr/local/lib64/ruby/gems/2.3.0/gems/actioncable-5.0.0.1/lib/action_cable/connection/subscriptions.rb:44:in `remove_subscription'
我还注意到崩溃前的下一行。
Unsubscribing from channel:
要生成的代码是:logger.info"取消订阅频道:#{data [' identifier']}"。这意味着它没有找到数据['标识符']。所以我开始调试,我看到actioncable中base.rb的第88行只获得{"命令":"取消订阅"}而不是{"命令" :"取消订阅","标识符":" (这里有频道名称)}
带我到action_cable.js。 (我本来是从这里开始的,但我讨厌JS。)这是我的问题:功能(订阅)。我发送的是标识符,而不是订阅对象。
Subscriptions.prototype.remove = function(subscription) {
this.forget(subscription);
if (!this.findAll(subscription.identifier).length) {
this.sendCommand(subscription, "unsubscribe");
}
return subscription;
};
答案 1 :(得分:1)
ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\ -f1
返回一个订阅对象,您必须将其传递到App.cable.subscriptions.create({channel: "RoomChannel", room_id: 2})
函数
remove
之后
var subscription = App.cable.subscriptions.create({channel: "RoomChannel", room_id: 2});
答案 2 :(得分:0)
App["identifier"].disconnected() #e.g App["chat_4"].disconnect()
=> YourChannel stopped streaming from chat_4 #rails terminal
以上是停止流式传输的行,下面是您订阅频道的方式
App['chat' + id] = App.cable.subscriptions.create({channel:
'YourChannel', chat_id: id}, {
disconnected: function () {
App.cable.subscriptions.remove(this)
},
)}
答案 3 :(得分:0)
我知道这是一个老问题,但是我也遇到了同样的问题。上面的答案都不对我有用,实际上,至少在Rails 5.0.1中,它们是不正确的。好的,这是一个前端问题,但这就是为什么无论您叫App.yourChannelName.unsubscribe()
还是App.yourChannelName.remove(App.yourChannelName)
例如。如果您有类似的内容(示例代码在coffeescript中,请忽略缺少vars和Vanilla JS中的其他内容):
App.yourChannel = App.cable.subscriptions.create({channel: 'YourChannel', id: id})
...
// do stuff, execute callbacks, whatnot
...
// try to execute unsubscribe
App.yourChannel.unsubscribe()
.unsubscribe()
是订阅原型上的一种方法,仅执行return this.consumer.subscriptions.remove(this)
this.consumer.subscriptions
返回您的订阅实例,在上面的示例中,它将是App.yourChannel
,并使用Subscription实例调用.remove
方法-即。与App.yourChannel
因此App.yourChannel.unsubscribe()
与调用App.cable.subscriptions.remove(App.yourChannel)
相同(或您选择在其中存储Subscription实例的任何变量。
我还看到了与OP相同的错误,除了在我的情况下,这是由于两次调用App.yourChannel.unsubscribe()
引起的-这是我在通过通道接收到特定数据后立即被第一次调用,并且第二次是由于在重新预订App.yourChannel
之前在特定情况下运行了自定义清除。
因此,如果您看到类似的错误,建议您查看服务器日志。 您可能会看到类似的
Registered connection (some-id) <-- initial subscription
YourChannel is transmitting the subscription confirmation
...
// other stuff while user is subscribed to the channel
...
Unsubscribing from channel: {"channel":"YourChannel","id":"some-id"} <-- initial unsubscribe call
YourChannel stopped streaming from your_channel_some-id
// some other requests potentially, perhaps some DB queries
...
// there are no requests to subscribe to the channel with the some-id, eg. you won't see this
// Registered connection (some-id)
// YourChannel is transmitting the subscription confirmation
Unsubscribing from channel: {"channel":"YourChannel","id":"some-id"} <-- duplicated unsubscribe call
Could not execute command from {"command"=>"unsubscribe", "identifier"=>"{\"channel\":\"YourChannel\",\"id\":\"some-id\"}"}) [NoMethodError - undefined method `unsubscribe_from_channel' for nil:NilClass]:
基本上,用户先进行订阅,取消订阅,然后尝试再次取消订阅(即使他们不再订阅该频道了)