2011-11-15 4 views
4

나는 Cowboy websocket 서버를 가지고 있으며 gen_event 핸들러를 등록하여 websocket을 통해 뭔가를 보내고 싶습니다. 또한 websocket_handle/3으로 정규 동기 요청에 응답 할 수 있어야합니다. cowboy_http_websocket_handler.erl에서 아무 것도 보이지 않았고 cowboy_http_websocket:websocket_send/3을 내보낼 수 없습니다. 내가 오픈 소켓을 통해 뭔가를 보낼 수있는 쉬운 방법을 놓치고 있습니까?카우보이와 웹 소켓을 통해 비동기 적으로 데이터를 보내려면 어떻게해야합니까?

+2

이 주제에 답하는 가장 쉬운 방법은 cowboy의 github에서 질문하고 작성자에게 질문하는 것입니다. Loïc Hoguin은 토론의 장이 열려 있습니다. – W55tKQbuRu28Q4xv

답변

3

the example websocket handler에서 websocket_info/3은 이와 같은 자료를 보내는 데 사용됩니다. websocket_info/3을 사용하여 websocket의 초기화 코드에 gen_event:add_sup_handler/3을 결합하십시오. 연결의 pid를 핸들러의 상태로 유지하고 비동기 이벤트와 함께 메시지를 보냅니다.

+0

오래 전이 답변을 알고 있지만 질문이 있습니다 ... 왜 당신은 카우보이 응용 프로그램의 시작이 아니라 websocket의 int 코드에 이벤트 처리기를 추가합니까? –

+0

세션이 설정되면 websocket의 초기화 코드가 실행됩니다. 카우보이는 한 번만 초기화됩니다. 이 연결을 열려면 메시지를 보내야하며, 응용 프로그램을 시작할 때 미래 연결에 대한 pid 알 수 없습니다. 즉, 새로운 버전의 카우보이가 출시되었으므로 이것이 쓸모 없게 될 수도 있습니다. – nmichaels

+0

나는 너와 비슷한 문제가 있었는데 해결 방법을 추가했다.나를 올바른 방향으로 가리켜 주셔서 감사합니다. 비슷한 문제에 직면 한 다른 사람에게 유용 할 수 있습니다. –

2

@nmichaels 대답은 올바른 방향으로 나를 가리켰다. 그리고 나는 내부 메시지를 websocket_info에 보내는 카우보이 앱에서 gen_event를 성공적으로 사용했다. 그러나 대답은 약간 날짜가 나고 카우보이가 많이 바뀌었기 때문에 최신 카우보이 버전에서 작동하는 솔루션을 추가하고 싶습니다. 다행히도 이것은 얼랑 (Erlang)과 카우보이에 새로운 도움이되기를 바랍니다.

카우보이의 gen_event을 구현하기 위해 필요한 세 가지 단계

  • gen_event를 시작하고 당신이 핸들러 나는 세계적으로 이벤트라고 my_events를 등록한 다음

    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,[]). 
    

등록이 있습니다 (참고 : 로컬에서도 이벤트를 등록 할 수 있습니다.) 모듈에 핸들러를 추가했습니다.

  • 이벤트 처리기를 만듭니다.

  • 이제 이벤트 처리기에 카우보이의 모든 위치에서 이벤트를 알릴 수 있습니다. 예를 들어 아래 코드는 websocket_handler

    { _,_ }-> 
    
        gen_event: notify(global:whereis_name(my_events),{event_name,self()}), 
        {ok,Req,State}; 
    

이 모든 코드는 전 세계적으로 이벤트의 my_events에 등록 이벤트를 통지한다하고있다에서 이벤트를 발생시킵니다. 그게 전부 야.

OP에 문제가있는 또 다른 문제는 초기화 할 때 pid를 알 수없는 연결 및 연결을 여는 메시지를 보내는 방법이었습니다. 이 문제를 해결하기 위해 채널 아래에 프로세스 ID를 등록하는 pg2을 사용할 수 있습니다. PID 관리를위한 매우 유용한 모듈입니다. 그래서 위의 코드는이

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

같은 것을로 변환 할 수 있습니다 그리고이 방법은 특정 소켓에 특정 PID와에 의해 확장에 메시지를 보낼 수 있습니다.

관련 문제