将websocket连接存储到redis

时间:2015-05-23 18:48:15

标签: ruby websocket redis sinatra padrino

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

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

我意识到我可以store the connections in an class variable,但这不适用于跨进程。

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

2 个答案:

答案 0 :(得分:1)

  

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

你无法重建它,你需要保持它活着,否则你断开你的客户端。

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

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

  1. 您要发送的邮件
  2. 您要将消息发送给
  3. 的人

答案 1 :(得分:1)

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

(*请注意,虽然Redis可以存储数据,但它无法存储对象,但它肯定无法存储实时套接字)

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

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