Reputation: 53
I work to switch Action Cable to AnyCable.
I don't use cookies to identify users, I use JWT because my app provide only API.
So in case of a chat, we need to retrieve the user who send the message.
In log, I see this message1:
RPC Command: <AnyCable::CommandMessage: command: "subscribe", identifier: "{\"channel\":\"RoomChannel\",\"room_id\":\"566\"}", connection_identifiers: "{\"current_user\":{\"id\":\"XXXXXXXX\",\"login_time\":1589745276,\"okta_id\":\"[email protected]\"
How can I retrieve the value of the object "connection_identifiers"?
Below the current connection Class : `Class : module ApplicationCable class Connection < ActionCable::Connection::Base include Authentication
identified_by :current_user
def connect
self.current_user = create_user_from_tokens
reject_unauthorized_connection unless current_user.valid
end
end end`
create_user_from_tokens > Create a user object from JWT token
And the current reception method for a new message : `def receive(content) return false unless receive_params return false unless conversation
message = content['content']
message_params = {conversation_id: @conversation.id,
conversation: @conversation,
sender_id: @connection.current_user.okta_id,
sender_name: @connection.current_user.name,
content: message}
ConversationMessageService.post message_params
rescue StandardError Rails.logger.error I18n.t('log.api.websocket.error_receive') render json: {error: :bad_request, error_description: I18n.t('log.api.websocket.error_receive'), error_uri: ''}, status: :bad_request end`
As I undertand it is impossible to retrieve @connection.
Upvotes: 0
Views: 413
Reputation: 191
To access the current user from the channel, you can use #current_user
accessor (Rails adds this delegation for you automatically).
So, the code should be:
message_params = {conversation_id: @conversation.id,
conversation: @conversation,
sender_id: current_user.okta_id,
sender_name: current_user.name,
content: message}
If I understood you correctly, your current_user
object is not an AR record but a plain Ruby class, right?
Then current_user
in channels would simply return a JSON-encoded string, not the object.
Currently, AnyCable uses GlobalID to serialize/deserialize connection identifiers. You must add GlobalID functionality to your class to make it work with AnyCable the same way as with Action Cable. For example:
class User
include GlobalID::Identification
def self.find_by_gid(gid)
new(gid.params)
end
def to_global_id
super(to_h.merge!(app: :custom))
end
alias to_gid to_global_id
end
# setup GlobalID to correctly resolve your custom class
GlobalID::Locator.use :custom do |gid|
gid.model_name.constantize.find_by_gid(gid)
end
Upvotes: 0