将 WebSocket 连接存储到 Redis

7
我正在使用 websocket-rack 构建聊天应用程序 API。
我希望将 websocket 连接(最终成为 Rack::WebSocket::Handler::Base::Connection 的实例)存储在 Redis 中,以便可以从其他进程进行过滤和引用。
我意识到我可以将连接存储在类变量中,但这不能跨进程工作。
显然,对象本身无法存储在 Redis 中,但是我能否存储 websocket_key 和其他一些信息,并在需要向其发送消息时重新构建连接对象?
2个回答

3
当我想向连接对象发送消息时,你无法重新构建它,必须保持其活动状态,否则将断开客户端。维护WebSocket连接的进程还需要提供API,以便其他进程可以告诉它代表他们发送消息。例如,这可能是一个简单的私有(仅接受来自localhost的连接)HTTP API,在其中您发送具有两个参数的POST消息:
1. 您想要发送的消息 2. 您想要发送消息给谁

1
谢谢马丁,这正是我在想的。现在我只能将所有东西放在同一个进程中,并稍后再找出解决方案。 - fridgerator
1
我在我的当前架构中使用类似的东西。不过,我没有自己编写它,而是使用了一个nginx插件。请看https://github.com/wandenberg/nginx-push-stream-module,它运行得非常好。 - Martin Konecny

2
我建议使用Websockets框架,比如Plezi web-app framework,它可以处理websocket连接IO,并通过Redis服务器帮助您在多个进程之间广播数据*。
(*请注意,尽管Redis可以存储数据,但它无法存储对象,也绝对无法存储实时socket)
例如: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.

一个使用Plezi框架的工作聊天服务器可能如下所示*:

* 这只是一个草稿,可以在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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接