1

我必须说我对Misultin对 Web Sockets 的支持印象深刻(这里有一些例子)。我的 JavaScript 正在以“可忽略的”延迟或滞后发出请求并通过网络获取响应,太好了!

看看 WebSockets 的数据处理程序循环的样子,它类似于普通的 TCP/IP 套接字,至少是 Erlang 中的基本方式

% 回调收到的 websockets 数据
handle_websocket(Ws) ->
    收到
        {浏览器,数据} ->
            ws:send(["received '", Data, "'"]),
            handle_websocket(Ws);
        _忽略->
            handle_websocket(Ws)
    5000 之后 ->
        ws:send("推!"),
        handle_websocket(Ws)
    结尾。

这段代码在由 Misultin 生成的进程中执行,这是您在启动服务器时为其提供的功能,如下所示:

开始(端口)->
    HTTPHandler = fun(Req) -> handle_http(Req, Port) 结束,
    WebSocketHandler = fun(Ws) -> handle_websocket(Ws)结束,
    选项 = [{port, Port},{loop, HTTPHandler},{ws_loop, WebSocketHandler}],
    misultin:start_link(选项)。
. 有关此的更多代码,请查看示例页面。
我有几个问题。

问题 1:我可以像我们通常在 Erlang 中使用 TCP/IP 套接字一样更改 Web 套接字的控制进程吗?(我们通常使用gen_tcp:controlling_process(Socket,NewProcessId):)
问题 2: Misultin是唯一支持 WebSockets 的 Erlang/OTP HTTP 库吗?其余的在哪里?
编辑: 现在,我需要能够从 Misultin 传输 WebSocket 控件的原因
想一想gen_server将控制 WebSocket 池的一个,比如它是一个游戏服务器。在当前的 Misultin 示例中,对于每个 WebSocket 连接,都有一个控制进程,换句话说,对于每个 WebSocket,都会有一个衍生进程。现在,我知道 Erlang 是 Processes 的英雄,但是,我不希望这样,我希望这些初始进程在处理到我gen_server的 WebSocket 控制权限后立即终止。
我希望这gen_server可以在这些 WebSocket 之间切换数据。在当前的实现中,我需要Pid像这样跟踪 Misultin 的 handle_websocket 进程:

%% 这里是misultin的控制流程
%% 我得到它的 Pid 并将它保存在某个地方
%% 并将其链接到 my_gen_server 以便
%% 如果它退出我知道它已经消失了

handle_websocket(Ws)->
    process_flag(trap_exit,true),
    PID =自我(),
    链接(my_gen_server),
    保存连接(PID),
    等待消息(WS)。

wait_msgs(Ws)->
    收到
        {浏览器,数据}->
            FromPid = self(),
            send_to_gen_server(数据,FromPid),
            handle_websocket(Ws);
        {广播,消息} ->
            %% 我可以广播到所有连接的 WebSockets      
            ws:发送(消息),
            handle_websocket(Ws);
        _Ignore -> handle_websocket(Ws)  
    结尾。

上面,这个想法非常有效,我将所有控制过程保存到 Mnesia Ram 表中,如果应用程序想要向该特定用户发送消息,则根据给定标准查找它。但是,根据我想要实现的目标,我意识到在现实世界中,进程可能太多以至于我的服务器可能会崩溃。我希望至少有一个gen_server来控制数千个 Web Socket,而不是为每个 Web Socket 拥有一个进程,这样,我可以节省一些内存。

建议: Misultin 的作者可以在他的下一个版本中为我们创建 Web Socket Groups 实现,从而我们可以让一组 WebSockets 由同一进程控制。这将类似于Nitrogen's Comet Groups其中彗星连接在同一控制下组合在一起。如果这不可能,我们将需要自己进行控制,提供一个 API,我们可以在其中接管这些 Web 套接字的控制。

工程师们对此有何看法?
您对此有何建议和/或评论?

米苏尔廷的作者可以对此说些什么。谢谢大家

4

3 回答 3

4

(一)牛仔开发者在这里。

我不建议使用任何类型的中央服务器来负责控制一组 websocket 连接。主要原因是这是一个过早的优化,您只是在推测内存使用情况。

去年早些时候对单个服务器上的 50 万个 websocket 连接进行的测试导致 misultin 使用 20GB 内存,cowboy 使用 16.2GB 或 14.3GB,具体取决于 websocket 进程是否处于休眠状态。您可以假设 websocket 的所有 erlang 实现都非常接近这些数字。

不使用 hibernate 和 misultin 的牛仔之间的区别应该非常接近每个连接使用额外进程的内存开销。(请随时在此 ostinelli 上纠正我)。

我敢打赌,在购买服务器时考虑到这一点要比在任务/资源和流程之间没有 1:1 映射的应用程序中设计和解决问题要便宜得多。

https://twitter.com/#!/nivertech/status/114460039674212352

于 2012-01-11T21:08:40.197 回答
2

不确定问题 1,但关于问题 2,YawsCowboy也支持 WebSockets。

于 2012-01-10T19:51:24.943 回答
2

米苏尔廷的作者在这里。

我强烈建议您不要更改控制过程,因为这会破坏 Misultin 的所有内部结构。正如史蒂夫建议的那样,YAWS 和 Cowboy 支持 WebSockets,并且在Mochiweb上完成了一些实现,但我不知道有任何被积极维护。

您正在讨论内存问题,但我认为您正在混合概念。我无法理解为什么您确实需要从 gen_server 集中控制所有内容:您认为“许多进程会使您的 VM 崩溃”的假设实际上是错误的,Erlang 是建立在参与者模型之上的,这有很多优点:

  • 如果您使用单个 gen_server,则由于多核使用而导致的性能不存在
  • 能够使用“让它崩溃”的理念:目前看起来你的 gen_server 崩溃会导致所有可用的游戏崩溃
  • ...

Erlang 能够在单个 VM 上处理数十万个进程,并且在此之前,您的打开套接字的可用文件描述符将用完。

因此,我建议您考虑将游戏逻辑放在各个 Websocket 进程中,并使用消息传递使它们交互。例如,您可以考虑生成包含单个游戏参与者和状态信息的“游戏进程”。最终,一个 gen_server 会跟踪可用的游戏 - 并且仅执行操作(最终通过拥有 ETS 表)。这就是我可能想要的方式,所有这些都具有适当的主管结构。

显然,我不确定你想要达到什么目的,所以我只是在这里假设。但是,如果您关心的是内存 - 好吧,正如 TRIAL AND ERROR EXP 在下面所说的那样:不要过早地优化某些东西,尤其是当您考虑以一种看起来实际上可能会限制它执行能力的方式使用 Erlang 时的。

我的 0.02 美元。

于 2012-01-11T03:26:32.063 回答