操作电缆问题:消息偶尔不会发送或偶尔发送到错误的频道

时间:2017-01-11 01:53:31

标签: ruby-on-rails ruby heroku actioncable

我将Action Cable用于具有多种不同渠道的聊天应用程序。在Heroku上使用Redis和Postgresql(以保存消息)设置所有内容,95%的时间在开发和生产方面都非常有用。

有时,发送的邮件不会显示。消息被发送,它保存在数据库中,但除非我刷新,否则它永远不会出现在前端。或者,该消息显示在另一个未被定向的频道中。同样,一切都妥善保存在Postgres数据库中。它只是前端不稳定。在某个地方,ActionCable似乎感到困惑。

这个问题对我来说很少发生,很难复制到正确调试。但是我有很多用户经常报告这个问题,我很难弄清楚如何跟踪它。

以下是我的一些代码:

Javascript角/信道/ channels.js

class PodsChannel < ApplicationCable::Channel
  def subscribed
    stream_from "pods_channel_#{params['pod_slug']}"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end

  def speak(data)
    #after_create_commit callback fires to create a job to broadcast message
    pod_message = PodMessage.create! pod_slug: data['pod_slug'], message_body: data['message'], user_id: data['user_id'], message_type: data['msg_type']
  end
end

通道/ pods_channel.rb

$(document).on("ready",function(){
  var pod_slug = $("#pod_slug_value").val();

  // hack to prevent double posting of messages
  if (!App.pods || JSON.parse(App.pods.identifier).pod_slug != pod_slug){
    App.pods = App.cable.subscriptions.create(
      { channel: 'PodsChannel', pod_slug: pod_slug },
      {
      received: function(data) {
        if ( ($(".chat-stream").length) && data.pod_slug == pod_slug ){ // hack to prevent msgs going accross pods
          //#CLEAN: this is a super hackish way of preventing double messages
          if(!$("#msg_" + data.msg_id).length){
            $(data.message).appendTo($(".chat-stream")).find('.msg-text a').attr('target', '_blank');
            $("#msg_" + data.msg_id + " .msg-text").html(Autolinker.link($("#msg_" + data.msg_id + " .msg-text").html(), { mention: "sutra" }));
            $(".chat-stream").scrollTop($(".chat-stream")[0].scrollHeight);
          }
        }
      },

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

  if ( $(".chat-stream").length ) {
    $(".chat-stream").scrollTop($(".chat-stream")[0].scrollHeight);
  };

  captureMessage();
});

function captureMessage(){    

  $(document).on('click', "#btn-submit-msg", {}, function(){
    var raw_text = $("#msg-input-text").val();
    if (raw_text != ""){
      submitMessage(raw_text, "pod_message");
    }
  });

  $(document).on('keydown', '#msg-input-text', {}, function(event) {
    if (event.which == 13 && !event.shiftKey && !event.ctrlKey && !event.metaKey) {
        event.preventDefault();
        event.stopPropagation();
        if (event.target.value != "") {
          submitMessage(event.target.value, "pod_message")
        }
    }
    });
}

function submitMessage(raw_text, msg_type){
  var message = raw_text;
  var pod_slug = $("#pod_slug_value").val();
  var user_id = $("#current_user_id_value").val();
  var msg_type = msg_type;
  if (App.pods.consumer.connection.disconnected == false) {
    App.pods.speak(message, pod_slug, user_id, msg_type);
    if (msg_type != "attachment") {
      $("#msg-input-text").val("");
    }
  }
}

模型/ pod_message.rb

class PodMessage < ApplicationRecord
    after_create_commit { MessageBroadcastJob.perform_now self }
end

作业/ message_broadcast_job.rb

class MessageBroadcastJob < ApplicationJob
  queue_as :default

  def perform(pod_message)
    stream_id = "pods_channel_#{pod_message.pod_slug}"
    ActionCable.server.broadcast stream_id, message: render_message(pod_message), msg_id: pod_message.id, pod_slug: pod_message.pod_slug
  end

  private
    def render_message(pod_message)
      renderer = ApplicationController.renderer.new
      renderer.render(partial: 'pod_messages/pod_message', locals: { pod_message: pod_message })
    end
end

0 个答案:

没有答案