Skip to content

jan-schreib/ws_client

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WsClient

A websocket client that uses websocat via a Port. In case of a crash of websocat it will be restarted and submit the same commands as before to get back to the state before the crash.

Dependencies

If

iex> System.find_executable("websocat")

returns a valid path you are good to go!

Installation

def deps do
  [
    {:ws_client, "~> 0.1.0"}
  ]
end

Usage

Without a supervisor

# create callback on how to handle the received data from the server
cb = fn data -> data |> IO.inspect end
# the server to connect to
url = "wss://echo.websocket.org"

# start the worker (GenServer)
{:ok, _} =
  GenServer.start_link(WsClient.Worker, %{cb: cb, url: url, port: "", commands: []}, name: EchoWorker)

# send from the client to the server, the callback defined above will handle the answer message.
WsClient.send(TestWorker, "hi\n")

With a supervisor (single worker)

def start(_type, _args) do
  children = [
    {WsClient.Worker,
     args: %{
       cb: &IO.inspect/1,
       url: "wss://echo.websocket.org",
       port: "",
       commands: []
     },
     name: EchoWorker}
  ]

  opts = [strategy: :one_for_one, name: Test.Supervisor]
  Supervisor.start_link(children, opts)
end

With a supervisor (and multiple workers)

This may be useful in case you want to connect to multiple websocket endpoints at the same time.

@impl true
def start(_type, _args) do
  children = [
    Supervisor.child_spec(
      {WsClient.Worker,
       args: %{
         cb: &IO.inspect/1,
         url: "wss://echo.websocket.org",
         port: "",
         commands: []
       },
       name: FirstWorker},
      id: :my_worker_1
    ),
    Supervisor.child_spec(
      {WsClient.Worker,
       args: %{
         cb: &IO.inspect/1,
         url: "wss://echo.websocket.org",
         port: "",
         commands: []
       },
       name: SecondWorker},
      id: :my_worker_2
    )
  ]

  opts = [strategy: :one_for_one, name: Test.Supervisor]
  Supervisor.start_link(children, opts)
end

Usage

After the connection you can use

WsClient.send(pid, message)

to send a message to the web server you are connected to, e.g.

WsClient.send(TestWorker, "hi\n")

To change the handling callback at runtime use

WsClient.callback(pid, fun)

Example with Elixir 1.18 and the new internal JSON function:

cb = fn data -> JSON.decode(data) end
WsClient.callback(Worker, cb)

To close the port (will otherwise be handled automatically on exit of the GenServer)

WsClient.disconnect(pid)

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages