websocket client

1,029 views
Skip to first unread message

Rajmohan Banavi

unread,
Sep 2, 2015, 3:31:26 PM9/2/15
to elixir-l...@googlegroups.com
How do I implement a websocket client in elixir? I guess cowboy is to be used only on the server end. Any pointers would be appreciated.

Thanks.

Onorio Catenacci

unread,
Sep 3, 2015, 11:25:30 AM9/3/15
to elixir-lang-talk
This seems that it may be worthwhile for you to read over: https://viget.com/extend/websockets-with-elixir-how-to-sync-multiple-clients


--
Onorio

Rajmohan Banavi

unread,
Sep 4, 2015, 3:46:51 AM9/4/15
to elixir-l...@googlegroups.com
Thanks Onorio, for the suggestion. I did look at phoenix but I am not looking for a publish/subscribe sort of functionality nor implement a webapp server. The elixir client app needs to connect to an existing server (not accept ws connections as in phoenix).

One of the ways is to use the websocket_client library (implemented in erlang) and call from elixir. Are there any examples on how to do this?

Cheers,
Rajmohan


--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/ee124c1d-fd45-4ba0-8513-e9722918a716%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Chris McGrath

unread,
Sep 4, 2015, 5:33:32 AM9/4/15
to elixir-l...@googlegroups.com

On 4 Sep 2015, at 08:46, Rajmohan Banavi <rajmoha...@gmail.com> wrote:

One of the ways is to use the websocket_client library (implemented in erlang) and call from elixir. Are there any examples on how to do this?

There’s an elixir slack bot library that uses websocket_client, https://github.com/BlakeWilliams/Elixir-Slack

HTH,

Chris

signature.asc

Dave Cottlehuber

unread,
Sep 5, 2015, 1:45:03 AM9/5/15
to elixir-l...@googlegroups.com
https://github.com/meh/elixir-socket/ ?


Dave Cottlehuber
Skunkwerks, GmbH

Thomas Moulia

unread,
Sep 5, 2015, 3:41:27 PM9/5/15
to elixir-lang-talk
elixir-socket works well, with the caveat that you can't create active socket sort of behaviour without hacking an additional bridge process to listen for and forward on messages. See issue #19. In other words, if you want a process to handle both websocket and Erlang messages you either need the bridge process, or a polling-ish solution.

websocket_client provides a behaviour which provides gen_server-like callbacks for handling incoming websocket and Erlang messages.

Here's another example of using websocket_client from Elixir: https://github.com/MyMedsAndMe/spell/blob/master/lib/spell/transport/websocket.ex

Cheers,
-Thomas

Rajmohan Banavi

unread,
Sep 7, 2015, 2:15:04 AM9/7/15
to elixir-l...@googlegroups.com
Thanks folks.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.

Rajmohan Banavi

unread,
Sep 7, 2015, 3:44:44 AM9/7/15
to elixir-l...@googlegroups.com
I am running into a linking error.

I have a basic app created with mix, added the dependency.
{:websocket_client, github: "sanmiguel/websocket_client" }

And call
:websocket_client.start_link(url, __MODULE__, self, [])

And  have a callback handler
def init(_, _conn_state) do
.....
end

But I get the following undefined error

** (EXIT from #PID<0.88.0>) an exception was raised:
    ** (UndefinedFunctionError) undefined function: WsClean.init/1
        (ws_clean) WsClean.init(#PID<0.88.0>)
        src/websocket_client.erl:147: :websocket_client.init/1
        (stdlib) gen_fsm.erl:378: :gen_fsm.init_it/6
        (stdlib) proc_lib.erl:239: :proc_lib.init_p_do_apply/3

Why is it looking for an init/1 (with 1 parameter). As per the documentation on https://github.com/jeremyong/websocket_client, init/2 should be present. Am I missing anything imp here especially when calling erlang libs from elixir?

Thanks.

Rajmohan Banavi

unread,
Sep 7, 2015, 10:22:17 AM9/7/15
to elixir-l...@googlegroups.com
I have gotten past the issue by having init/1. Though I am curious about reduction in number of params.

Now I am facing issues with sending messages over WS. Can anyone point out as to what I am missing? Below is the iex session. How do I send messages over the established WS connection?

----------------------------------------------------------------

iex(2)> {:ok, sock} = :websocket_client.start_link('ws://echo.websocket.org', WsApp, self, [])
{:ok, #PID<0.99.0>}
iex(3)> send sock, {:send, {:text, 'whatsup'}}
** (EXIT from #PID<0.88.0>) :undef

Interactive Elixir (1.0.5) - press Ctrl+C to exit (type h() ENTER for help)

19:45:40.504 [error] ** Websocket client WsApp terminating in :websocket_info/3
   for the reason :error::undef
** Last message was {:send, {:text, 'whatsup'}}
** Handler state was #PID<0.88.0>
** Stacktrace: [{WsApp, :websocket_info,
  [{:send, {:text, 'whatsup'}},
   {:websocket_req, :ws, 'echo.websocket.org', 80, '/', :infinity, :undefined,
    :undefined,
    {:transport, :gen_tcp, :tcp, :tcp_closed, :tcp_error,
     [:binary, {:active, true}, {:packet, 0}]}, "AKJnDy6AfmlQBu4FLWBxHg==",
    :undefined, :undefined, :undefined, :undefined, :undefined}, #PID<0.88.0>],
  []},

Thomas Moulia

unread,
Sep 8, 2015, 8:00:12 PM9/8/15
to elixir-lang-talk, rajmoha...@gmail.com
Rajmohan, is it possible to see the source code? The init/2 function is the required callback, so something strange is happening, but it's hard to tell exactly what without the source.

Alex Shneyderman

unread,
Sep 10, 2015, 5:59:10 PM9/10/15
to elixir-lang-talk, rajmoha...@gmail.com
cowboy project has sub-project called gun (https://github.com/ninenines/gun). It was lately upgraded to be used as websocket client. it works pretty well - I use it in one of my apps. You will will have to mix erlang and elixir though.

Cheers,
Alex.


On Wednesday, September 2, 2015 at 3:31:26 PM UTC-4, Rajmohan Banavi wrote:

Alex Shneyderman

unread,
Sep 10, 2015, 6:11:28 PM9/10/15
to elixir-lang-talk, rajmoha...@gmail.com
Here is a basic example of gun use - https://gist.github.com/ashneyderman/5eca8b1bed16a7b6f4be. This particular example assumes binary payloads.

Rajmohan Banavi

unread,
Sep 15, 2015, 5:41:11 AM9/15/15
to Alex Shneyderman, elixir-lang-talk
Alex,

I used your example code in a new mix project. And this is the error I am facing with iex. Any pointers on what am I missing?

user@sandbox:~/transport$ iex -S mix
Erlang/OTP 18 [erts-7.0] [source-4d83b58] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.0.5) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Transport.connect(%{ hostname: 'echo.websocket.org', port: 80, connection_timeout: 40, path: ""}) 
** (exit) exited in: :gen_server.call(:gun_sup, {:start_child, [#PID<0.94.0>, 'echo.websocket.org', 80, %{}]}, :infinity)
    ** (EXIT) no process
       (stdlib) gen_server.erl:212: :gen_server.call/3
                src/gun.erl:121: :gun.open/3
    (transport) lib/transport.ex:7: Transport.connect/1
iex(1)>

Alex Shneyderman

unread,
Sep 15, 2015, 11:20:33 AM9/15/15
to elixir-lang-talk, a.shne...@gmail.com, rajmoha...@gmail.com
you need to start gun application

Application.ensure_all_started(:gun)

before doing Transport.connect

I would also wrap transport into a spawn

  spawn(fn() -> Transport.connect(...) end)

Cheers,
Alex.

Rajmohan Banavi

unread,
Sep 22, 2015, 5:36:41 AM9/22/15
to Alex Shneyderman, elixir-lang-talk
Alex,

Thanks, it works well. Sorry for the late reply. Here is an iex sessions dump

est@sandbox:~/test$ iex -S mix
Erlang/OTP 18 [erts-7.0] [source-4d83b58] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.0.5) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> pid = spawn(fn() -> Transport.connect(%{ hostname: 'echo.websocket.org', port: 80, connection_timeout: 4000, path: "/"}) end)
#PID<0.115.0>
iex(2)> send pid, {:send, "Hello world!"}
Transport: sending frame "Hello world!"
{:send, "Hello world!"}
Transport: received: "Hello world!"
iex(3)> 
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution
Reply all
Reply to author
Forward
0 new messages