This module can be used to talk directly to PhoenixJS without needing to add anything to your Model. You can send and receive messages to and from the JS Socket from anywhere in your Elm program. That is all it does and all it is intended to do.
If you want more functionality, the top level Phoenix module takes care of a lot of the low level stuff such as automatically connecting to the Socket.
A type alias repesenting the params to be sent when connecting, such as authentication params like username and password.
A type alias representing the port function required to send messages out
to the accompanying JS.
You will find this port function in the
Port
module.
Connect to the Socket, providing any required
ConnectOptions and Params as well as the port function
to use.
import Json.Encode as JE
import Phoenix.Socket as Socket
import Ports.Phoenix as Port
-- A simple connection
Socket.connect [] Nothing Port.phoenixSend
-- A connection with options and auth params
options =
[ Socket.HeartbeatIntervalMillis 500
, Socket.Timeout 10000
]
params =
JE.object
[ ("username", JE.string "Joe Bloggs")
, ("password", JE.string "password")
]
Socket.connect options (Just params) Port.phoenixSendDisconnect the Socket, maybe providing a status code for the closure.
A type alias representing the information received when the Socket closes.
A type alias representing the Channel topic id. For example
"topic:subTopic".
A type alias representing an event received from a Channel.
A type alias representing data that is received from a Channel.
A type alias representing a raw Channel message received by the Socket.
A type alias representing a raw Presence message received by the Socket.
A type alias representing a raw Heartbeat received by the Socket.
A type alias representing all of the info available about the Socket.
Information received about the Socket.
An InternalError should never happen, but if it does, it is because the
JS is out of sync with this package.
If you ever receive this message, please raise an issue.
All of the messages you can receive from the Socket.
Subscribe to receive incoming Socket messages.
import Phoenix.Socket as Socket
import Ports.Phoenix as Port
type Msg
= SocketMsg Socket.Msg
| ...
subscriptions : Model -> Sub Msg
subscriptions _ =
Socket.subscriptions
SocketMsg
Port.socketReceiverRequest information about the Socket.
Here you can log data to the console, and activate and deactive the socket's
logger, but be warned, there is no safeguard when you compile such as you
get when you use Debug.log. Be sure to deactive the logging before you deploy
to production.
However, the ability to easily toggle logging on and off leads to a possible use case where, in a deployed production environment, an admin is able to see all the logging, while regular users do not.
Log some data to the console.
import Json.Encode as JE
import Ports.Phoenix as Port
log "info" "foo"
(JE.object
[ ( "bar", JE.string "foo bar" ) ]
)
port.phoenixSend
-- info: foo {bar: "foo bar"}In order to receive any output in the console, you first need to activate the
Socket's logger. There are two ways to do this. You can use the
startLogging function, or you can pass the Logger True
ConnectOption to the connect
function.
import Ports.Phoenix as Port
connect [ Logger True ] Nothing Port.phoenixSendActivate the Socket's logger function. This will log all messages that the Socket sends and receives.
Deactivate the Socket's logger function.
The options that can be set on the Socket when instantiating a
new Socket(url, options)on the JS side.See https://hexdocs.pm/phoenix/js/#Socket for more info on the options and the effect they have.
However, there are two potential instances where we have to work around the inability to send functions through
ports. This is if you wish to employ a backoff strategy that increases the time interval between repeated attempts to reconnect or rejoin.To do this on the JS side, you would provide a function that returns an
Int. But because we can't send functions through ports, the way to create these functions is to also use the...SteppedBackoffcounterparts:On the JS side, the above options result in:
For a consistent time interval simply ignore the
...SteppedBackoffoptions: