Action Cable: Messages are sometimes not delivered or are sometimes sent to the wrong channel

I use Action Cable for chat with various channels. Everything is configured using Redis and Postgresql (to save messages) on Heroku, and 95% of the time works fine in development and production.

Sometimes, although sent messages are not displayed. The message is sent, it is stored in the database, but then it never appears on the front side if I do not update. Or the message appears in another channel for which it is not directed. Again, everything is stored correctly in the Postgres database. He just becomes awkward at the front end. Somewhere, the ActionCable seems to be confused.

This problem rarely occurs to me, which is very difficult to replicate for proper debugging. But I have a bunch of users who regularly report a problem, and I'm struggling to figure out how to track it.

Here is my code:

JavaScripts / channels / 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 

Channels / 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(""); } } } 

models / pod_message.rb

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

Work / 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 
+5
source share

Source: https://habr.com/ru/post/1262617/


All Articles