복붙노트

[REDIS] 의 이유가 무엇 일 수 레일 ActionCable에서 "식별자 구독을 찾을 수 없습니다"?

REDIS

의 이유가 무엇 일 수 레일 ActionCable에서 "식별자 구독을 찾을 수 없습니다"?

나는 레일 5.0.0.rc1 + ActionCable + 레디 스를 사용하여 메신저 응용 프로그램을 짓고 있어요.

나는 단일 채널 ApiChannel과 조치의 숫자를했습니다. >, 뭔가를 물어 뭔가 다시 얻고, "방송"행동은 - -이 일부 "유니 캐스트"행동이> 뭔가를, 일부 연결된 클라이언트에 페이로드를 방송.

때때로 내가 여기에서 RuntimeError에 예외를 받고 있어요 : (식별자로 구독을 찾을 수 https://github.com/rails/rails/blob/master/actioncable/lib/action_cable/connection/subscriptions.rb#L70 수 없습니다. ..).

이것의 이유는 무엇을 할 수 있습니까? 어떤 상황에서 나는 그런 예외를받을 수 있나요? 나는 문제를 조사에 꽤 많은 시간을 소비 (그리고 그렇게 할 것입니다) 어떤 힌트는 크게 감사하겠습니다!

해결법

  1. ==============================

    1.그것은이 문제와 관련된 것 같습니다 : https://github.com/rails/rails/issues/25381

    그것은이 문제와 관련된 것 같습니다 : https://github.com/rails/rails/issues/25381

    레일은 구독이 생성되었지만 실제로는 아직 수행하지 않은 응답 경쟁 조건의 일종.

    구독을 수립 한 후 작은 시간 제한을 추가하는 임시 해결책이 문제를 해결함에.

    더 많은 조사가 필요는하지만 할 수 있습니다.

  2. ==============================

    2.이 오류의 원인은 당신이하고 메시징 가입 식별자의 차이가있을 수 있습니다. 나는 (보석 'devise_token_auth'로) 레일 5 API 모드에서 ActionCable를 사용하고 나도 같은 오류가 직면 :

    이 오류의 원인은 당신이하고 메시징 가입 식별자의 차이가있을 수 있습니다. 나는 (보석 'devise_token_auth'로) 레일 5 API 모드에서 ActionCable를 사용하고 나도 같은 오류가 직면 :

    (ERROR) 구독 :

    {"command":"subscribe","identifier":"{\"channel\":\"UnreadChannel\"}"}
    

    메시지 보내기 (ERROR) :

    {"command":"message","identifier":"{\"channel\":\"UnreadChannel\",\"correspondent\":\"client2@example.com\"}","data":"{\"action\":\"process_unread_on_server\"}"}
    

    어떤 이유로 ActionCable은 두 번 같은 식별자를 적용하기 위해 클라이언트 인스턴스가 필요합니다 - 가입하면서 메시징 동안 :

    /var/lib/gems/2.3.0/gems/actioncable-5.0.1/lib/action_cable/connection/subscriptions.rb:74

    def find(data)
      if subscription = subscriptions[data['identifier']]
        subscription
      else
        raise "Unable to find subscription with identifier: #{data['identifier']}"
      end
    end
    

    이 라이브 예입니다 : 사용자가 실시간 모드에서 읽지 않은 메시지 알림을받을 어디 메시징 서브 시스템을 구현합니다. 가입 당시, 난 정말하지만 메시징시, 특파원이 필요하지 않습니다 - 내가 할.

    그래서 솔루션은 데이터의 해시 식별자 해시에서 기자를 이동하는 것입니다 :

    메시지 보내기 (CORRECT) :

    {"command":"message","identifier":"{\"channel\":\"UnreadChannel\"}","data":"{\"correspondent\":\"client2@example.com\",\"action\":\"process_unread_on_server\"}"}
    

    이 방법은 오류가 사라입니다.

    여기 내 UnreadChannel 코드는 다음과 같습니다

    class UnreadChannel < ApplicationCable::Channel
      def subscribed
    
        if current_user
    
          unread_chanel_token = signed_token current_user.email
    
          stream_from "unread_#{unread_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
      end
    
      def process_unread_on_server param_message
    
        correspondent = param_message["correspondent"]
    
        correspondent_user = User.find_by email: correspondent
    
        if correspondent_user
    
          unread_chanel_token = signed_token correspondent
    
          ActionCable.server.broadcast "unread_#{unread_chanel_token}_channel",
                                       sender_id: current_user.id
        end
    
      end
    
    end
    

    도우미 : (당신은 일반 식별자를 노출하지 않아야 - 인코딩 그들에게 같은 방법으로 서명 것들로 인코딩 일반 쿠키를 레일)

      def signed_token string1
    
        token = string1
    
    # http://vesavanska.com/2013/signing-and-encrypting-data-with-tools-built-in-to-rails
    
        secret_key_base = Rails.application.secrets.secret_key_base
    
        verifier = ActiveSupport::MessageVerifier.new secret_key_base
    
        signed_token1 = verifier.generate token
    
        pos = signed_token1.index('--') + 2
    
        signed_token1.slice pos..-1
    
      end  
    

    이를 요약하면 모든 먼저 나중에 전화 MESSAGE 명령을 원하는 경우 명령을 구독 호출해야합니다. 두 명령 (여기에서 "채널") 같은 식별자 해시가 있어야합니다. 심지어없이 당신은 여전히 ​​(구독 후) 메시지를 보낼 수 있습니다 (- 가입 된 후크없이 그러나 아무도들을받지 않을 것이다 -) (!) 여기에 흥미로운 무엇, 가입 된 후크가 필요하지 않습니다.

    여기에 또 다른 흥미로운 점은 구독 후크 내부에서이 코드를 사용하는 것입니다 :

    stream_from "unread_#{unread_chanel_token}_channel"
    

    그것은 단지 "수신"방향에 적용 - 그리고 분명히 unread_chanel_token 무엇이든 될 수 있습니다.

    (같은 \ "채널 \"\ "UnreadChannel \") 구독 식별자가 그래서 미래의 메시지 전송 작업을위한 "암호"로 간주되어야한다 (예를 들어, 그것은 단지 "전송"방향에 적용) - 당신이 원하는 경우 메시지 (첫번째 송신 후 구독하고) 동일 제공을 보내 다시 "통과", 또는 당신은 설명 오류가 발생합니다.

    그리고 더 그것의 - 그것은 단지 "비밀번호"정말 - 당신이 볼 수 있듯이, 당신은 실제로 당신이 원하는 whereever에게 메시지를 보낼 수 있습니다 :

    ActionCable.server.broadcast "unread_#{unread_chanel_token}_channel", sender_id: current_user.id
    

    이상한, 맞죠?

    이 모든 꽤 복잡하다. 왜이 공식 문서에 설명되지 않은?

  3. from https://stackoverflow.com/questions/37696238/what-can-be-the-reason-of-unable-to-find-subscription-with-identifier-in-rails by cc-by-sa and MIT license