0

Pubnub を使用して、サーバーからクライアント (ブラウザー ページ) にライブ メッセージを公開しています。Pubnub を使用する場合、メッセージ サイズの制約を順守する必要があるため、場合によってはメッセージをチャンクし、分割して送信し、クライアント側で再構築する必要があります。Pubnub のアドバイスに従って、Pubnub.publish()関数の呼び出しが速すぎない場合 (つまり、メッセージの断片が単に for ループを介してポンピングされている場合)、メッセージの各チャンクを確実に配信できます。

Pubnub Ruby API はPubnub.publish()、 、チャネル、メッセージ、およびコールバック関数で 3 つの必須引数を指定します。以下に示すコールバック関数は、Pubnub の Ruby の例からのものです。

    @my_callback = lambda { |message| puts(message) }
    pn.publish(:channel => :hello_world,
      :message => "hi",
      :callback => @my_callback)

コールバックのメッセージ(パブリッシュの "hi" メッセージではありません) には、publish()"sent" や "message to large" などの値を持つ呼び出しのステータス情報が含まれており、どちらにも一意の識別子が付随します。

したがって、Pubnub フードの下のどこかで、このコールバックが取得.call()されています - このプロセスの間に入る方法があるかどうか疑問に思っています。より詳細には、3 つのチャンクに分割する必要があるメッセージがあるとします。チャンク 0 を送信し、コールバックで「送信済み」ステータスを受信したら、チャンク 1 を送信したいと考えています。等...

私はラムダ関数とそのスコープにあまり詳しくありません。これが私の最初の試みでした。

    @my_callback = lambda { |message| 
                            puts(message) 
                            Rails.logger.debug("Setting pubnub_do_send to true from callback")
                            pubnub_do_send = true
                          }

    pubnub_do_send = true

    while !pubnub_message.nil?
      if pubnub_do_send 

        #Send pubnub message
        #Cut off first chunk of message (this is why I'm testing for nil)
        #Set pubnub_do_send to false

        Rails.logger.debug("Message #{message_id} chunk #{chunk_id} sent")
        pubnub_do_send = false
      end
    end

これは完全な失敗をもたらしました - (私が推測しなければならなかった場合) pubnub_do_send が再び true に設定されなかったため、サーバーが無限の while ループに完全にロックされました。デバッグ ログを見ると、最初のメッセージ (「メッセージ 1 チャンク 0 が送信されました」) が表示されますが、コールバック関数からの出力は表示されません。(おそらく、それ自体が見つかった無限 while ループのため)

これを行うためのクリーンな方法が必要です。コードをある程度リファクタリングし、最初にメッセージを分割して配列に格納し、次に配列をループして送信するだけで問題ありませんが、解決策ができるように感じます.私はラムダ関数とコールバックがあまり得意ではありません。

ソリューションは次のようになります。

    @my_callback = lambda { |message| 
                            puts(message) 
                            send_pubnub_message(message_id, chunk_id, chunk)
                          }

    def send_pubnub_message(message_id, chunk_id, chunk)
      #Send pubnub message
      #Send message_id, next chunk_id, and next chunk to my_callback
    end

しかし、問題は、私が直接呼び出すのではなく、メッセージに関するステータスを取得するmy_callbackときに Pubnub によって呼び出されることです! (pubnub にメッセージをミックスにアタッチさせながらPubnub.publish()、message_id、chunk_id、およびチャンクをコールバックに挿入する方法はありますか?それは間違っているように聞こえますが、Ruby を使用している可能性があります...)

すべての助けを前もって感謝します。

4

1 に答える 1

1

コールバックでメッセージチャンクの状態を処理しようとしてはいけません。公開のステータスを通知する責任は1つだけです。ただし、メッセージに内容を挿入することはできます。現在の状態を認識しているメッセージラッパーを作成し、それをラムダで送信する可能性があるため、追跡する必要はありません。私は次のコードをテストしていませんが、これが私が話していることの例です:

class Message
  attr_accessor :id, :message, :chunked_message, :chunk_id
  def initialize(id, message)
    @id, @message = id, message
    chunk_message
  end
  def current_chunk
    @chunked_message[@chunk_id]
  end
  def next_chunk
    @chunk_id += 1
    self
  end
  def more?
    @chunked_message.length > chunk_id
  end
  private
  def chunk_message 
    implement splitting message here
  end
end 


def send_pubnub_message(message)
  pn.publish(:channel => :hello_world,
  :message => message.current_chunk
  :callback => lambda { |status| 
                        puts(status)
                        case status[0] // 1 = success, 0 = fail
                        when 1
                          send_pubnub_message(message.next_chunk) if message.more?
                        when 0
                          handle_pubnub_error(status[1], message)
                        end
                      }
end
于 2013-03-06T17:30:40.563 に答える