您好我已经使用rails 5实现了动作电缆。它在本地工作正常,但它不能在heroku上工作。在heroku上,每当我发送任何消息时,它都会发送四条消息,两条重复消息和两条空白消息。这是我的代码: - conversation.js
App.conversation = App.cable.subscriptions.create("ConversationChannel", {
connected: function() {},
disconnected: function() {},
received: function(data) {
var conversation = $('#conversations-list').find("[data-conversation-id='" + data['conversation_id'].$oid + "']");
if (data['window'] !== undefined) {
var conversation_visible = conversation.is(':visible');
if (conversation_visible) {
var messages_visible = (conversation).find('.panel-body').is(':visible');
if (!messages_visible) {
conversation.removeClass('panel-default').addClass('panel-success');
conversation.find('.panel-body').toggle();
}
conversation.find('.messages-list').find('ul').append(data['message']);
}
else {
$('#conversations-list').append(data['window']);
conversation = $('#conversations-list').find("[data-conversation-id='" + data['conversation_id'].$oid + "']");
conversation.find('.panel-body').toggle();
}
}
else {
conversation.find('ul').append(data['message']);
}
var messages_list = conversation.find('.messages-list');
var height = messages_list[0].scrollHeight;
messages_list.scrollTop(height);
},
speak: function(message) {
return this.perform('speak', {
message: message
});
},
});
$(document).on('submit', '.new_message', function(e) {
e.preventDefault();
var values = $(this).serializeArray();
App.conversation.speak(values);
$(this).trigger('reset');
});
的application.js
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
// vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require rails-ujs
// require turbolinks
//= require jquery-3.2.1.min
// require_tree .
(function() {
$(document).on('click', '.toggle-window', function(e) {
e.preventDefault();
var panel = $(this).parent().parent();
var messages_list = panel.find('.messages-list');
panel.find('.panel-body').toggle();
panel.attr('class', 'panel panel-default');
if (panel.find('.panel-body').is(':visible')) {
var height = messages_list[0].scrollHeight;
messages_list.scrollTop(height);
}
});
})();
Cable.js
//= require action_cable
//= require_self
//= require_tree ./channels
(function() {
this.App || (this.App = {});
App.cable = ActionCable.createConsumer();
}).call(this);
create.js
var conversations = $('#conversations-list');
var conversation = conversations.find("[data-conversation-id='" + "<%= @conversation.id %>" + "']");
if (conversation.length !== 1) {
conversations.append("<%= j(render 'conversations/conversation', conversation: @conversation, user: current_user) %>");
conversation = conversations.find("[data-conversation-id='" + "<%= @conversation.id %>" + "']");
}
conversation.find('.panel-body').show();
var messages_list = conversation.find('.messages-list');
var height = messages_list[0].scrollHeight;
messages_list.scrollTop(height);
聊天截图 enter image description here
请让我知道如何解决它。我正在使用带有ruby-2.4.0的rails 5。我也在使用redis服务器进行工作。
答案 0 :(得分:0)
您设置了一个与ActionCable无关的Javascript event
侦听器。
每当您触发submit
底部时,您都会调用在页面上附加消息的App.conversation.speak()
函数
$(document).on('submit', '.new_message', function(e) {
e.preventDefault();
var values = $(this).serializeArray();
App.conversation.speak(values);
$(this).trigger('reset');
});
这是您的speak
功能
speak: function(message) {
return this.perform('speak', {
message: message
});
我引用Defining The Channel's Subscriber
我们使用
App.cable.subscriptions.create
向我们的消费者添加新订阅。我们为此函数提供了我们要订阅的频道名称的参数ConversationChannel
。当调用此
subscriptions.create
函数时,它将调用ConversationChannel#subscribed
方法,实际上是回调方法。
So what is a callback method?我无法清楚地回答这个问题。
此方法负责订阅和流式传输到此频道的消息。
应用程序/信道/ conversation_channel.rb
class ConversationChannel < ApplicationCable::Channel
def subscribed
stream_from 'conversation'
end
end
那
来自我们的消息广播的
ConversationChannel#subscribed
个流,将任何新消息作为JSON发送到客户端订阅功能。
这是我在将Message
保存到数据库后实现ActionCable的方法我在MessagesController
中触发了Sophie Debenedetto指南中的以下操作(我不知道)如果您将Conversation
保存到数据库或Message
)
应用程序/控制器/ messages_controller.rb
class MessagesController < ApplicationController
def create
message = Message.new(message_params)
message.user = current_user
if message.save
ActionCable.server.broadcast 'messages',
message: message.content,
user: message.user.username
head :ok
end
end
...
end
ActionCable.server.broadcast 'messages',
向received
内的App.cable.subscription
函数发送调用,该函数负责使用新消息更新页面。
此调用仅针对此事件subscribed
的用户执行。订阅通过subscribed
ConversationChannel
方法进行管理
App.conversation = App.cable.subscriptions.create('ConversationChannel', {
received: function(data) {
$('#messages').append(this.speak(data));
},
speak: function(data) {
return "<br><p> <strong>" + data.user + ": </strong>" + data.message + "</p>";
};
}
});
它以json
格式message: message.content, user: message.user.username
这些代码中的一部分来自我的应用https://sprachspiel.xyz,这是您可以测试的动作有线应用,该应用仍应正常运行。这是github repository
我相信你正在调用你的js函数两次,或者做一些解决方法来使actioncable工作导致div被追加两次。我相信你正在执行两个不同的时间j来运行动作电缆。
请记住,动作电缆是一个websocket,用于在2个不同的用户/浏览器上更新该消息