首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在rails中使用em-websocket构建对话系统的层次性?

在rails中使用em-websocket构建对话系统的层次性?
EN

Stack Overflow用户
提问于 2015-12-29 06:21:42
回答 2查看 121关注 0票数 1

也许这是服务器推送系统的一个很好的例子。系统中有很多用户,用户可以互相交谈。可以这样实现:一个用户(通过websocket)向服务器发送消息,然后服务器将消息转发给另一个用户。关键是找到ws(websocket对象)和用户之间的绑定。下面的示例代码如下:

代码语言:javascript
复制
EM.run {
  EM::WebSocket.run(:host => "0.0.0.0", :port => 8080, :debug => false) do |ws|
    ws.onopen { |handshake|
      # extract the user id from handshake and store the binding between user and ws
    }
    ws.onmessage { |msg|
      # extract the text and receiver id from msg
      # extract the ws_receiver from the binding
      ws_receiver.send(text)
    }
  end
}

我想找出以下问题:

  1. 可以序列化ws对象,以便将其存储到磁盘或数据库中?否则,我只能将绑定存储到内存中。
  2. em-websocket和websocket-rails之间有什么区别?
  3. 对于websocket,您推荐哪款宝石?
EN

回答 2

Stack Overflow用户

发布于 2015-12-29 06:33:58

您正在接近一个websockets非常适合的用例,因此您走上了正确的轨道。

  1. 您可以使用Marshal序列化ws对象,但是将websocket对象看作有点像http请求对象,因为它们是一种通信类型的抽象。最好是封送/存储数据。
  2. em-websocket是一个较低(Ish)水平的websocket库,或多或少直接建立在网络机器上。websocket-rails是websockets上的一个更高级别的抽象,内置了许多优秀的工具和相当好的ok文档。它是建立在faye-websocket-rails之上的,它本身就是建立在网络机器上的。*注意,Rails 5的新网络套接字库
  3. 我过去使用过websocket,而且非常喜欢它。它会照顾你很多。但是,如果您可以使用Rails 5和Action,那么这就是未来。
票数 1
EN

Stack Overflow用户

发布于 2015-12-29 17:36:02

以下是对蔡斯·吉利亚姆简洁的回答的补充,其中包括对em-websocketwebsocket-rails (很长一段时间没有维护)、faye-websocket-railsActionCable的引用。

我建议使用普莱齐框架。它既是一个独立的应用程序框架,也是一个Rails Websocket增强。

我也会考虑以下几点:

  1. 您是否需要在连接之间持久化消息(即,如果其他用户脱机,消息是否应在“消息框”中等待?消息要等多久?)?
  2. 您想保存消息历史记录吗?

这些点将帮助您决定是否对消息使用持久存储(即数据库)。

也就是说,要在Rails中使用普莱齐,请在应用程序的config/initializers文件夹中创建一个init_plezi.rb。使用以下代码(作为示例):

代码语言:javascript
复制
class ChatDemo
    # use JSON events instead of raw websockets
    @auto_dispatch = true
    protected #protected functions are hidden from regular Http requests
    def auth msg
        @user = User.auth_token(msg['token'])
        return close unless @user
        # creates a websocket "mailbox" that will remain open for 9 hours.
        register_as @user.id, lifetime: 60*60*9, max_connections: 5
    end
    def chat msg, received = false
        unless @user # require authentication first
           close
           return false
        end
        if received
           # this is only true when we sent the message
           # using the `broadcast` or `notify` methods
           write msg # writes to the client websocket
        end
        msg['from'] = @user.id
        msg['time'] = Plezi.time # an existing time object
        unless msg['to'] && registered?(msg['to'])
           # send an error message event
           return {event: :err, data: 'No recipient or recipient invalid'}.to_json
        end
        # everything was good, let's send the message and inform
        # this will invoke the `chat` event on the other websocket
        # notice the `true` is setting the `received` flag.
        notify msg['to'], :chat, msg, true
        # returning a String will send it to the client
        # when using the auto-dispatch feature
        {event: 'message_sent', msg: msg}.to_json
    end
end
# remember our route for websocket connections.
route '/ws_chat', ChatDemo
# a route to the Javascript client (optional)
route '/ws/client.js', :client

请设置自己的服务器(碘,Ruby服务器),所以请记住从应用程序中删除对pumathin或任何其他自定义服务器的引用。

在客户端,您可能希望使用Plezi提供的Javascript助手(它是可选的).加:

代码语言:javascript
复制
<script src='/es/client.js' />
<script>

    TOKEN = <%= @user.token %>;
    c = new PleziClient(PleziClient.origin + "/ws_chat") // the client helper
    c.log_events = true // debug
    c.chat = function(event) {
       // do what you need to print a received message to the screen
       // `event` is the JSON data. i.e.: event.event == 'chat'           
    }
    c.error = function(event) {
       // do what you need to print a received message to the screen
       alert(event.data);
    }
    c.message_sent = function(event) {
       // invoked after the message was sent
    }
    // authenticate once connection is established
    c.onopen = function(event) {
       c.emit({event: 'auth', token: TOKEN});
    }
    //  //  to send a chat message:
    //  c.emit{event: 'chat', to: 8, data: "my chat message"}
</script>

我没有测试实际的消息代码,因为它只是一个框架,而且它还需要一个带有User模型和token的Rails应用程序,我不想仅仅为了回答一个问题而编辑这个应用程序(无意冒犯)。

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

https://stackoverflow.com/questions/34505574

复制
相关文章

相似问题

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