phollyer/elm-phoenix-websocket/1.0.3

NOTE: the latest version is 4.0.0

Channel

This module is for working directly with channels.

Before you can join a channel and start sending and receiving, you first need to connect to a socket.

Sending Messages

send : EventOut -> PortOut msg -> Cmd msg

Send an EventOut to the channel.

import Channel exposing (EventOut(..))
import Ports.Phoenix as Phx


-- Join a Channel


Phx.sendMessage
  |> Channel.send
    (Join
      { topic = "topic:subtopic"
      , timeout = Nothing
      , payload = Nothing
      }
    )


-- Push some data to a Channel


import Json.Encode as JE


Phx.sendMessage
  |> Channel.send
    (Push
      { topic = Just "topic:subtopic"
      , event = "send_msg"
      , timeout = Nothing
      , data =
          JE.object
            [ ("msg", "Hello to everyone!" |> JE.string) ]
      }
= Join JoinConfig
| Push PushConfig
| On EventConfig
| Off EventConfig
| Leave LeaveConfig

All of the events you can send to the channel.

Each of these EventOut messages corresponds to the equivalent function in the PhoenixJS API. For more info on these please read the API docs.

type alias JoinConfig =
{ topic : String
, timeout : Maybe Int
, payload : Maybe Value
}

A type alias representing the settings for joining a channel.

topic - the channel topic id, for example: "topic:subtopic".

timeout - optional timeout, in ms, before retrying to join if the previous attempt failed.

payload - optional data to be sent to the channel when joining.

type alias PushConfig =
{ topic : Maybe String
, event : String
, timeout : Maybe Int
, payload : Value
}

A type alias representing the settings for pushing messages over a channel.

topic - the channel topic id, for example: Just "topic:subtopic".

The topic is used to track the channels on the JS side. This allows for utilising multiple channels. Setting topic = Nothing will send the push over the last used channel, or the only channel you're using if using only one channel.

event - the event to send to the channel.

timeout - optional timeout, in ms, before retrying to push if the previous attempt failed.

payload - the data to be sent.

type alias EventConfig =
{ topic : Maybe String
, event : String
}

A type alias representing channel events that can be turned On or Off.

topic - optional channel topic id, for example: Just "topic:subtopic".

The topic is used to track the channels on the JS side. This allows for utilising multiple channels. Setting topic = Nothing will set the event on the last used channel, or the only channel you're using if using only one channel.

event - the event that you want to be turned On or Off.

In order to receive event Messages, they need to be registered with an On event sent to the channel. So if your Phoenix Channel is going to push or broadcast a new_msg event, it needs to be registered as follows:

import Channel
import Ports.Phoenix as Phx


Phx.sendMessage
    |> Channel.send
        (On
            { topic = Just "topic:subtopic"
            , event = "new_msg"
            }
        )

Now you will be able to receive new_msgs as follows:

import Channel exposing (EventIn(..))
import Ports.Phoenix as Phx


type Msg
    = ChannelMsg Channel.EventIn


update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
    case msg of
        ChannelMsg (Message "topic:subtopic" "new_msg" payload) ->
            ...


subscriptions : Model -> Sub Msg
subscriptions _ =
    Phx.channelReceiver
        |> Channel.subscriptions
            ChannelMsg

NB you must set your On events after you have joined the relevant channel.

type alias LeaveConfig =
{ topic : Maybe String
, timeout : Maybe Int
}

A type alias representing the settings for leaving a channel.

topic - optional channel topic id, for example: Just "topic:subtopic".

The topic is used to track the channels on the JS side. This allows for utilising multiple channels. Setting topic = Nothing will leave the last used channel, or the only channel you're using if using only one channel.

timeout - optional timeout, in ms, before retrying to leave if the previous attempt failed.

type alias PortOut msg =
PackageOut -> Cmd msg

A type alias representing the port function required to send the EventOut to the channel.

You could write this yourself, if you do, it needs to be named sendMessage, although you may find it simpler to just add this port module to your src - it includes all the necessary port functions.

type alias PackageOut =
{ target : String
, event : String
, payload : Value
}

A type alias representing the data sent out through a port to a channel. You will not use this directly.

Receiving Messages

subscriptions : (EventIn -> msg) -> PortIn msg -> Sub msg

Subscribe to receive incoming channel events.

import Channel
import Ports.Phoenix as Phx


type Msg
  = ChannelMsg Channel.EventIn
  | ...




subscriptions : Model -> Sub Msg
subscriptions _ =
    Phx.channelReceiver
      |> Channel.subscriptions
        ChannelMsg
type EventIn
= JoinOk Topic Value
| JoinError Topic Value
| JoinTimeout Topic
| PushOk Topic PushEvent Value
| PushError Topic PushEvent Value
| PushTimeout Topic PushEvent
| Message Topic PushEvent Value
| Error Topic Value
| LeaveOk Topic
| Closed Topic
| InvalidEvent Topic String Value

All of the events you can receive from the channel.

If you are using more than one channel, then you can check Topic to determine which channel the EventIn relates to. If you are only using a single channel, you can ignore Topic.

InvalidEvent means that an event has been received from the accompanying JS that cannot be handled. This should not happen, if it does, please raise an issue.

type alias Topic =
String

A type alias representing the channel topic. Use this to identify the channel an EventIn relates to.

If you are only using one channel, you can ignore this.

type alias PushEvent =
String

A type alias representing a Push to a channel. Use this to identify which Push an EventIn relates to.

type alias PortIn msg =
(PackageIn -> msg) -> Sub msg

A type alias representing the port function required to receive the EventIn from the channel.

You could write this yourself, if you do, it needs to be named channelReceiver, although you may find it simpler to just add this port module to your src - it includes all the necessary port functions.

type alias PackageIn =
{ topic : String
, event : String
, payload : Value
}

A type alias representing the data received from a channel. You will not use this directly.