Skip to content

Commit

Permalink
Generalize Socket.onDie to Socket.onClose, Socket.onAbnormalClose and…
Browse files Browse the repository at this point in the history
… Socket.onNormalClose
  • Loading branch information
saschatimme committed Nov 19, 2016
1 parent d38d6ff commit 1ad3b92
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 32 deletions.
2 changes: 1 addition & 1 deletion example/web/elm/src/Chat.elm
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ socket : Int -> Socket Msg
socket accessToken =
Socket.init lobbySocket
|> Socket.withParams [ ( "accessToken", toString accessToken ) ]
|> Socket.onDie RefreshAccessToken
|> Socket.onAbnormalClose RefreshAccessToken


lobby : String -> Channel Msg
Expand Down
41 changes: 27 additions & 14 deletions src/Phoenix.elm
Original file line number Diff line number Diff line change
Expand Up @@ -481,18 +481,18 @@ onSelfMsg router selfMsg state =
Nothing ->
Task.succeed state

Just internalSocket ->
Just ({ connection, socket } as internalSocket) ->
let
backoffIteration =
case internalSocket.connection of
case connection of
InternalSocket.Opening n _ ->
n + 1

_ ->
0

backoff =
internalSocket.socket.reconnectTimer backoffIteration
socket.reconnectTimer backoffIteration

-- update channels because of disconnect
getNewState =
Expand All @@ -501,19 +501,32 @@ onSelfMsg router selfMsg state =
finalNewState pid =
Task.map (updateSocket endpoint (InternalSocket.opening backoffIteration pid internalSocket)) getNewState

notifyApp =
case
( internalSocket.socket.onDie
, internalSocket |> InternalSocket.isOpening
)
of
( Just onDie, False ) ->
Platform.sendToApp router onDie &> Task.succeed ()
notifyOnClose =
if InternalSocket.isOpening internalSocket then
Task.succeed ()
else
Maybe.map (\onClose -> Platform.sendToApp router (onClose details)) socket.onClose
|> Maybe.withDefault (Task.succeed ())

_ ->
Task.succeed ()
notifyOnNormalClose =
-- see https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent for error codes
if InternalSocket.isOpening internalSocket || details.code /= 1000 then
Task.succeed ()
else
Maybe.map (Platform.sendToApp router) socket.onNormalClose
|> Maybe.withDefault (Task.succeed ())

notifyOnAbnormalClose =
-- see https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent for error codes
if InternalSocket.isOpening internalSocket || details.code /= 1006 then
Task.succeed ()
else
Maybe.map (Platform.sendToApp router) socket.onAbnormalClose
|> Maybe.withDefault (Task.succeed ())
in
notifyApp
notifyOnClose
&> notifyOnNormalClose
&> notifyOnAbnormalClose
&> attemptOpen router backoff internalSocket
|> Task.andThen finalNewState

Expand Down
6 changes: 5 additions & 1 deletion src/Phoenix/Internal/Socket.elm
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ isOpening internalSocket =

socketMap : (a -> b) -> Socket.Socket a -> Socket.Socket b
socketMap func socket =
{ socket | onDie = Maybe.map func socket.onDie }
{ socket
| onClose = Maybe.map ((<<) func) socket.onClose
, onNormalClose = Maybe.map func socket.onNormalClose
, onAbnormalClose = Maybe.map func socket.onAbnormalClose
}


opening : Int -> Process.Id -> InternalSocket msg -> InternalSocket msg
Expand Down
49 changes: 33 additions & 16 deletions src/Phoenix/Socket.elm
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
module Phoenix.Socket exposing (Socket, init, heartbeatIntervallSeconds, withoutHeartbeat, reconnectTimer, withParams, withDebug, onDie)
module Phoenix.Socket exposing (Socket, init, heartbeatIntervallSeconds, withoutHeartbeat, reconnectTimer, withParams, withDebug, onClose, onAbnormalClose, onNormalClose)

{-| A socket declares to which endpoint a socket connection should be established.
# Definition
@docs Socket
# Helpers
@docs init, withParams, heartbeatIntervallSeconds, withoutHeartbeat, reconnectTimer, withDebug, onDie
@docs init, withParams, heartbeatIntervallSeconds, withoutHeartbeat, reconnectTimer, withDebug, onAbnormalClose, onNormalClose, onClose
-}

import Time exposing (Time)
Expand All @@ -25,7 +25,9 @@ type alias PhoenixSocket msg =
, withoutHeartbeat : Bool
, reconnectTimer : Int -> Float
, debug : Bool
, onDie : Maybe msg
, onClose : Maybe ({ code : Int, reason : String, wasClean : Bool } -> msg)
, onAbnormalClose : Maybe msg
, onNormalClose : Maybe msg
}


Expand All @@ -41,7 +43,9 @@ init endpoint =
, withoutHeartbeat = False
, reconnectTimer = defaultReconnectTimer
, debug = False
, onDie = Nothing
, onClose = Nothing
, onAbnormalClose = Nothing
, onNormalClose = Nothing
}


Expand Down Expand Up @@ -97,19 +101,32 @@ withDebug socket =
{ socket | debug = True }


{-| Set a callback which will be called if the socket connection got interrupted. Useful for updating query params like access tokens.
+
+ type Msg =
+ RefreshAccessToken | ...
+
+ init "ws://localhost:4000/socket/websocket"
+ |> withParams [ ( "accessToken", "abc123" ) ]
+ |> onDie RefreshAccessToken
+
{-| Set a callback which will be called if the socket connection got closed abnormal, i.e., if the server declined the socket authentication. So this callback is useful for updating query params like access tokens.
type Msg =
RefreshAccessToken | ...
init "ws://localhost:4000/socket/websocket"
|> withParams [ ( "accessToken", "abc123" ) ]
|> onAbnormalClose RefreshAccessToken
-}
onAbnormalClose : msg -> Socket msg -> Socket msg
onAbnormalClose onAbnormalClose_ socket =
{ socket | onAbnormalClose = Just onAbnormalClose_ }


{-| Set a callback which will be called if the socket connection got closed normal. Useful if you have to do some additional clean up.
-}
onNormalClose : msg -> Socket msg -> Socket msg
onNormalClose onNormalClose_ socket =
{ socket | onNormalClose = Just onNormalClose_ }


{-| Set a callback which will be called if the socket connection got closed. You can learn more about the code [here](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent).
-}
onDie : msg -> Socket msg -> Socket msg
onDie onDie_ socket =
{ socket | onDie = Just onDie_ }
onClose : ({ code : Int, reason : String, wasClean : Bool } -> msg) -> Socket msg -> Socket msg
onClose onClose_ socket =
{ socket | onClose = Just onClose_ }


defaultReconnectTimer : Int -> Time
Expand Down

0 comments on commit 1ad3b92

Please sign in to comment.