我需要水平可扩展的WebSocket连接服务器用于聊天系统,其中连接到不同WebSocket服务器的浏览器客户端可以在单独的聊天室中交换消息 。
Clients HaProxy WebSocket server1 WebSocket server2 Redis/ZeroMQ
| | | |
client A ----=------------>o<----------------|------------------>|
| | | |
client B ----=-------------|---------------->o<----------------->|
| | | |
此处client A
和client B
通过HaProxy
与两个不同的WebSocket servers
相关联,后者通过Redis/ZeroMQ
后端交换邮件,例如that和that个问题。
考虑构建该架构,我想知道是否已经存在开源模拟。你建议看看这样的项目是什么?
答案 0 :(得分:0)
查看Plezi Ruby框架。我是作者,它内置了自动Redis可扩展性。
(您只需使用Redis网址设置ENV['PL_REDIS_URL']
)
至于实现这一目标的架构,它很简单......我认为。
每个服务器实例“订阅”两个频道:用于“广播”的全球频道(发送给所有用户或大型“家庭”用户的消息)和用于“单播”的唯一频道(用于特定用户的消息)连接到服务器)。
每个服务器管理其内部广播系统,以便将消息路由到特定用户,连接家庭或所有用户,与目标受众一样。
您可以找到源代码here。 Redis集成使用this code和websocket object code处理。
使用websocket object on_broadcast callback处理Web套接字广播。 Iodine服务器使用websocket implementation处理每个服务器实例中的内部广播。
我已将内部流程架构详细信息发布为an answer to this question
我认为socket.io也有跨服务器支持。
由于评论,我认为我会添加一些代码......如果你编辑你的问题并添加更多关于你正在寻找的功能的规范,我可以在这里编辑代码。
我正在使用术语“房间”,因为这是你提到的,虽然我没有想到Plezi只是一个“聊天”框架,但它是一个非常简单的用例来展示它的实时能力。
如果您使用的是Ruby,则可以在irb
终端中运行以下命令(确保先安装Plezi):
require 'plezi'
class MultiRoom
def on_open
return close unless params[:room] && params[:name]
@name = params[:name]
puts "connected to room #{params[:room]}"
# # if you use JSON to get room data,
# # you can use room arrays like so:
# params[:room] = params[:room].split(',') unless params[:room].is_a?(Array)
end
def on_message data
to_room = params[:room]
# # if you use JSON you can try:
# to_room = JSON.parse(data)['room'] rescue nil
# # we can use class `broadcast`, to broadcast also to self
MultiRoom.broadcast :got_msg, to_room, data, @name if to_room
end
protected
def got_msg room, data, from
write ::ERB::Util.html_escape("#{from}: #{data}") if params[:room] == room
# # OR, on JSON, with room arrays, try something like:
# write data if params[:room].include?(room)
end
end
class EchoConnection
def on_message data
write data
MultiRoom.broadcast "myroom", "Echo?", "system" if data == /^test/i
end
end
route '/echo', EchoConnection
route '/:name/(:room)', MultiRoom
# # add Redis auto-scaling with:
# ENV['PL_REDIS_URL'] = "redis://:password@my.host:6389/0"
exit # if running in terminal, using irb
你可以通过连接到:ws:// localhost:3000 / nickname / myroom
来测试它连接到多个“房间”(你需要重新编写JSON和多房间的代码),试试:ws:// localhost:3000 / nickname / myroom,your_room
通过连接到ws:// localhost:3000 / echo
来测试回声请注意,echo的行为方式不同,并允许您为不同的关注点设置不同的websockets - 即,使用JSON有一个连接用于更新和消息,另一个用于通过websockets使用原始二进制数据进行多个文件上载。