【问题标题】:Rails ActionCable / Turbolinks chat issue: posting duplicate messagesRails ActionCable / Turbolinks 聊天问题:发布重复消息
【发布时间】:2016-09-16 23:12:37
【问题描述】:

我遇到了 ActionCable 和 Turbolinks 的问题。我设置了一个类似于example chat app shared by DHH的聊天应用。

为了拥有多个聊天室并将聊天室 ID 传递给 ActionCable 订阅初始化程序,我有这样的事情:

$(document).on("turbolinks:load",function(){
  var pod_slug = $("#pod_slug_value").val();
  App.pods = App.cable.subscriptions.create(
    { channel: 'PodsChannel', pod_slug: pod_slug },
    {
    received: function(data) {
      if ( $(".chat-stream").length ){
        $(data.message).appendTo($(".chat-stream"));
        $(".chat-stream").scrollTop($(".chat-stream")[0].scrollHeight);
      }
    },

    speak: function(message, pod_slug) {
      return this.perform('speak',{
        message: message,
        pod_slug: pod_slug
      });
    }
  });

  // captures text input from input field
  captureMessage();

});

但是,当我在应用程序周围单击并返回页面时,Turbolinks 似乎多次绑定订阅处理程序,现在当我提交消息时,我在聊天流中收到重复消息。

我尝试过以各种方式解决这个问题。当我没有在订阅处理程序前面加上以下内容时,我没有问题:

$(document).on("turbolinks:load",function(){...

但是我无法获取聊天室 ID (pod_slug),因为在 javascript 执行之前文档 DOM 没有加载。

看起来这个问题有一个简单的解决方案,因为 ActionCable 和 Turbolinks 都受到 Basecamp 的大力支持。许多demo chat tutorials 建议以这种方式设置聊天。我在这里遗漏了什么吗?

【问题讨论】:

    标签: javascript ruby-on-rails chat turbolinks actioncable


    【解决方案1】:

    我遇到了同样的问题,并以这种方式解决了它

    if (!App.pods) {
      App.pods = App.cable.subscriptions.create(
       { channel: 'PodsChannel', pod_slug: pod_slug },
       { ... /* and so on */ }
    }
    

    每次重新加载页面时,'turbolinks:load' 事件都会起作用,因此您必须检查 App.pods 对象是否已经创建。

    希望这会对你有所帮助。

    【讨论】:

    • 但是 app.pods 不包含对所有不同聊天室的引用吗?因此,一旦创建了一个房间,检查它是否存在会阻止您启动新房间。没有?
    • @Lorenz 是的,你是对的。就我而言,我只需要一个频道,所以这个解决方案对我有用。但是现在我对这个问题很感兴趣,所以我会尝试找出我可以为您提供哪些帮助。
    • 我做了类似的事情来暂时解决我的问题:'if (!App.pods || JSON.parse(App.pods.identifier).pod_slug != pod_slug){' 但感觉非常老套。
    【解决方案2】:

    您可以使用App.cable.subscriptions.remove 删除App.cable.subscriptions.create 返回的订阅。所以也许检查App.pods 是否设置,如果是,请在再次订阅之前将其删除。

    【讨论】:

      【解决方案3】:

      我喜欢你的方法,MaruniakS。深入消费者对象,看起来它有一个测试,看它是否断开连接。只改变第一行,我们也可以这样做:

      if (!App.pods || App.pods.consumer.connection.disconnected) {
        App.pods = App.cable.subscriptions.create(
          { channel: 'PodsChannel', pod_slug: pod_slug },
          { ... /* and so on */ }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-04
        • 2014-12-28
        • 2016-07-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多