我正在使用Devise和gem' devise_token_auth'在Rails 5 API Action Cable中实现聊天。
我有ChatRequestChannel
参与订阅:
stream_from "chat_request_#{chat_request_chanel_token}_channel"
我需要以某种方式可靠地检索chat_request_chanel_token
挂钩内的unsubscribed
值 - 向其他订阅者发送消息。这是我的代码:
class ChatRequestChannel < ApplicationCable::Channel
def subscribed
answerer = params["answerer"]
chat_request_chanel_token = answerer
answerer_user = User.find_by email: answerer
if answerer_user
stream_from "chat_request_#{chat_request_chanel_token}_channel"
else
# http://api.rubyonrails.org/classes/ActionCable/Channel/Base.html#class-ActionCable::Channel::Base-label-Rejecting+subscription+requests
reject
end
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
chat_request_chanel_token = "What to put here????"
message = "Client disconnected"
ActionCable.server.broadcast "chat_request_#{chat_request_chanel_token}_channel",
disconnected: message
end
end
所有客户订阅ChatRequestChannel
并使用如下命令(answerer
param因客户而异):
{"command":"subscribe","identifier":"{\"channel\":\"ChatRequestChannel\",\"answerer\":\"client1@example.com\"}"}
当客户端与Action Cable断开连接时,实际上会调用unsubscribed
挂钩。因此,我无法向unsubscribed
提供任何参数。
我建议每个客户端只有一个(每个参数)参数化订阅ChatRequestChannel
。它是存储在Action Cable中的某个位置并且可以检索吗?
答案 0 :(得分:0)
streams
<强> /var/lib/gems/2.3.0/gems/actioncable-5.0.1/lib/action_cable/channel/streams.rb 强>
def stream_from(broadcasting, callback = nil, coder: nil, &block)
broadcasting = String(broadcasting)
# Don't send the confirmation until pubsub#subscribe is successful
defer_subscription_confirmation!
# Build a stream handler by wrapping the user-provided callback with
# a decoder or defaulting to a JSON-decoding retransmitter.
handler = worker_pool_stream_handler(broadcasting, callback || block, coder: coder)
streams << [ broadcasting, handler ]
connection.server.event_loop.post do
pubsub.subscribe(broadcasting, handler, lambda do
ensure_confirmation_sent
logger.info "#{self.class.name} is streaming from #{broadcasting}"
end)
end
end
请参阅第streams << [ broadcasting, handler ]
行。
这是我的代码基于它:
module ApplicationCable
class Channel < ActionCable::Channel::Base
include ApplicationHelper
def stream_name
streams.try(:[],0).try(:[],0)
end
def token_from_stream_name
stream_name ? stream_name.gsub(channel_name,"").slice(1..-"_channel".size-1) : ""
end
end
end
stream_name
方法现在可以在unsubscribe
挂钩中使用。当客户端与服务器套接字断开连接时,将为每个客户端的订阅(到该通道)自动调用unsubscribed
挂钩。在stream_name
内呼叫unsubscribe
会返回当前正在停止的订阅的名称,允许您通知此频道的所有其他订阅者:
class ChatChannel < ApplicationCable::Channel
....
def unsubscribed
# Any cleanup needed when channel is unsubscribed
message = { user_id: current_user.id, online: :off }
ActionCable.server.broadcast stream_name, chat_cancel: message
end
....
end