Fedecks Server

Provides a websocket for a Phoenix application, for establishing communications with a Fedecks Client, probably running on a Nerves Device.

installation

Installation

Add to deps


{:fedecks_server, "~> 0.1"}

using

Using

step-1-implement-a-handler

Step 1 - Implement a handler

Implement a FedecksServer.FedecksHandler to handle connecting and upstream messages.

eg

defmodule MyAppWeb.MyFedecksHandler do
  @behaviour FedecksHandler

  @impl FedecksHandler
  def authenticate(%{"username" => username, 
                    "password" => password, 
                    "fedecks-device-id" => device_id}) do
    MyApp.MyAuth.device_auth(username, password, device_id)
  end

  def authenticate?(_), do: false

  @impl FedecksHandler
  def otp_app, do: :my_app
end

Other optional callbacks you can implement include

step-2-add-configuration

Step 2 - Add configuration

In your config you must add configuration for your handler. eg

import Config

config :my_app, MyAppWeb.MyFedecksHandler,
  salt: System.fetch_env!("FEDECKS_SALT"),
  secret: System.fetch_env!("FEDECKS_SECRET")

The salt and secret are used to encode the authentication token that is used for restablishing connections without logging in. You can generate them, for instance, with mix phx.gen.secret.

Additional optional configuration options are

  • token_refresh_millis: the number of milliseconds between a refreshed token being sent to the client. Defaults to 3 hours.
  • token_expiry_secs: the number of seconds after which a token will expire. Currently set to 4 weeks, which is arguably over long.

step-3-add-to-the-endpoint

Step 3 - Add to the endpoint

Add the endpoint with the macro FedecksServer.Socket.fedecks_socket/2. Eg

defmodule MyAppWeb.Endpoint
  use Phoenix.Endpoint, otp_app: :my_app

  import FedecksServer.Socket, only: [fedecks_socket: 1]

  fedecks_socket(MyApp.SocketHandler)
end

The socket path defaults to "fedecks" but can be optionally provided to the FedecksServer.Socket.fedecks_socket/2. Note that the actual path will have "/websocket" appended as Phoenix.Socket.Transport also supports long polling and needs to know which the client wants: the default path is actually "fedecks/websocket".

step-4-implement-the-rest-of-the-owl-the-client-side

Step 4 - Implement the rest of the owl the client side

Use Fedecks Client on your Nerves device to communicate with the server.

potential-roadmap

Potential roadmap

Phoenix 1.7 now uses WebSock which is analagous to Plug for websockets, which allows for more flexible approach to adding a Phoenix.Socket.Transport to your endpoint. I want to find some time to explore that approach.