Implement ServerMessage for all the server messages.

main
Mari 3 years ago
parent 84bbdd31f0
commit 942b7eb20b
  1. 14
      server/action/syncable.go
  2. 3
      server/go.sum
  3. 6
      server/room/room.go
  4. 4
      server/state/synced.go
  5. 69
      server/websocket/server.go

@ -28,4 +28,16 @@ type Syncable interface {
// If an action is correctly applied and has an effect, it should return nil.
Apply(s *state.Synced) error
}
type SyncableProducer func()
type SyncableSlice []Syncable
func (s SyncableSlice) MarshalLogArray(encoder zapcore.ArrayEncoder) error {
var finalErr error = nil
for _, a := range s {
err := encoder.AppendObject(a)
if err != nil && finalErr == nil {
finalErr = err
}
}
return finalErr
}

@ -3,10 +3,8 @@ github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -40,7 +38,6 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11 h1:Yq9t9jnGoR+dBuitxdo9l6Q
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=

@ -11,7 +11,7 @@ type NewOptions struct {
// BaseLogger is the logger that the room should attach its data to.
BaseLogger *zap.Logger
// StartingState is a state.Synced that defines the state of the room on creation.
StartingState state.Synced
StartingState *state.Synced
// StartingClientOptions sets the configuration of the first client to be created, the one that will be returned
// from New.
StartingClientOptions NewClientOptions
@ -32,7 +32,7 @@ type room struct {
logger *zap.Logger
}
// Creates and starts up a new room, joins a new client to it and returns that client.
// New creates and starts up a new room, joins a new client to it and returns that client.
func New(opts NewOptions) *Client {
logger := opts.BaseLogger.Named("Room")
id := xid.New()
@ -40,7 +40,7 @@ func New(opts NewOptions) *Client {
id: id,
incomingChannel: make(chan ClientMessage),
clients: make(map[xid.ID]internalClient),
currentState: opts.StartingState,
currentState: *opts.StartingState,
logger: logger,
}
go r.act()

@ -10,7 +10,7 @@ type Synced struct {
User UserData `json:"user"`
}
func (s Synced) MarshalLogObject(encoder zapcore.ObjectEncoder) error {
func (s *Synced) MarshalLogObject(encoder zapcore.ObjectEncoder) error {
mapErr := encoder.AddObject("map", s.Map)
userErr := encoder.AddObject("user", s.User)
if mapErr != nil {
@ -21,7 +21,7 @@ func (s Synced) MarshalLogObject(encoder zapcore.ObjectEncoder) error {
}
// Copy creates a deep copy of this Synced instance.
func (s Synced) Copy() Synced {
func (s *Synced) Copy() Synced {
return Synced{
Map: s.Map.Copy(),
User: s.User.Copy(),

@ -6,8 +6,6 @@ import (
"hexmap-server/state"
)
// TODO: Make all the ServerMessages implement ServerMessage.
// ServerMessageType is an enum type for the server's messages.
type ServerMessageType string
@ -32,13 +30,41 @@ type ServerHello struct {
// Version is the protocol version the server is running.
Version int `json:"version"`
// State is the complete state of the server as of when the client joined.
State state.Synced `json:"state"`
State *state.Synced `json:"state"`
}
func (s ServerHello) MarshalLogObject(encoder zapcore.ObjectEncoder) error {
encoder.AddString("type", string(ServerHelloType))
encoder.AddInt("version", s.Version)
return encoder.AddObject("state", s.State)
}
func (s ServerHello) ServerType() ServerMessageType {
return ServerHelloType
}
// ServerRefresh is the action sent to reestablish the current state of the server in response to ClientRefresh.
type ServerRefresh struct {
// State is the complete state of the server as of when the corresponding ClientRefresh was processed.
State state.Synced `json:"state"`
State *state.Synced `json:"state"`
}
func (s ServerRefresh) MarshalLogObject(encoder zapcore.ObjectEncoder) error {
encoder.AddString("type", string(ServerRefreshType))
return encoder.AddObject("state", s.State)
}
func (s ServerRefresh) ServerType() ServerMessageType {
return ServerRefreshType
}
type IDSlice []int
func (i IDSlice) MarshalLogArray(encoder zapcore.ArrayEncoder) error {
for _, v := range i {
encoder.AppendInt(v)
}
return nil
}
// ServerOK is the action sent when one or more client actions have been accepted and applied.
@ -46,7 +72,16 @@ type ServerOK struct {
// IDs contains the IDs of the actions which were accepted and applied, in the order they were accepted and applied.
// This is the same as the order they were received, though other actions may have been between these that were
// rejected.
IDs []int `json:"ids"`
IDs IDSlice `json:"ids"`
}
func (s ServerOK) MarshalLogObject(encoder zapcore.ObjectEncoder) error {
encoder.AddString("type", string(ServerOKType))
return encoder.AddArray("ids", s.IDs)
}
func (s ServerOK) ServerType() ServerMessageType {
return ServerOKType
}
// ServerFailed is the action sent when one or more client actions have been rejected.
@ -54,14 +89,34 @@ type ServerFailed struct {
// IDs contains the IDs of the actions which were rejected, in the order they were rejected.
// This is the same as the order they were received, though other actions may have been between these that were
// accepted and applied.
IDs []int `json:"ids"`
IDs IDSlice `json:"ids"`
// Error contains the error text sent from the server about why these actions failed.
Error string `json:"error"`
}
func (s ServerFailed) MarshalLogObject(encoder zapcore.ObjectEncoder) error {
encoder.AddString("type", string(ServerFailedType))
err := encoder.AddArray("ids", s.IDs)
encoder.AddString("error", s.Error)
return err
}
func (s ServerFailed) ServerType() ServerMessageType {
return ServerFailedType
}
// ServerAct is the action sent when one or more client actions from other clients have been accepted and applied.
// The client's own actions will never be included in this action.
type ServerAct struct {
// Actions contains the actions that are now being applied.
Actions []action.Syncable `json:"actions"`
Actions action.SyncableSlice `json:"actions"`
}
func (s ServerAct) MarshalLogObject(encoder zapcore.ObjectEncoder) error {
encoder.AddString("type", string(ServerActType))
return encoder.AddArray("actions", s.Actions)
}
func (s ServerAct) ServerType() ServerMessageType {
return ServerActType
}

Loading…
Cancel
Save