我必须说,我对Misaltin对Web套接字的支持印象深刻(这里的一些例子)。我的JavaScript正在以"微不足道"的延迟或滞后触发请求并获得响应,太棒了!!
看看WebSockets的数据处理程序循环是什么样子的,它类似于普通TCP/IP套接字,至少是Erlang 中的基本方式
%对接收到的websockets数据的回调handle_websocket(W)->接收{浏览器,数据}->Ws:send(["received",Data,"'"]),handle_websocket(W);_忽略->handle_websocket(W)5000之后->Ws:send("推!"),handle_websocket(W)终止
这段代码是在Misultin派生的进程中执行的,Misultin是您在启动服务器时赋予它的一个函数,如下所示:
启动(端口)->HTTPHandler=fun(Req)->handle_http(请求,端口)端,WebSocketHandler=乐趣(W)-> handle_ websocket(Ws)结束,选项=[{port,port},{loop,HTTPHandler},{ws_loop,WebSocketHandler}],误用:start_link(选项)。。关于这方面的更多代码,请查看示例页面
我有几个问题
问题1:我可以像通常在Erlang中使用TCP/IP套接字那样更改Web套接字的控制进程吗?(我们通常使用:
gen_tcp:controlling_process(Socket,NewProcessId)
)问题2:误用是唯一支持WebSockets的Erlang/OTP HTTP库吗?剩下的在哪里?
编辑:现在,我需要能够从Misultin
传输WebSocket控件的原因想象一个
gen_server
,它将控制一个WebSocket池,比如说它是一个游戏服务器。在当前的误用示例中,对于每个WebSocket连接,都有一个控制进程,换句话说,对于每个WebService,都会有一个派生进程。现在,我知道Erlang是进程的英雄,但我不希望这样,我希望这些初始进程在处理到我的gen_server
(WebSocket的控制权限)时立即死亡我希望这个
gen_server
能够在这些WebSocket之间切换数据。在当前的实现中,我需要跟踪误用handle_websocket进程的Pid
,如下所示:
%%以下是误用的控制过程%%我拿到它的Pid并把它保存在某个地方%%并将其链接到my_gen_server,以便%%如果它离开了,我知道它不见了handle_websocket(W)->process_flag(trap_exit,true),Pid=self(),链接(my_gen_server),save_connection(Pid),wait_msgs(W)。wait_msgs(Ws)->接收{browser,Data}->FromPid=self(),send_to_gen_server(数据,FromPid),handle_websocket(W);{广播,消息}->%%我可以向所有连接的WebSocket广播Ws:send(Message),handle_websocket(W);_忽略->handle_websocket(W)终止
如上所述,这个想法非常有效,我将所有控制过程保存到Mnesia Ram表中,如果应用程序想向特定用户发送消息,则根据给定的标准进行查找。然而,对于我想要实现的目标,我意识到在现实世界中,流程可能太多,以至于我的服务器可能会崩溃。我希望至少有一个gen_server
来控制数千个Web套接字,而不是为每个Web套接字都有一个进程,这样,我可以了解如何节省内存
建议:Misultin的作者可以在他的下一个版本中为我们创建Web套接字组实现,这样我们就可以由同一进程控制一组WebSocket。这将类似于Nitrogen's Comet Groups
,其中彗星连接在相同的控制下分组在一起。如果这不可能,我们将需要自己的控制,提供一个API,我们可以接管这些Web套接字的控制。
你们工程师对此有何看法
您对此有何建议和/或意见
《误用》的作者可以对此发表一些看法。感谢所有
(一)牛仔开发者。
我不建议使用任何类型的中央服务器来控制一组websocket连接。主要原因是这是一个过早的优化,你只是在猜测内存的使用情况。
去年早些时候,一项针对单个服务器上50万个websocket连接的测试导致了使用20GB内存的误用,牛仔使用16.2GB或14.3GB,这取决于websocket进程是否处于休眠状态。您可以假设websocket的所有erlang实现都非常接近这些数字。
牛仔不使用hibernate和误用之间的区别应该非常接近于每个连接使用额外进程的内存开销。(请随时纠正我的错误)。
我敢打赌,在购买服务器时考虑这一点要比在应用程序中设计和解决问题便宜得多,因为在应用程序的任务/资源和流程之间没有1:1的映射。
https://twitter.com/#/nivertech/status/114460039674212352
此处为误用的作者。
我强烈反对你改变控制过程,因为这会破坏Misultin的所有内部结构。正如Steve所建议的,YAWS和Cowboy支持WebSockets,并且有一些实现是通过Mochiweb完成的,但我不知道有任何实现是积极维护的。
你在讨论记忆问题,但我认为你在混淆概念。我不明白为什么你需要从一个gen_server"集中"控制一切:你认为"许多进程会使你的VM崩溃"的假设实际上是错误的,Erlang是建立在actor的模型之上的,这有很多优点:
- 由于多核使用而导致的性能,如果使用单个gen_server,则不会出现这种情况
- 能够使用"让它崩溃"的理念:目前看来,你的gen_server崩溃会导致所有可用的游戏瘫痪
Erlang能够在一个虚拟机上处理数十万个进程,在此之前,您将无法使用开放套接字的可用文件描述符。
因此,我建议您考虑将您的游戏逻辑包含在各个Websocket进程中,并使用消息传递使它们进行交互。例如,你可以考虑生成"游戏进程",其中包含单个游戏参与者和状态的信息。最终,一个跟踪可用游戏的gen_server,并且只执行(最终通过拥有ETS表)。这可能是我想走的路,所有这些都有合适的主管结构。
很明显,我不确定你想要实现什么,所以我只是假设一下。但是,如果你关心的是内存,那么,正如下面的TRIAL AND ERROR EXP所说:不要过早地优化某些东西,尤其是当你考虑使用Erlang的方式看起来可能会限制它做它能做的事情时。
我的0.02美元。
不确定问题1,但关于问题2,Yaws和Cowboy也支持WebSockets。