Are there any libraries that can help me build a WebSocket client?

Hello.
I am looking for a library that will help me build a WebSocket client, I’ve found WebSockex but it seems to be abandoned. I just want to build a client that sends and receive information from a server. Any recommendations are appreciated.

1 Like

You could take a look at the implementation of the client side LiveSocket for Phoenix LiveView.

There’s also LiveState and its client side related projects that could be a good option or starting point for reference.

Have a look at GitHub - mtrudel/bandit: Bandit is a pure Elixir HTTP server for Plug & WebSock applications :slight_smile:

Edit: Ooops, you asked for a client… Bandit is a server.


For my last websocket client I used WebSockex.

1 Like

You have the native WebSocket API, and you can setup in the router using websock_adapter, nicely explained by BMilde Websockets. Although no heartbeat, retries…

Thanks for the recommendation.
I am trying WebSockex and getting this error:

{:error,
 %UndefinedFunctionError{
   module: nil,
   function: nil,
   arity: nil,
   reason: nil,
   message: nil
 }}

It doesn’t provide any information, here is my code:

def start_link() do
    WebSockex.start_link("wss://fstream.binance.com/ws/bnbusdt@aggTrade", __MODULE__, nil)
  end

  def handle_frame({type, msg}, state) do
    IO.puts "Received Message - Type: #{inspect type} -- Message: #{inspect msg}"
    {:ok, state}
  end

Thanks for replying, According to the article you provided, that library contains the implementation to upgrade an HTTP connection to a WS connections. I want to directly connect to the wss://... endpoint.

Hard to say what’s happening without a stack trace.

I tried your code and it works:

defmodule WsClient do
  use WebSockex

  def start_link do
    WebSockex.start_link("wss://fstream.binance.com/ws/bnbusdt@aggTrade", __MODULE__, nil)
  end

  def handle_frame({type, msg}, state) do
    IO.puts "Received Message - Type: #{inspect type} -- Message: #{inspect msg}"
    {:ok, state}
  end
end

Result:

iex(4)> WsClient.start_link()
{:ok, #PID<0.224.0>}
Received Message - Type: :text -- Message: "{\"e\":\"aggTrade\",\"E\":1721436649844,\"a\":585965926,\"s\":\"BNBUSDT\",\"p\":\"592.070\",\"q\":\"0.01\",\"f\":1345576048,\"l\":1345576048,\"T\":1721436649691,\"m\":true}"
Received Message - Type: :text -- Message: "{\"e\":\"aggTrade\",\"E\":1721436650734,\"a\":585965927,\"s\":\"BNBUSDT\",\"p\":\"592.080\",\"q\":\"3.92\",\"f\":1345576049,\"l\":1345576064,\"T\":1721436650579,\"m\":false}"
Received Message - Type: :text -- Message: "{\"e\":\"aggTrade\",\"E\":1721436651055,\"a\":585965928,\"s\":\"BNBUSDT\",\"p\":\"592.090\",\"q\":\"0.03\",\"f\":1345576065,\"l\":1345576065,\"T\":1721436650901,\"m\":true}"
Received Message - Type: :text -- Message: "{\"e\":\"aggTrade\",\"E\":1721436652573,\"a\":585965929,\"s\":\"BNBUSDT\",\"p\":\"592.090\",\"q\":\"0.19\",\"f\":1345576066,\"l\":1345576067,\"T\":1721436652419,\"m\":true}"

On a machine with an older Elixir (1.13), in case that makes a difference.

2 Likes

Believe it or not, I forgot the use WebSockex. But in my defense, I just wrote a script that uses HTTPoison without useing it and it worked, which gave me the illusion that mix imports these modules automatically during compilation or interpretation.

Thank you for including it in your code.

use isn’t directly comparable to “imports” in other languages (after all, there’s import/2 already :stuck_out_tongue: ) - it generates code into the module that calls it.

HTTPoison supports two different styles of interaction: plain functions (HTTPoison.get etc) and “wrapping”. Wrapping can be useful when you need to make many similar-shaped requests.

Websockex doesn’t support the plain function approach at all.

2 Likes

Thanks for the insight, I knew skipping parts of the documentation will haunt me someday.