问题描述
构建服务器以通过websocket接收传入连接,并将在该套接字中流动的数据流传输到其他websocket上的n
订户的最简单方法是什么?以流应用程序为例,其中一个人正在向n
消费者广播.
What would be the simplest way to build a server that receives incoming connections via a websocket, and streams the data flowing in that socket out to n
subscribers on other websockets. Think for example of a streaming application, where one person is broadcasting to n
consumers.
忽略身份验证之类的东西,构建可以实现此目的的服务器的最简单方法是什么?我对当大块数据到达服务器时会发生什么感到困惑.它将进入内存中的缓冲区,然后如何将其分配给等待它的n
使用者?某种循环缓冲区? websockets是否适合此协议?谢谢.
Neglecting things like authentication, what would be the simplest way to build a server that can achieve this? I'm a little confused about what would happen when a chunk of data hits the server. It would go into a buffer in memory, then how would it be distributed to the n
consumers waiting for it? Some sort of circular buffer? Are websockets an appropriate protocol for this? Thanks.
推荐答案
这里是使用Ruby Plezi框架(我是作者,所以有偏见):
Here's one using the Ruby Plezi framework (I'm the author, so I'm biased):
require 'plezi'
class Client
# Plezi recognizes websocket handlers by the presence of the
# `on_message` callback.
def on_message data
true
end
protected
# this will be out event.
def publish data
write data
end
end
class Streamer
def on_message data
Client.broadcast :publish, data
end
end
# the streamer will connect to the /streamer path
route '/streamer', Streamer
# the client will connect to the /streamer path
route '/', Client
# on irb, we start the server by exiting the `irb` terminal
exit
您可以使用Ruby终端(irb
)对其进行测试-就这么简单.
You can test it with the Ruby terminal (irb
) - it's that simple.
我使用了带有两个浏览器窗口的 Websocket.org回声测试来测试连接,其中一个流"和其他监听.
I tested the connections using the Websocket.org echo test with two browser windows, one "streaming" and the other listening.
-
使用ws://localhost:3000/streamer进行流媒体websocket连接
use ws://localhost:3000/streamer for the streamer websocket connection
使用ws://localhost:3000/建立客户端连接.
use ws://localhost:3000/ for the client's connection.
魔术发生在IO内核中,我将其放置在名为碘.
The magic happens in the IO core, which I placed in a separate Ruby gem (Ruby libraries are referred to as 'gems') called Iodine.
碘利用Ruby的面向对象方法(在Ruby中,所有对象都是对象)来处理广播.
Iodine leverages Ruby's Object Oriented approach (in Ruby, everything is an object) to handle broadcasting.
一个很好的切入点,用于挖掘那段代码在这里.遇到方法each
时,请注意它是从核心协议,并使用从 IO地图.
A good entry point for digging through that piece of the code is here. When you encounter the method each
, note that it's inherited from the core Protocol and uses an Array derived from the IO map.
碘的websocket实现遍历IO处理程序数组(key=>value
映射的value
一半),如果IO处理程序是Websocket,它将通过.回调是异步调用的在执行时锁定IO处理程序,以避免冲突.
Iodine's websocket implementation iterates through the array of IO handlers (the value
half of a key=>value
map), and if the IO handler is a Websocket it will "broadcast" the message to that IO handler by invoking the on_broadcst
callback. The callback is invoked asynchronously and it locks the IO handler while being executed, to avoid conflicts.
Plezi 利用碘的broadcast
方法并使用相同的概念,因此 on_broadcast
回调将过滤掉不相关的消息.
Plezi leverages Iodine's broadcast
method and uses the same concept so that the on_broadcast
callback will filter out irrelevant messages.
出于性能方面的考虑,单播的工作方式略有不同,但大多类似.
Unicasting works a little bit differently, for performance reasons, but it's mostly similar.
我很抱歉在我的代码中使用了很多速记...我猜是在使用Ruby之前的习惯.我经常使用condition ? when_true : when_false
速记,并且倾向于将内容压缩成一行...但是它应该可读性强.
I'm sorry for using a lot of shorthand in my code... pre-Ruby habits I guess. I use the condition ? when_true : when_false
shorthand a lot and tend to squish stuff into single lines... but it should be mostly readable.
祝你好运!
这篇关于服务器体系结构:websocket多播服务器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!