How do you use Gun as a Cowboy client?

前端 未结 2 1879
一生所求
一生所求 2020-12-21 05:43

I followed the Getting Started instructions for Cowboy, and I\'ve got Cowboy running and listening on port 8080, and I got the Hello Erlang! response when I ent

相关标签:
2条回答
  • 2020-12-21 06:25

    A summary of the issues/suggestions from the comments discussion

    1. For running your Erlang app (in this case including gun as a dependency), you need to have the path to beam and .app files discoverable to the shell. When using erlang.mk, the easiest way to do that would be running the release using make run

    2. On Cowboy side, to have Websocket handled correctly, you need to have a handler defined in your cowboy routes. See example in Cowboy Websocket example

    See also Gun user guide for more details about handling Websocket in Gun

    0 讨论(0)
  • 2020-12-21 06:27

    Success!

    ~/erlang_programs/my_gun/src/my.erl:

    -module(my).
    -compile(export_all).
    
    get() ->
        ...
    
    ws() ->
    
        {ok, _} = application:ensure_all_started(gun),
        {ok, ConnPid} = gun:open("localhost", 8080),
        {ok, _Protocol} = gun:await_up(ConnPid),
    
        gun:ws_upgrade(ConnPid, "/websocket"),
    
        receive
            {gun_ws_upgrade, ConnPid, ok, Headers} ->
                    upgrade_success(ConnPid, Headers);
            {gun_response, ConnPid, _, _, Status, Headers} ->
                    exit({ws_upgrade_failed, Status, Headers});
            {gun_error, _ConnPid, _StreamRef, Reason} ->
                    exit({ws_upgrade_failed, Reason})
            %% More clauses here as needed.
        after 1000 ->
                exit(timeout)
        end,
    
    
    upgrade_success(ConnPid, Headers) ->
        io:format("Upgraded ~w. Success!~nHeaders:~n~p~n", 
                  [ConnPid, Headers]),
    
        gun:ws_send(ConnPid, {text, "It's raining!"}),
    
        receive
            {gun_ws, ConnPid, {text, Msg} } ->
                io:format("~s~n", [Msg])
        end.
    

    On the cowboy side:

    -module(myws_handler).
    -compile(export_all).
    
    init(Req, State) ->
        {cowboy_websocket, Req, State}.  %Perform websocket setup
    
    websocket_handle({text, Msg}, State) ->
        {
         reply, 
         {text, io_lib:format("Server received: ~s", [Msg]) },
         State
        };
    websocket_handle(_Other, State) ->  %Ignore
        {ok, State}. 
    

    Here's the output:

    ~/erlang_programs/my_gun$ gmake run
    gmake[1]: Entering directory '/Users/7stud/erlang_programs/my_gun/deps/gun'
    gmake[2]: Entering directory '/Users/7stud/erlang_programs/my_gun/deps/cowlib'
    gmake[2]: Leaving directory '/Users/7stud/erlang_programs/my_gun/deps/cowlib'
    gmake[2]: Entering directory '/Users/7stud/erlang_programs/my_gun/deps/ranch'
    gmake[2]: Leaving directory '/Users/7stud/erlang_programs/my_gun/deps/ranch'
     GEN    rebar.config
    gmake[1]: Leaving directory '/Users/7stud/erlang_programs/my_gun/deps/gun'
     DEPEND my_gun.d
     ERLC   my.erl
     APP    my_gun
    ===> Starting relx build process ...
    ===> Resolving OTP Applications from directories:
              /Users/7stud/erlang_programs/my_gun/ebin
              /Users/7stud/erlang_programs/my_gun/deps
              /Users/7stud/.evm/erlang_versions/otp_src_19.2/lib/erlang/lib
              /Users/7stud/erlang_programs/my_gun/apps
              /Users/7stud/erlang_programs/my_gun/_rel
    ===> Resolved my_gun_release-1
    ===> rendering builtin_hook_status hook to "/Users/7stud/erlang_programs/my_gun/_rel/my_gun_release/bin/hooks/builtin/status"
    ===> Including Erts from /Users/7stud/.evm/erlang_versions/otp_src_19.2/lib/erlang
    ===> release successfully created!
    ===> tarball /Users/7stud/erlang_programs/my_gun/_rel/my_gun_release/my_gun_release-1.tar.gz successfully created!
    Exec: /Users/7stud/erlang_programs/my_gun/_rel/my_gun_release/erts-8.2/bin/erlexec -boot /Users/7stud/erlang_programs/my_gun/_rel/my_gun_release/releases/1/my_gun_release -mode embedded -boot_var ERTS_LIB_DIR /Users/7stud/erlang_programs/my_gun/_rel/my_gun_release/lib -config /Users/7stud/erlang_programs/my_gun/_rel/my_gun_release/releases/1/sys.config -args_file /Users/7stud/erlang_programs/my_gun/_rel/my_gun_release/releases/1/vm.args -pa -- console
    Root: /Users/7stud/erlang_programs/my_gun/_rel/my_gun_release
    /Users/7stud/erlang_programs/my_gun/_rel/my_gun_release
    heart_beat_kill_pid = 38883
    Erlang/OTP 19 [erts-8.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
    
    
    =PROGRESS REPORT==== 10-Jul-2017::18:04:38 ===
              supervisor: {local,sasl_safe_sup}
                 started: [{pid,<0.353.0>},
                           {id,alarm_handler},
                           {mfargs,{alarm_handler,start_link,[]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]
    
    =PROGRESS REPORT==== 10-Jul-2017::18:04:38 ===
              supervisor: {local,sasl_sup}
                 started: [{pid,<0.352.0>},
                           {id,sasl_safe_sup},
                           {mfargs,
                               {supervisor,start_link,
                                   [{local,sasl_safe_sup},sasl,safe]}},
                           {restart_type,permanent},
                           {shutdown,infinity},
                           {child_type,supervisor}]
    
    =PROGRESS REPORT==== 10-Jul-2017::18:04:38 ===
              supervisor: {local,sasl_sup}
                 started: [{pid,<0.354.0>},
                           {id,release_handler},
                           {mfargs,{release_handler,start_link,[]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]
    
    =PROGRESS REPORT==== 10-Jul-2017::18:04:38 ===
             application: sasl
              started_at: 'my_gun@127.0.0.1'
    
    =PROGRESS REPORT==== 10-Jul-2017::18:04:38 ===
              supervisor: {local,runtime_tools_sup}
                 started: [{pid,<0.360.0>},
                           {id,ttb_autostart},
                           {mfargs,{ttb_autostart,start_link,[]}},
                           {restart_type,temporary},
                           {shutdown,3000},
                           {child_type,worker}]
    
    =PROGRESS REPORT==== 10-Jul-2017::18:04:38 ===
             application: runtime_tools
              started_at: 'my_gun@127.0.0.1'
    Eshell V8.2  (abort with ^G)
    
    (my_gun@127.0.0.1)1> my:ws().
    
    =PROGRESS REPORT==== 10-Jul-2017::18:04:41 ===
              supervisor: {local,inet_gethost_native_sup}
                 started: [{pid,<0.367.0>},{mfa,{inet_gethost_native,init,[[]]}}]
    
    =PROGRESS REPORT==== 10-Jul-2017::18:04:41 ===
              supervisor: {local,kernel_safe_sup}
                 started: [{pid,<0.366.0>},
                           {id,inet_gethost_native_sup},
                           {mfargs,{inet_gethost_native,start_link,[]}},
                           {restart_type,temporary},
                           {shutdown,1000},
                           {child_type,worker}]
    Upgraded <0.365.0>. Success!
    Headers:
    [{<<"connection">>,<<"Upgrade">>},
     {<<"date">>,<<"Tue, 11 Jul 2017 00:04:40 GMT">>},
     {<<"sec-websocket-accept">>,<<"pYv8QeeJfzQgaS/x8flZHyrIexk=">>},
     {<<"server">>,<<"Cowboy">>},
     {<<"upgrade">>,<<"websocket">>}]
    Server received: It's raining!
    ok
    
    (my_gun@127.0.0.1)2> 
    
    0 讨论(0)
提交回复
热议问题