ConnectionManager.onChannelMessage()は、connectionSerialが異なるが、以前と同じメッセージIDを持つメッセージを受信しました。廃棄

ジェイソン・ガルテン

Webベースの予約システムにAblyRealtimeを使用する。

すべてが正常に機能していますが、jsコンソールで一貫していくつかのエラーが発生します。

基本的に、日付セレクターがあり、訪問者が日付を選択すると、グローバル変数dayを日付(のようなもの2018-05-25)に設定して呼び出しますVisitorMessages.start()。これにより、メッセージをサブスクライブしてチャネルに表示しvisitor:2018-05-25、他のすべてのチャネルからサブスクライブを解除します。 。

またvisitor:all、誰もがメッセージを受信し、プレゼンスが不要なチャネルもあります。

これが私がしていることです(CoffeeScriptを許してください):

VisitorMessages =
  realtime: null
  connected_first_time: false
  start: ->
    unless @realtime
      @realtime = new Ably.Realtime
        authUrl: '/auth'
        recover: (lastConnectionDetails, cb) ->
          cb(true)
          return

    @unsubscribe()

    dayChannel = @realtime.channels.get("visitor:#{day}")
    allChannel = @realtime.channels.get("visitor:all")

    allChannel.subscribe (m) ->
      switch m.name
        when " . . . "
          # . . .
    dayChannel.subscribe (m) ->
      switch m.name
        when " . . . "
          # . . .

    dayChannel.presence.subscribe 'enter', (member) -> VisitorMessages.setNumOnline(dayChannel)
    dayChannel.presence.subscribe 'leave', (member) -> VisitorMessages.setNumOnline(dayChannel)
    dayChannel.presence.enter()
    VisitorMessages.setNumOnline(dayChannel)

    @realtime.connection.on 'connected', ->
      VisitorMessages.refreshData() # not showing this function here
      VisitorMessages.connected_first_time = true # the refreshData() function returns if this is false
      dayChannel = VisitorMessages.realtime.channels.get("visitor:#{day}")
      dayChannel.attach()
      dayChannel.presence.enter()
      VisitorMessages.setNumOnline(dayChannel)
      allChannel = VisitorMessages.realtime.channels.get("visitor:all")
      allChannel.attach()

  setNumOnline: (channel) ->
    channel.presence.get (err, members) ->
      # I use ractive.js to manipulate the DOM
      ractive.set('number_online', members.length)

  unsubscribe: ->
    for channelName of VisitorMessages.realtime.channels.all
      unless channelName == 'visitor:all'
        channel = VisitorMessages.realtime.channels.get(channelName)
        channel.presence.leave()
        channel.presence.unsubscribe()
        channel.unsubscribe()
        channel.detach()
        VisitorMessages.realtime.channels.release(channelName)

jsコンソールでは、訪問者はこれらの束を取得します。

Ably: ConnectionManager.onChannelMessage() received message with different connectionSerial, but same message id as a previous; discarding

時々これ:

Ably: RealtimePresence._ensureMyMembersPresent(): Presence auto-re-enter failed: [c: Unable to enter presence channel (incompatible state); code=90001]

そして、別の日付(日付を設定して電話をかける)に切り替えるとVisitorMessages.start()、次のようになります。

Channels.onChannelMessage(): received event for non-existent channel: visitor:2018-05-26

これはおそらく、日を切り替えるときに明示的にチャンネルをリリースしているためだと思いますが、そうしなかったときVisitorMessages.realtime.channels.allは、これまでに参加したすべてのチャンネルが含まれ、未登録のチャンネルのメッセージを受信して​​いました。

ですから、ここではさまざまなことが起こっていますが、誰かが私のアプローチの全体像の欠陥を見たり、これらのエラーが発生している理由を理解するのを手伝ってくれますか?繰り返しますが、すべてが正常に機能しますが、何かが正しくありません!

ありがとう!


上記のコードをjavascriptにコンパイルします。

var VisitorMessages;

VisitorMessages = {
  realtime: null,
  connected_first_time: false,
  start: function() {
    var allChannel, dayChannel;
    if (!this.realtime) {
      this.realtime = new Ably.Realtime({
        authUrl: '/auth',
        recover: function(lastConnectionDetails, cb) {
          cb(true);
        }
      });
    }
    this.unsubscribe();
    dayChannel = this.realtime.channels.get("visitor:" + day);
    allChannel = this.realtime.channels.get("visitor:all");
    allChannel.subscribe(function(m) {
      switch (m.name) {
        case " . . . ":
          // . . .
      }
    });
    dayChannel.subscribe(function(m) {
      switch (m.name) {
        case " . . . ":
          // . . .
      }
    });
    dayChannel.presence.subscribe('enter', function(member) {
      VisitorMessages.setNumOnline(dayChannel);
    });
    dayChannel.presence.subscribe('leave', function(member) {
      VisitorMessages.setNumOnline(dayChannel);
    });
    dayChannel.presence.enter();
    VisitorMessages.setNumOnline(dayChannel);
    return this.realtime.connection.on('connected', function() {
      VisitorMessages.refreshData();
      VisitorMessages.connected_first_time = true;
      dayChannel = VisitorMessages.realtime.channels.get("visitor:" + day);
      dayChannel.attach();
      dayChannel.presence.enter();
      VisitorMessages.setNumOnline(dayChannel);
      allChannel = VisitorMessages.realtime.channels.get("visitor:all");
      allChannel.attach();
    });
  },
  setNumOnline: function(channel) {
    channel.presence.get(function(err, members) {
      ractive.set('number_online', members.length);
    });
  },
  unsubscribe: function() {
    var channel, channelName, results;
    for (channelName in VisitorMessages.realtime.channels.all) {
      if (channelName !== 'visitor:all') {
        channel = VisitorMessages.realtime.channels.get(channelName);
        channel.presence.leave();
        channel.presence.unsubscribe();
        channel.unsubscribe();
        channel.detach();
        VisitorMessages.realtime.channels.release(channelName);
      }
    }
  }
};
サイモンウールフ

私はAblyのエンジニアです。

特に大きな絵を描く人はいません。ここで起こっているさまざまなことがたくさんあります。

Ably:ConnectionManager.onChannelMessage()は、connectionSerialが異なるメッセージを受信しましたが、メッセージIDは以前と同じです。廃棄

これは、クライアントライブラリがメッセージの複数のコピーを受信し、それらを自動的に重複排除していることを意味します。これは、クライアントライブラリがcomet-> websocketのライブアップグレードを行った直後に発生することがあります。それが一貫して発生する場合は、他に何かが起こっている可能性があります。お問い合わせください。ライブでデバッグを試みます。

Channels.onChannelMessage():存在しないチャネルのイベントを受信しました:visitor:2018-05-26

あなたが正しく指摘したように、それはあなたがチャンネルを解放しているからです。channels.release()はめったに使用されない機能であり、クライアントが非常に多くのチャネルに接続および切断しchannels.allて、大量のメモリまとめて取得し始める場合にのみ実際に役立ちます。そのため、release()はそれらを削除して、ガベージコレクションできるようにします。99%の人がやらなければならないことや知っておく必要があることではありません。APIドキュメントにも含まれていないと思います。まだ切り離されていないチャネルでは絶対に使用しないでください。未定義の動作が発生します。

コードで呼び出すと、呼び出したとしても、チャネルは実際にはまだ切り離されていませんdetach()パーチャンネル#デタッチ()のためのAPIドキュメントは、非同期操作です-それは巧みからの切り離しを要求し、に入れたチャネルをdetachingその間に状態。チャネルを解放する必要がある場合(およびクライアント側で解放する必要はほとんどありません)、コールバックdetach()(またはonce('detached')リスナー)で実行する必要があります

それをしていなかったとき、VisitorMessages.realtime.channels.allには、これまでに参加したことのあるすべてのチャネルが含まれていました。

ええ、でもそれは問題ありません。そのオブジェクトに含まれているからといって、それらがアタッチされているわけではありません。あなたは、そのもののためにこれらのエントリをフィルタリングすることでのみ、添付のものを表示することができますstateです'attached'

まだ購読していないチャンネルのメッセージを受信して​​いました。

購読解除はローカル操作です(追加したリスナーを同期的に削除するだけです)。libがサーバーからメッセージを受信しないようにする場合は、チャネルからデタッチする必要があります。channels/ messagesのドキュメントを参照してください。

(unsubscribe()を呼び出した後もメッセージリスナーが呼び出されている、またはlibがdetached状態のチャネルでメッセージを受信して​​いる場合は、どちらも不可能である必要があります-購読解除コードが壊れています(私はしませんコーヒースクリプトをよく知っているのではないかと思います)、呼び出されているリスナーが思ったチャンネルのものではない、またはably-jsにバグがあります。liblog: {level: 4}コンストラクターで設定すると、デバッグログが有効になります。 libが何をしているのか、ログの分析についてサポートが必要な場合はお知らせください)。

Ably: RealtimePresence._ensureMyMembersPresent(): Presence auto-re-enter failed: [c: Unable to enter presence channel (incompatible state); code=90001]

通常、これは、チャネルが一時停止された後(たとえば、インターネットから2分以上切断されたため)、自動的に再接続および再入力を試みたが、できなかったことを意味します。たとえば、クライアントが現在、そのチャネルにアクセスするための権限がありません。

しかし、あなたの場合、手動でrelease()dしたチャネルからのノイズだと思いますが、サーバーからは通知されなかったため、問題が発生しましたdetached

(私は実際に、channels.release()をガードして、アクティブな状態のチャネルに対してそれを実行しないようにする機能の提案を提出しました-https://github.com/ably/docs/issues/437)。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してくださいdebugcn@gmail.com

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ