【问题标题】:Store websocket connection to redis将 websocket 连接存储到 redis
【发布时间】:2015-08-05 15:19:52
【问题描述】:

我正在使用websocket-rack 构建聊天应用程序 API。

我想将 websocket 连接(最终成为 Rack::WebSocket::Handler::Base::Connection 的一个实例)存储在 redis 中,以便它们可以被过滤并从其他进程中引用。

我知道我可以store the connections in an class variable,但这不能跨进程工作。

对象本身显然不能存储在redis中,但是我可以存储websocket_key和其他一些信息,并在我想向它发送消息时以某种方式重建连接对象吗?

【问题讨论】:

    标签: ruby websocket redis sinatra padrino


    【解决方案1】:

    我建议使用 Websockets 框架,例如 the Plezi web-app framework,它可以处理 websocket 连接 IO 并帮助您通过 Redis 服务器跨多个进程广播数据*。

    (* 注意Redis虽然可以存储数据,但不能存储对象,而且肯定不能存储活动套接字)

    例如:Plezi 会让你分叉你的服务器,它会自动使用 Redis 在不同进程或不同机器上的 websocket 之间广播/单播数据:

    require 'plezi'
    ENV['PL_REDIS_URL'] = "redis://username:password@my.host:6379"
    # fork to 4 processes, each will have at least 2 Redis connections
    GR::Settings.set_forking 4
    # ... plezi code
    Plezi.start # now it will fork.
    

    使用the Plezi framework 的工作聊天服务器看起来像这样*:

    * 这只是在irb 终端中运行的草稿。使用plezi new app_name 命令设置的 Plezi 应用程序看起来更有条理。

    require 'plezi'
    
    # # optional Redis URL: automatic broadcasting across processes:
    # ENV['PL_REDIS_URL'] = "redis://username:password@my.host:6379"
    
    class ChatController
        def index
            %q{        This is a Plezi chat demo app using websockets.
            To test this app, go to: http://www.websocket.org/echo.html
            In the Location URL fill in the following url: ws://localhost:3000/nickname
            Click Connect. No the app will act as a chat demo server with your browser as the client.
    
            Try running the demo from two different browser windows to see chat messages between windows.
            remember to set the correct Location URL in each window.}
        end
        def on_message data
            msg = "#{params[:id] ? params[:id].to_s : 'unknown'}: #{data}"
            broadcast :_send, msg
            _send msg
            true
        end
        def _send message
            response << message
        end
    end
    
    # starts listening with default settings, on port 3000
    listen
    
    # this is automatically converted to the RESTful route: '/(:id)'
    route '/', ChatController
    
    # exit terminal to start server
    exit
    

    【讨论】:

      【解决方案2】:

      当我想向它发送消息时以某种方式重建连接对象?

      你不能重建它,你需要让它保持活跃,否则你会断开你的客户端。

      维护您的 WebSocket 连接(活动)的进程还需要提供一个 API,以便其他进程可以告诉它代表他们发送消息。

      例如,这可能是一个简单的私有(仅接受来自localhost 的连接)HTTP API,您可以在其中发送带有两个参数的 POST 消息:

      1. 您要发送的消息
      2. 您要将消息发送给谁

      【讨论】:

      • 谢谢马丁,我就是这么想的。我现在只需要在同一个过程中保持这一切,稍后再找出解决方案。
      • 我对我当前的架构使用了类似的东西。除了自己编写之外,我使用了一个 nginx 插件。看看github.com/wandenberg/nginx-push-stream-module 效果很好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-09
      • 2019-07-01
      • 2022-08-03
      • 2020-08-10
      • 2021-10-27
      • 2020-01-07
      相关资源
      最近更新 更多