Provides a websocket for a Phoenix application, for establishing communications with a Fedecks Client, probably running on a Nerves Device.
Add to deps
{:fedecks_server, "~> 0.1"}
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
c:FedecksServer.FedecksHandler.handle_in/2
for handling incoming messages as Erlang termsc:FedecksServer.FedecksHandler.handle_raw_in/2
for handling incoming raw binary messsagesc:FedecksServer.FedecksHandler.connection_established/1
- this will be called every time a connection is established with a client. You can use this for things like tracking with Phoenix.Presence or subscribing to a Pub Sub topic with your device id, to allow messages to be sent to your device.c:FedecksServer.FedecksHandler.handle_info/2
- handle internal messages sent to your socket's process inbox. If you have subscribed to a Pub Sub topic with your device id, then this is how you would initiate sending messages to your device.c:FedecksServer.FedecksHandler.socket_error/3
- any errors that have happened, such as receiving an invalid message or authentication failures, would be reported here.
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.
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".
Use Fedecks Client on your Nerves device to communicate with the server.
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.