在 Rails 上使用 Event Machine Websocket 进行聊天,在开发中运行精简,但在生产中没有
Posted
技术标签:
【中文标题】在 Rails 上使用 Event Machine Websocket 进行聊天,在开发中运行精简,但在生产中没有【英文标题】:Chat made with Event Machine Websocket on rails, running thin worked in development but not production 【发布时间】:2015-04-06 18:04:32 【问题描述】:我在 Rails 应用程序上创建了一个实时聊天,并使用 EventMachine 运行 Websocket 进行实时聊天。实时聊天在多台机器上的 localhost 上运行。
它还可以在 ubuntu 上开发中的 Amazon EC2 实例上运行,但是当我尝试将其移至生产环境时,实时聊天不再起作用。没有数据来回发送。
这是我的控制器:
@clients = []
EM.run do
EM::WebSocket.start(host: "0.0.0.0", port: 3060) do |ws|
crypt = ActiveSupport::MessageEncryptor.new(ENV['SECRET_KEY_BASE'])
ws.onopen do |handshake|
conversation_data = crypt.decrypt_and_verify(handshake.query_string)
@clients << socket: ws, conv_info: conversation_data
end
ws.onclose do
ws.send "Closed."
@clients.delete ws
end
ws.onmessage do |data|
data = data.split('L56HTY9999')
body = data[0]
key = data[-1]
conversation = crypt.decrypt_and_verify(key)
new_message = Message.new(body: body, user_id: conversation[:user_id], conversation_id: conversation[:conversation_id])
if new_message.save
@clients.each do |socket|
if socket[:conv_info][:conversation_id] == conversation[:conversation_id]
socket[:socket].send new_message.chat_show
end
end
else
if socket[:conv_info][:user_id] == conversation[:user_id]
socket[:socket].send new_message.errors.to_json
end
end
end
end
end
这是我在页面上的javascript:
function addMessage(msg)
var content = JSON.parse(msg);
var context =
userImage: content.image,
author: content.username,
convoText: content.body,
time: content.created_at
;
var source = $('#add-newest-comment').html();
var template = Handlebars.compile(source);
var newComment = template(context);
$('#container').append(newComment);
var key = '<%= @conv_id %>';
var socket, host;
host = "ws://0.0.0.0:3060?"+ key;
function onErrors(msg)
$("#chat-log .error").text( msg);
setTimeout(function()
$( "#chat-log .error" ).text("");
, 3000);
function socketHealth(msg)
console.log(msg);
function connect()
try
socket = new WebSocket(host);
socketHealth("Socket State: " + socket.readyState);
socket.onopen = function()
socketHealth("Socket Status: " + socket.readyState + " (open)");
socket.onclose = function()
socketHealth("Socket Status: " + socket.readyState + " (closed)");
socket.onmessage = function(msg)
addMessage(msg.data);
catch(exception)
onErrors("Error: " + exception);
$(function()
connect();
);
function send()
var text = $("#message").val();
if (text == '')
onErrors("Please Enter a Message");
return;
try
socket.send(text + 'L56HTY9999' + key);
catch(exception)
onErrors("Failed To Send")
$("#message").val('');
$('#message').keypress(function(event)
if (event.keyCode == '13') send();
);
$("#disconnect").click(function()
socket.close()
);
我正在使用以下命令运行我的服务器:
bundle exec thin start -p 80 -d -l thin.log -P thin.pid
我的网站位于http://puppyplaydate.co/
控制台记录这个
Socket State: 0
messages:153 WebSocket connection to 'ws://0.0.0.0:3060/?aVI0OFVHS2VET3d4OTQ4M2s4Rk5VMld1eVlXOUFoVUFxT1JMSm5LWDJOUEhScU50MzFub2JMQ3Y4NG1uekl3TS0tYnlBU1ZRclErK3QxWERHN0taSTVzUT09--01ec4a49ce0aeef59bee5d5b8e13d7916abc20e1' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
messages:148 Socket Status: 3 (closed)
我使用 netstat 检查服务器是否正在侦听该端口并将其返回:
tcp 0 0 *:3060 *:* LISTEN
我在网上进行了研究,有人说他们使用“守护进程”gem 在生产环境中运行 websocket?我不确定这是否是我需要的。
我真的卡住了,提前感谢您的帮助!
【问题讨论】:
【参考方案1】:问题是我运行的是 Thin 服务器而不是 Rails,而不是运行设置为启动 Thin 的 Rails 服务器。
【讨论】:
以上是关于在 Rails 上使用 Event Machine Websocket 进行聊天,在开发中运行精简,但在生产中没有的主要内容,如果未能解决你的问题,请参考以下文章
使用 Capistrano 将 Rails 应用程序部署到多个服务器 - 最佳实践
在移动设备上禁用 Bootstrap 日期选择器的键盘弹出窗口(Rails 4,Jquery)