Websocket Handler

Websocket Handler is a macro-based approach to handling WebSocket connections in a Plug-based Elixir application. It also serves a JavaScript WebSocket client at a specific endpoint, making it easy to integrate WebSocket communication into web applications.

Websocket.Handler

Module allows you to define WebSocket routes and event handlers using a simple, macro-based syntax. It automatically serves the JavaScript WebSocket client at the /ws/client.js endpoint.

Usage

To use Websocket.Handler, you need to include it in your application’s router module and define event handlers using the provided macros.

defmodule MyWebsocketRouter do
  use Websocket.Handler

  on(:connect) do
    IO.puts("Client connected")
  end

  on(:disconnect) do
    IO.puts("Client disconnected")
  end

  on(:json) do
    IO.puts("Received JSON: #{inspect(conn.json)}")
  end

  on(:file) do
    # Save the file to disk or process it
    IO.puts("Received file")
  end

  on(:message) do
    # Message is just plain text.
    IO.puts("Received message: #{conn.message}")
  end
end

Then in your Plug router, simply forward your websocket route to your handler.

defmodule MyAppRouter do
  use Plug.Router

  plug :match
  plug :dispatch

  forward "/ws", to: MyWebsocketRouter

  match _ do
    send_resp(conn, 404, "Not Found")
  end
end

Events

ws/client.js is generated to handle websocket connection and callbacks for on: json, text/message and file. Just include it.

Example Usage

Here’s how you can include and use the WebSocket client in your HTML files:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebSocket Client</title>
</head>
<body>
    <script src="/ws/client.js"></script>
    <script>
        client.onJson((data) => {
            console.log(&#39;Received JSON:&#39;, data);
        });

        client.onFile((data) => {
            console.log(&#39;Received file data&#39;);
            const fileUrl = URL.createObjectURL(data);
            const link = document.createElement(&#39;a&#39;);
            link.href = fileUrl;
            link.download = &#39;downloaded_file&#39;;
            link.click();
            URL.revokeObjectURL(fileUrl);
        });

        client.onMessage((message) => {
            console.log(&#39;Received message:&#39;, message);
        });

        client.onConnect(() => {
            console.log(&#39;Connected to WebSocket server&#39;);
        });

        client.onDisconnect(() => {
            console.log(&#39;Disconnected from WebSocket server&#39;);
        });

        // Sending different types of data using the new syntax
        client.send(json({ hello: "world" }));
        client.send("some text");
        const fileBlob = new Blob(["This is a file content"], { type: &#39;text/plain&#39; });
        client.send(file(fileBlob));
    </script>
</body>
</html>

License

This project is licensed under the MIT License.