2011-11-15 14 views
4

私はCowboy websocketサーバーを持っています。私はgen_eventハンドラを登録して、websocketを介して何かを送信したいと考えています。 websocket_handle/3で定期的な同期リクエストに返信できるようにする必要もあります。私はcowboy_http_websocket_handler.erlに何も明白ではなく、cowboy_http_websocket:websocket_send/3はエクスポートされていません。オープンソケットで何かを送る簡単な方法がないのですか?カウボーイとwebsocketで非同期にデータを送信するにはどうすればよいですか?

+2

このトピックに答える最も簡単な方法は、cowboyのgithubで問題を作成し、著者に尋ねることです。 LoïcHoguinは非常に議論の余地があります。 – W55tKQbuRu28Q4xv

答えて

3

the example websocket handlerでは、websocket_info/3はこのようなものを送信するために使用されます。 websocketのinitコードにgen_event:add_sup_handler/3をwebsocket_info/3と組み合わせてください。接続のpidをハンドラの状態に保ち、非同期イベントでメッセージを送信するだけです。

+0

私は長いこと前にこれに答えましたが、私は質問があります...なぜあなたのカウボーイアプリの開始ではなくwebsocketのintコードでイベントハンドラを追加しますか? –

+0

websocketのinitコードは、セッションの設定時に実行されます。カウボーイは一度だけ初期化されます。これは、接続を開くためのメッセージを送信する必要があり、アプリケーションの起動時に将来接続するためのpidはわかりません。それは、最近、カウボーイの新しいバージョンが出てきたので、これは時代遅れかもしれないと言いました。 – nmichaels

+0

私はあなたと同様の問題を抱えており、私はそれを解決した方法を追加しました。私を正しい方向に向けてくれてありがとう。それは、同様の問題に直面している他の人には役に立ちます。 –

2

@nmichaels答えは正しい方向に私を指摘し、私は正常にカウボーイアプリでwebsocket_infoに内部メッセージを送信するためにgen_eventを使用しました。しかし、答えは少し日付で、カウボーイは大きく変わったので、私はそれに追加して、最新のカウボーイバージョンで動作するソリューションを提供したいと思います。うまくいけば、これはErlangとカウボーイに新しいことを助けるでしょう。

カウボーイでgen_eventを実装するために必要な3つのステップ

  • gen_eventを起動して、あなたのハンドラIは、グローバルイベントと呼ば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にし、特定のソケットへの拡張により、メッセージを送信することができます。この方法のようなものに変換することができます。

関連する問題