Erlang 如何使用Cowboy通过websocket异步发送数据?

Erlang 如何使用Cowboy通过websocket异步发送数据?,erlang,websocket,cowboy,Erlang,Websocket,Cowboy,我有一个websocket服务器,我想注册一个通过websocket发送内容的处理程序。我还需要能够使用websocket\u handle/3回复定期同步请求。我在中没有看到任何明显的内容,也没有导出。我是否缺少通过开放式套接字发送内容的简单方法?在中,websocket\u info/3用于发送类似的内容。将websocket的初始代码与websocket_info/3合并。将连接的pid保持在处理程序的状态,只发送一条包含异步事件的消息。@nmichaels answer为我指明了正确的方

我有一个websocket服务器,我想注册一个通过websocket发送内容的处理程序。我还需要能够使用
websocket\u handle/3
回复定期同步请求。我在中没有看到任何明显的内容,也没有导出。我是否缺少通过开放式套接字发送内容的简单方法?

在中,websocket\u info/3用于发送类似的内容。将websocket的初始代码与websocket_info/3合并。将连接的pid保持在处理程序的状态,只发送一条包含异步事件的消息。

@nmichaels answer为我指明了正确的方向,我在一个牛仔应用程序中成功地使用gen_事件将内部消息发送到websocket_信息。但是答案有点过时,牛仔已经改变了很多,所以我想补充一下,并提供一个在最新牛仔版本上工作的解决方案。希望这将有助于一些新的二郎和牛仔

在《牛仔》中实施gen_活动需要三个步骤

  • 启动gen_事件并注册处理程序

    start(_Type, _Args) ->
    Dispatch = cowboy_router:compile(wrinqle_routes:routes_configuration()),
    {ok, _} = cowboy:start_http(http, 100, [{port, 3000}],
                                [{env, [{dispatch, Dispatch}]}]),
      pg2:start(),
    
      gen_event:start({global,my_events}),
      gen_event:add_handler({global,my_events},my_event_handler,[]).
    
在这里,我已全局注册了名为my_events的事件(注意:您也可以在本地注册事件),并在模块my_event_handler中添加了处理程序

  • 创建一个事件处理程序

  • 现在,您可以从cowboy中的任何位置通知事件处理程序。例如,下面的代码从websocket_处理程序引发事件

    { _,_ }->
    
       gen_event: notify(global:whereis_name(my_events),{event_name,self()}),
        {ok,Req,State};
    
这段代码所做的只是全局通知在my_events下注册的事件。就这样

OP遇到的另一个问题是如何向打开的连接发送消息,以及初始化时pid未知的连接。要解决这个问题,您可以使用通道下的哪个寄存器进程id。它是管理PIDs的一个非常有用的模块。所以上面的代码可以转换成这样

  [H|T] = pg2:get_members(Name)
  gen_event: notify(global:whereis_name(my_events),{event_name, H}).

通过这种方式,您可以将消息发送到特定的pid,并通过扩展发送到特定的套接字

回答这个问题最简单的方法是在cowboy'sGitHub上创建一个问题并询问作者。洛伊克·霍金非常愿意讨论。我知道你很久以前就回答了这个问题,但我有一个问题。。。为什么要在websocket的int代码中添加事件处理程序,而不是在cowboy应用程序的开头添加事件处理程序?设置会话时会运行websocket的init代码。牛仔只初始化一次。这需要向打开的连接发送消息,并且在应用程序启动时不知道未来连接的PID。这就是说,一个新版本的牛仔最近出来了,所以这可能是过时的。我有一个类似的问题,你的,我已经添加了我解决它的方法。谢谢你给我指明了正确的方向。它可能对其他面临类似问题的人有用。