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.
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 ...SteppedBackoff
counterparts:
[ ReconnectAfterMillis 1000
, ReconnectSteppedBackoff [ 10, 20, 50, 100, 500 ]
, RejoinAfterMillis 10000
, RejoinSteppedBackoff [ 1000, 2000, 5000 ]
]
On the JS side, the above options result in:
{ reconnectAfterMs: function(tries){ return [10, 20, 50, 100, 500][tries - 1] || 1000 },
rejoinAfterMs: function(tries){ return [1000, 2000, 5000][tries - 1] || 10000 }
}
For a consistent time interval simply ignore the ...SteppedBackoff
options:
[ ReconnectAfterMillis 1000
, RejoinAfterMillis 10000
]
Json.Encode.Value
A type alias repesenting the params to be sent when connecting, such as authentication params like username and password.
{ msg : String
, payload : Json.Encode.Value } -> Platform.Cmd.Cmd ms
}
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 : List ConnectOption -> Maybe Params -> PortOut msg -> Platform.Cmd.Cmd msg
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.phoenixSend
disconnect : Maybe Basics.Int -> PortOut msg -> Platform.Cmd.Cmd msg
Disconnect the Socket, maybe providing a status code for the closure.
{ reason : Maybe String
, code : Basics.Int
, wasClean : Basics.Bool
, type_ : String
, isTrusted : Basics.Bool
}
A type alias representing the information received when the Socket closes.
String
A type alias representing the Channel topic id. For example
"topic:subTopic"
.
String
A type alias representing an event received from a Channel.
Json.Encode.Value
A type alias representing data that is received from a Channel.
{ topic : Topic
, event : Event
, payload : Payload
, joinRef : Maybe String
, ref : Maybe String
}
A type alias representing a raw Channel message received by the Socket.
{ topic : Topic
, event : Event
, payload : Payload
}
A type alias representing a raw Presence message received by the Socket.
{ topic : Topic
, event : Event
, payload : Payload
, ref : String
}
A type alias representing a raw Heartbeat received by the Socket.
{ connectionState : String
, endPointURL : String
, isConnected : Basics.Bool
, makeRef : String
, protocol : String
}
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.
({ msg : String
, payload : Json.Encode.Value } -> msg) -> Platform.Sub.Sub ms
)
A type alias representing the port
function required to receive
a Msg from the Socket.
You will find this port
function in the
Port
module.
subscriptions : (Msg -> msg) -> PortIn msg -> Platform.Sub.Sub msg
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.socketReceiver
Request information about the Socket.
connectionState : PortOut msg -> Platform.Cmd.Cmd msg
endPointURL : PortOut msg -> Platform.Cmd.Cmd msg
info : PortOut msg -> Platform.Cmd.Cmd msg
isConnected : PortOut msg -> Platform.Cmd.Cmd msg
makeRef : PortOut msg -> Platform.Cmd.Cmd msg
protocol : PortOut msg -> Platform.Cmd.Cmd msg
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 : String -> String -> Json.Encode.Value -> PortOut msg -> Platform.Cmd.Cmd msg
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.phoenixSend
startLogging : PortOut msg -> Platform.Cmd.Cmd msg
Activate the Socket's logger function. This will log all messages that the Socket sends and receives.
stopLogging : PortOut msg -> Platform.Cmd.Cmd msg
Deactivate the Socket's logger function.