README.md

# Glock

Glock is a simple websocket client application based on the Gun
HTTP/HTTP2/Websocket Erlang library.

Glock aims to simplify the specific task of starting and configuring
a websocket client connection to a remote server, providing common
default values for all connection settings provided by Gun while still
allowing for full customization.

Glock also provides a set of callbacks for processing messages sent
to and received from the remote server and tracking state across the
life of the connection in whatever way makes sense to your application.
Default callback implementations let you get up and running immediately
for simply sending messages to a server and logging received responses
by implementing the `__using__/1` macro:

Example:

```elixir
  defmodule MySocket do
    use Glock.Socket
  end

  iex> {:ok, conn} = MySocket.start_link(host: "echo.websocket.org", path: "/")
  {:ok, #PID<0.260.0>}
  iex> :ok = MySocket.send(conn, "hello socket!")
```

Implementing the `init_stream/1` callback allows you to create and store
state for the socket connection which can be accessed from subsequent message
send or receive events. A simple example might be to count the number of
messages sent and received from the socket.

Example:

```elixir
  defmodule MySocket do
    use Glock.Socket

    def init_stream(conn: conn, protocols: _, headers: _) do
      %{
        "connection" => conn.stream,
        "sent" => 0,
        "received" => 0
      }
    end
  end
```

Implementing the `handle_send/2` callback allows for customization of the
message frame types and the encoding or serialization performed on messages
prior to sending. Piggy-backing the prior example, a complex data structure
could be serialized to JSON and counted before being sent to the remote server.

Example:

```elixir
  defmodule MySocket do
  ...

    def handle_send(message, state) do
      frame = {:text, JSON.encode(message)}
      new_state = Map.put(state, "sent", state["sent"] + 1)
      {frame, new_state}
    end
  end
```

Finally, implementing the `handle_receive/2` callback allows for custom
handling of messages beyond simply logging them. All messages received
by the gun connection pass through the `handle_receive/2` callback, so you
can decode them, store them, reprocess them or anything else you like.
This handler also covers receiving `:close` control frames and cleaning up/
shutting down the glock process appropriately according to the Websocket
specification.

Example:

```elixir
  defmodule MySocket do
  ...

    def handle_receive(frame, state) do
      case frame do
        {:text, message} ->
          send_to_internal_queue(message)
          new_state = Map.put(state, "received", state["received"] + 1)
          {:doesnt_matter, {:ok, new_state}}
        :close ->
          JSON.encode(state) |> write_to_log_service()
          {:close, {:close, state}}
        _ ->
          {:doesnt_matter, {:ok, state}}
      end
    end
  end
```

## Installation

The package can be installed by adding `glock` to your list
of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:glock, "~> 0.1.0"}
  ]
end
```

The docs can be found at [https://hexdocs.pm/glock](https://hexdocs.pm/glock).