billstclair/elm-websocket-framework-server/6.0.0

NOTE: this package is not compatible with Elm 0.19.1

WebSocketFramework.Server

Support for a Node.js server for WebSocketFramework messages.

Types

type alias Model servermodel message gamestate player =
{ servermodel : servermodel
, userFunctions :
UserFunctions servermodel message gamestate player
, state : ServerState gamestate player
, verbose : Bool
, gamePlayersDict : Dict GameId (List PlayerId)
, gameSocketsDict : Dict GameId (List Socket)
, socketGamesDict : Dict Socket (List GameId)
, socketPlayersDict : Dict Socket (List ( GameId, PlayerId ))
, deathRowDuration : Time
, deathWatch : List ( Time, GameId )
, deathWatchGameids : Dict GameId Bool
, deathWatchPlayers : List ( Time, GameId, PlayerId )
, deathWatchPlayerids : Dict PlayerId Bool
, time : Time
, seed : Seed
}

The server application model.

program creates one of these, via a call to init.

The four Dicts, mapping games, players, and sockets to each other, are used to give some time for a lost connection to come back. You must call the functions that maintain them, if you want those features.

deathRowDuration is the time that a socket must remain disconnected before its games and players will be auto-removed. It defaults to two minutes.

verbose is true to enable console logging of messages received and sent and auto-deletions. It is usually inititalized by the VERBOSE environment variable at server start time.

The deathWatch variables are used for the auto-removal process. You shouldn't need to deal with them, other than providing messageToGameid and messageToPlayerid values for userFunctions.

type Msg
= Connection Socket
| Disconnection Socket
| SocketMessage Socket String
| FirstTick Time
| Tick Time
| Noop

The messages processed by our update function.

Connection, Disconnection, and SocketMessage from through the inputPort from the Node.JS code. FirstTick and Tick are used to track time. Noop does nothing.

type WrappedModel servermodel message gamestate player
= WrappedModel (Model servermodel message gamestate player)

A type wrapper to prevent recursive types in Model.

type alias Socket =
Socket

An alias of WebSocketServer.Socket.

Callbacks

type alias UserFunctions servermodel message gamestate player =
{ encodeDecode : EncodeDecode message
, messageProcessor :
ServerMessageProcessor gamestate player message
, messageSender :
ServerMessageSender servermodel message gamestate player
, messageToGameid : Maybe (message -> Maybe GameId)
, messageToPlayerid : Maybe (message -> Maybe PlayerId)
, autoDeleteGame :
Maybe (GameId -> ServerState gamestate player -> Bool)
, gamesDeleter :
Maybe (ServerGamesDeleter servermodel message gamestate player)
, playersDeleter :
Maybe
(ServerPlayersDeleter servermodel message gamestate player)
, inputPort : InputPort Msg
, outputPort : OutputPort Msg
}

User functions that get called by the generic server code.

encodeDecode is used to translate messages to and from strings.

messageProcessor processes a client request into state changes and a response message.

messageSender decides what to do with the response message.

messageToGameid extracts a GameId from a message, if there is one.

messageToPlayerid extracts a PlayerId from a message, if there is one.

autoDeleteGame is called when all sockets referencing a GameId have disconnected. If it returns True, then the game will be put on deathwatch, meaning it will be removed from the tables after 2 minutes. Usually used to keep public games from being auto-deleted.

gamesDeleter is called when games are deleted due to their sockets being disconnected. See the ServerGamesDeleter description for more details.

playersDeleter is called when players are deleted due to their sockets being disconnected. See the ServerPlayersDeleter description for more details.

inputPort and outputPort are the ports used to communicate with the Node.js code.

type alias ServerMessageSender servermodel message gamestate player =
WrappedModel servermodel message gamestate player
-> Socket
-> ServerState gamestate player
-> message
-> message
-> ( WrappedModel servermodel message gamestate player, Cmd Msg )

User function that is called to send the response(s) to a request.

This will usually call sendToOne and/or sendToMany with the message emitted by the ServiceMessageProcessor in the UserFunctions passed to program.

The first message is the request that came from client to server. The second message is the response. If no response is returned by the ServiceMessageProcessor, this function is not called.

The ServerState arg is the value of the state property of the WrappedModel arg, pulled out for your convenience. If you change it, you must put it back in the model you return.

type alias ServerGamesDeleter servermodel message gamestate player =
WrappedModel servermodel message gamestate player
-> List GameId
-> ServerState gamestate player
-> WrappedModel servermodel message gamestate player

Called when games are auto-deleted due to socket connections being lost.

This will only happen if your server code tracks the association between sockets, games and players in the xxxDict properties of the Model. When tracked games are dropped, this function, stored in the gamesDeleter property of UserFunctions, is called, so that you can clean up any reference to those games in your gamestate.

type alias ServerPlayersDeleter servermodel message gamestate player =
WrappedModel servermodel message gamestate player
-> List PlayerId
-> ServerState gamestate player
-> WrappedModel servermodel message gamestate player

Called when players are auto-deleted due to socket connections being lost.

This will only happen if your server code tracks the association between sockets, games and players in the xxxDict properties of the Model. When tracked players are dropped, this function, stored in the playersDelete property of UserFunctions, is called, so that you can clean up any reference to those players in your gamestate.

Top-level program

servermodel
-> UserFunctions servermodel message gamestate player
-> Maybe gamestate
-> Program
(Maybe String)
(Model servermodel message gamestate player)
Msg

Create the top-level application program.

You will usually use the result of this function as the value of main in your top-level module.

Most servers will not need to use the servermodel, but it's a place to stash extra server-wide state that doesn't make sense in the game-specific gamestate.

servermodel
-> UserFunctions servermodel message gamestate player
-> Maybe gamestate
-> Maybe String
-> ( Model servermodel message gamestate player, Cmd Msg )

Return the initial Model and a Cmd to get the current time.

Usually called for you by program.

Message sending

Bool
-> MessageEncoder message
-> message
-> OutputPort Msg
-> Socket
-> Cmd Msg

Encode a message to a single socket via an output port.

If the first arg is True, log the operation on the console.

Bool
-> MessageEncoder message
-> message
-> OutputPort Msg
-> List Socket
-> Cmd Msg

Encode a message to multiple sockets via an output port.

If the first arg is True, log the operation on the console.

Support for creating random game and player identifiers.

WrappedModel servermodel message gamestate player
-> ( GameId, WrappedModel servermodel message gamestate player )

Generate a random GameId string, ensuring that it is not already assigned to a game.

Will not be used by servers that have no concept of a game.

WrappedModel servermodel message gamestate player
-> ( PlayerId, WrappedModel servermodel message gamestate player )

Generate a random PlayerId string, ensuring that it is not already assigned to a player.

Will not be used by servers that have no concept of a player.

Utilities

GameId
-> Socket
-> WrappedModel servermodel message gamestate player
-> List Socket

Return sockets associated with a game.

Removes the passed socket from the list.

Often useful in ServerMessageSender functions to send responses to all players.

WrappedModel servermodel message gamestate player
-> Socket
-> GameId
-> PlayerId
-> ( WrappedModel servermodel message gamestate player
, GameId
, PlayerId
)

Generate a new, random game and player ids for the passed GameId and PlayerId.

Update the Model.state tables, changing old to new.

Insert new in the Model.xxxDict tables.

Your ServerMessageProcessor will often generate fixed ids or incrementing integers. This makes them unique and secure.

WrappedModel servermodel message gamestate player
-> Socket
-> GameId
-> PlayerId
-> ( WrappedModel servermodel message gamestate player
, GameId
, PlayerId
)

Generate a new, random player id for the passed PlayerId on the passed GameId.

Update the Model.state tables, changing old to new.

Insert new in the Model.xxxDict tables.

Your ServerMessageProcessor will often generate fixed ids or incrementing integers. This makes them unique and secure.

WrappedModel servermodel message gamestate player
-> GameId
-> WrappedModel servermodel message gamestate player

Remove a game from the Model.xxxDict tables.

Your code is responsible for removing it from the Model.state tables.

WrappedModel servermodel message gamestate player
-> GameId
-> PlayerId
-> Bool
-> WrappedModel servermodel message gamestate player

Remove a player from the Model.xxxDict tables.

Your code is responsible for removing it from the Model.state tables.

Model accessors

verbose : WrappedModel servermodel message gamestate player -> Bool

Return whether VERBOSE is set in the server's environment