我必须说, Misultin's 对Web套接字的支持(一些示例 here )给我留下了深刻的印象。我的JavaScript正在发送请求并通过“微不足道”的延迟或延迟获得响应,Great !!
看看WebSockets的数据处理程序循环是怎样的,它类似于普通的TCP / IP套接字,至少是Erlang的基本方式
% callback on received websockets data handle_websocket(Ws) -> receive {browser, Data} -> Ws:send(["received '", Data, "'"]), handle_websocket(Ws); _Ignore -> handle_websocket(Ws) after 5000 -> Ws:send("pushing!"), handle_websocket(Ws) end.
这段代码是在Misultin产生的过程中执行的,Misultin是一个在启动服务器时给它的函数,如下所示:
start(Port)-> HTTPHandler = fun(Req) -> handle_http(Req, Port) end, WebSocketHandler = fun(Ws) -> handle_websocket(Ws) end, Options = [{port, Port},{loop, HTTPHandler},{ws_loop, WebSocketHandler}], misultin:start_link(Options).。更多关于此的代码,请查看示例页面。
gen_tcp:controlling_process(Socket,NewProcessId)
)gen_server
将控制一个WebSockets池,比如它的游戏服务器。在当前的Misultin示例中,对于每个WebSocket连接,都有一个控制进程,换句话说,对于每个WebSocket,都会有一个生成的进程。现在,我知道Erlang是一个有进程的英雄但是,我不想要这个,我希望这些初始进程一旦处理到我的gen_server
WebSocket的控制权限就会死掉。gen_server
能够在这些WebSockets之间切换数据。在当前的实现中,我需要像这样跟踪Misultin handle_websocket进程的Pid
:
%% Here is misultin's control process %% I get its Pid and save it somewhere %% and link it to my_gen_server so that %% if it exits i know its gone handle_websocket(Ws)-> process_flag(trap_exit,true), Pid = self(), link(my_gen_server), save_connection(Pid), wait_msgs(Ws). wait_msgs(Ws)-> receive {browser,Data}-> FromPid = self(), send_to_gen_server(Data,FromPid), handle_websocket(Ws); {broadcast,Message} -> %% i can broadcast to all connected WebSockets Ws:send(Message), handle_websocket(Ws); _Ignore -> handle_websocket(Ws) end.
上面,这个想法非常有效,我将所有控制过程保存到Mnesia Ram Table中,如果应用程序想要向该特定用户发送消息,则根据给定标准查找它。然而,根据我想要实现的目标,我意识到在现实世界中,流程可能太多,以至于我的服务器可能会崩溃。我想要至少一个gen_server
来控制数千个Web套接字,而不是每个Web Socket都有一个进程,这样,我可以节省一些内存。
建议: Misultin的作者可以在他的下一个版本中为我们创建Web套接字组实现,我们可以让一组WebSockets由同一个进程控制。这与Nitrogen's Comet Groups
类似,其中彗星连接在同一控件下组合在一起。如果这可能,我们将需要自己的控件,提供一个API,我们可以接管这些Web套接字的控制。
您的工程师对此有何看法?
您对此有何建议和/或评论?
Misultin的作者可以对此说些什么。感谢所有
答案 0 :(得分:4)
(一)牛仔开发者在这里。
我不建议使用任何类型的中央服务器负责控制一组websocket连接。主要原因是这是一个不成熟的优化,你只是在猜测内存使用情况。
去年早些时候在一台服务器上进行了50万个websocket连接的测试导致使用20GB内存的误报,使用16.2GB或14.3GB的牛仔,这取决于websocket进程是否处于休眠状态。您可以假设websockets的所有erlang实现都非常接近这些数字。
不使用hibernate和misultin的牛仔之间的区别应该非常接近每个连接使用额外进程的内存开销。 (随意在这个ostinelli上纠正我。)
我愿意打赌,在购买服务器时考虑这一点要比设计和解决在任务/资源和流程之间没有1:1映射的应用程序中的问题要便宜得多
答案 1 :(得分:2)
答案 2 :(得分:2)
Misultin的作者在这里。
我强烈反对你改变控制过程,因为这会破坏所有Misultin的内部。正如史蒂夫建议的那样,YAWS和Cowboy支持WebSockets,并且已经在Mochiweb上完成了实现,但我不知道是否有任何主动维护。
您正在讨论内存问题,但我认为您正在混合概念。我无法理解为什么你需要从gen_server“集中”控制所有内容:你假设“许多进程会崩溃你的虚拟机”实际上是错误的,Erlang建立在actor的模型之上,这有很多优点:
Erlang能够在单个VM上处理数十万个进程,在此之前,您将无法使用开放套接字方式的可用文件描述符。
因此,我建议您考虑将您的游戏逻辑放在单个Websocket进程中,并使用消息传递使它们进行交互。例如,您可以考虑产生“游戏过程”,其中包含单个游戏参与者和状态的信息。最终,gen_server跟踪可用的游戏 - 并且只做那个(最终通过拥有一个ETS表)。这就是我可能想要的方式,所有这些都有适当的主管结构。
显然,我不确定你想要实现的目标,所以我只是假设在这里。但是,如果你的关注是内存 - 好吧,正如下面的TRIAL AND ERROR EXP所说:不要过早地优化某些东西,特别是当你考虑使用Erlang的方式看起来可能实际上限制它做它能够做的事情的。
我的0.02美元。