首页 > 解决方案 > AnyCable : 在 ROR App 上检索信息 gRPC 信息

问题描述

我努力将 Action Cable 切换到 AnyCable。

我不使用 cookie 来识别用户,我使用 JWT 因为我的应用程序只提供 API。

所以在聊天的情况下,我们需要检索发送消息的用户。

在日志中,我看到这条消息 1:

RPC Command: <AnyCable::CommandMessage: command: "subscribe", identifier: "{\"channel\":\"RoomChannel\",\"room_id\":\"566\"}", connection_identifiers: "{\"current_user\":{\"id\":\"XXXXXXXX\",\"login_time\":1589745276,\"okta_id\":\"xxxxx@gmail.com\"

如何检索对象“connection_identifiers”的值?

当前连接类下面:`类:模块 ApplicationCable 类 Connection < ActionCable::Connection::Base 包括 Authentication

identified_by :current_user

def connect
  self.current_user = create_user_from_tokens

  reject_unauthorized_connection unless current_user.valid
end

结束结束`

create_user_from_tokens > 从 JWT 令牌创建用户对象

以及当前接收新消息的方法:`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

救援 StandardError Rails.logger.error I18n.t('log.api.websocket.error_receive') 渲染 json: {error: :bad_request, error_description: I18n.t('log.api.websocket.error_receive'), error_uri: ' '},状态::bad_request end`

据我了解,不可能检索@connection。

标签: ruby-on-railsactioncable

解决方案


要从频道访问当前用户,您可以使用#current_user访问器(Rails 会自动为您添加此委托)。

所以,代码应该是:

message_params = {conversation_id: @conversation.id,
                  conversation: @conversation,
                  sender_id: current_user.okta_id,
                  sender_name: current_user.name,
                  content: message}

如果我理解正确,您的current_user对象不是 AR 记录,而是普通的 Ruby 类,对吗?

然后current_user在通道中将简单地返回一个 JSON 编码的字符串,而不是对象。

目前,AnyCable 使用 GlobalID 来序列化/反序列化连接标识符。您必须将 GlobalID 功能添加到您的类中,以使其与 AnyCable 的工作方式与 Action Cable 的工作方式相同。例如:

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

推荐阅读