首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >抽筋框架同步使用em-synchrony的正确方式

抽筋框架同步使用em-synchrony的正确方式
EN

Stack Overflow用户
提问于 2013-10-31 20:41:42
回答 1查看 152关注 0票数 0

为了描述我的问题,我附加了简单的http://cramp.in/类。我添加了一些修改,但它的主要工作方式类似于action.rb

代码语言:javascript
复制
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方法中。

我试着按正确的顺序向客户发送消息。首先向所有订阅者发布消息,然后只为当前连接的客户端提供一些内部信息。

对于上述代码,客户端接收:

代码语言:javascript
复制
{"action":"message","user":"user1","message":"this info should appear after published message"}
{"action":"message","message":"simple message","user":"user1"}

它不是同步的,可能是因为他们受聘的反应。所以我试着用这样的方式同步:

代码语言:javascript
复制
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

现在,客户端以正确的顺序处理消息。

代码语言:javascript
复制
{"action":"message","message":"simple message","user":"user1"}
{"action":"message","user":"user1","message":"this info should appear after published message"}

我的问题是:

  • 当我评论EM::Synchrony.next_tick块时,消息顺序仍然是不正确的。在这个例子中,EM::Synchrony.next_tick块是什么意思?
  • 这是处理与Cramp或EventMachine的内联同步的好方法吗?
  • 有更好、更清晰的方法来处理吗?

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-12 23:08:07

我找到了这个问题的解决方案,em-synchrony应该通过要求这个库来内部工作:

代码语言:javascript
复制
require 'em-synchrony/em-hiredis'

class ChatAction < Cramp::Websocket

使用EM::Synchrony.next_tick块是个坏主意,在em-synchrony社区的大力帮助下,我添加了github上的em-hiredis 0.2.1兼容性补丁

现在,handle_message方法如下所示:

代码语言:javascript
复制
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拿走这颗宝石

代码语言:javascript
复制
gem 'em-synchrony', :git=> 'git://github.com/igrigorik/em-synchrony.git'

希望它能帮到别人。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19716265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档