stratus

Types

pub opaque type Builder(state, user_message)

This holds some information needed to communicate with the WebSocket.

pub opaque type Connection

These are the messages emitted or received by the underlying process. You should only need to interact with Message below.

pub opaque type InternalMessage(user_message)

This is the type of message your handler might receive.

pub type Message(user_message) {
  Text(String)
  Binary(BitArray)
  User(user_message)
}

Constructors

  • Text(String)
  • Binary(BitArray)
  • User(user_message)
pub opaque type Next(state, user_message)

Values

pub fn close(
  conn: Connection,
) -> Result(Nil, @internal SocketReason)

This will close the WebSocket connection.

pub fn continue(state: state) -> Next(state, user_message)
pub fn initialize(
  builder: Builder(state, user_message),
) -> Result(
  actor.Started(process.Subject(InternalMessage(user_message))),
  actor.StartError,
)

This opens the WebSocket connection with the provided Builder. It makes some assumptions about the request if you do not provide it. It will use ports 80 or 443 for ws or wss respectively.

It will open the connection and perform the WebSocket handshake. If this fails, the actor will fail to start with the given reason as a string value.

After that, received messages will be passed to your loop, and you can use the helper functions to send messages to the server. The close method will send a close frame and end the connection.

pub fn on_close(
  builder: Builder(state, user_message),
  on_close: fn(state) -> Nil,
) -> Builder(state, user_message)

You can provide a function to be called when the connection is closed. This function receives the last value for the state of the WebSocket.

NOTE: If you manually call stratus.close, this function will not be called. I’m unsure right now if this is a bug or working as intended. But you will be in the loop with the state value handy.

pub fn on_handshake_error(
  builder: Builder(state, user_message),
  on_handshake_error: fn(response.Response(BitArray)) -> Nil,
) -> Builder(state, user_message)

If the WebSocket handshake fails, this method will be called with the response received from the server. The process will stop after this.

pub fn send_binary_message(
  conn: Connection,
  msg: BitArray,
) -> Result(Nil, @internal SocketReason)

From within the actor loop, this is how you send a WebSocket text frame.

pub fn send_ping(
  conn: Connection,
  data: BitArray,
) -> Result(Nil, @internal SocketReason)

Send a ping frame with some data.

pub fn send_text_message(
  conn: Connection,
  msg: String,
) -> Result(Nil, @internal SocketReason)

From within the actor loop, this is how you send a WebSocket text frame. This must be valid UTF-8, so it is a String.

pub fn stop() -> Next(state, user_message)
pub fn stop_abnormal(reason: String) -> Next(state, user_message)
pub fn to_user_message(
  user_message: user_message,
) -> InternalMessage(user_message)

The Subject returned from initialize is an opaque type. In order to send custom messages to your process, you can do this mapping.

For example:

  // using `process.send`
  MyMessage(some_data)
  |> stratus.to_user_message
  |> process.send(stratus_subject, _)
  // using `process.try_call`
  process.try_call(stratus_subject, fn(subj) {
    stratus.to_user_message(MyMessage(some_data, subj))
  })
pub fn websocket(
  request req: request.Request(String),
  init init: fn() -> #(
    state,
    option.Option(process.Selector(user_message)),
  ),
  loop loop: fn(state, Message(user_message), Connection) -> Next(
    state,
    user_message,
  ),
) -> Builder(state, user_message)

This creates a builder to set up a WebSocket actor. This will use default values for the connection initialization timeout, and provide an empty function to be called when the server closes the connection. If you want to customize either of those, see the helper functions with_connect_timeout

pub fn with_connect_timeout(
  builder: Builder(state, user_message),
  timeout: Int,
) -> Builder(state, user_message)

This sets the maximum amount of time you are willing to wait for both connecting to the server and receiving the upgrade response. This means that it may take up to timeout * 2 to begin sending or receiving messages. This value defaults to 5 seconds.

pub fn with_selector(
  next: Next(state, user_message),
  selector: process.Selector(user_message),
) -> Next(state, user_message)
Search Document