为了描述我的问题,我附加了简单的http://cramp.in/类。我添加了一些修改,但它的主要工作方式类似于action.rb。
class ChatAction < Cramp::Websocket
use_fiber_pool
on_start :create_redis
on_finish :handle_leave, :destroy_redis
on_data :received_data
def create_redis
@redis = EM::Hiredis.connect('redis://127.0.0.1:6379/0')
end
def destroy_redis
@redis.pubsub.close_connection
@redis.close_connection
end
def received_data(data)
msg = parse_json(data)
case msg[:action]
when 'join'
handle_join(msg)
when 'message'
handle_message(msg)
else
# skip
end
end
def handle_join(msg)
@user = msg[:user]
subscribe
publish(:action => 'control', :user => @user, :message => 'joined the chat room')
end
def handle_leave
publish :action => 'control', :user => @user, :message => 'left the chat room'
end
def handle_message(msg)
publish(msg.merge(:user => @user))
# added only for inline sync tests
render_json(:action => 'message', :user => @user, :message => "this info should appear after published message")
end
private
def subscribe
@redis.pubsub.subscribe('chat') do |message|
render(message)
end
end
def publish(message)
@redis.publish('chat', encode_json(message))
end
def encode_json(obj)
Yajl::Encoder.encode(obj)
end
def parse_json(str)
Yajl::Parser.parse(str, :symbolize_keys => true)
end
def render_json(hash)
render encode_json(hash)
end
end更多关于我尝试做的事情是在handle_message方法中。
我试着按正确的顺序向客户发送消息。首先向所有订阅者发布消息,然后只为当前连接的客户端提供一些内部信息。
对于上述代码,客户端接收:
{"action":"message","user":"user1","message":"this info should appear after published message"}
{"action":"message","message":"simple message","user":"user1"}它不是同步的,可能是因为他们受聘的反应。所以我试着用这样的方式同步:
def handle_message(msg)
EM::Synchrony.sync publish(msg.merge(:user => @user))
EM::Synchrony.next_tick do # if I comment this block messages order is still incorrect
render_json(:action => 'message', :user => @user, :message => "this info should appear after published message")
end
end现在,客户端以正确的顺序处理消息。
{"action":"message","message":"simple message","user":"user1"}
{"action":"message","user":"user1","message":"this info should appear after published message"}我的问题是:
谢谢!
发布于 2013-11-12 23:08:07
我找到了这个问题的解决方案,em-synchrony应该通过要求这个库来内部工作:
require 'em-synchrony/em-hiredis'
class ChatAction < Cramp::Websocket使用EM::Synchrony.next_tick块是个坏主意,在em-synchrony社区的大力帮助下,我添加了github上的em-hiredis 0.2.1兼容性补丁。
现在,handle_message方法如下所示:
def handle_message(msg)
publish(msg.merge(:user => @user))
render_json(:action => 'message', :user => @user, :message => "this info should appear after published message")
end别忘了从github拿走这颗宝石
gem 'em-synchrony', :git=> 'git://github.com/igrigorik/em-synchrony.git'希望它能帮到别人。
https://stackoverflow.com/questions/19716265
复制相似问题