与Misultin Erlang HTTP库上的TCP / IP套接字相关的WebSockets

时间:2012-01-10 13:38:38

标签: erlang websocket misultin

我必须说, 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).
。更多关于此的代码,请查看示例页面。
我有几个问题。

问题1:我可以像通常使用Erlang中的TCP / IP套接字一样更改Web套接字的控制进程吗? (我们通常使用: gen_tcp:controlling_process(Socket,NewProcessId)
问题2: Misultin是唯一支持WebSockets的Erlang / OTP HTTP库吗?其余的在哪里?
编辑: 现在,我需要能够从Misultin转移WebSocket控件 想象一下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的作者可以对此说些什么。感谢所有

3 个答案:

答案 0 :(得分:4)

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

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

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

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

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:2)

Misultin的作者在这里。

我强烈反对你改变控制过程,因为这会破坏所有Misultin的内部。正如史蒂夫建议的那样,YAWS和Cowboy支持WebSockets,并且已经在Mochiweb上完成了实现,但我不知道是否有任何主动维护。

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

  • 由于多核使用导致的性能,如果您使用单个gen_server
  • 则不存在
  • 能够使用'let it crash'理念:目前看起来你的gen_server崩溃会导致所有可用游戏失效
  • ...

Erlang能够在单个VM上处理数十万个进程,在此之前,您将无法使用开放套接字方式的可用文件描述符。

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

显然,我不确定你想要实现的目标,所以我只是假设在这里。但是,如果你的关注是内存 - 好吧,正如下面的TRIAL AND ERROR EXP所说:不要过早地优化某些东西,特别是当你考虑使用Erlang的方式看起来可能实际上限制它做它能够做的事情的。

我的0.02美元。