Skip to content

GoWorld's Communication Protocol Between Server and Client

Seis edited this page Oct 28, 2017 · 1 revision

Packet

+----------------------+-----------------+
| PayloadLength uint32 | Payload ...byte |
+----------------------+-----------------+

In GoWorld, clients and server communicate using TCP/KCP/WebSocket data stream. Data are sent by packets. The size of the payload is PayloadLength bytes.

Messages

The payload of packets is interpreted as messages. Each message consists of an uint16 message type and other data fields. Data fields have various types. Data field types are listed as below.

  • byte, uint16, uint32, uint64, float32, float64, ... : basic data types, little endian
  • bool: same as byte with value 1/0
  • Bytes: bytes of data whose size if predefined
  • VarBytes: an uint32 size followed with size bytes of data
  • ClientID: 16 bytes of Client ID
  • EntityID: 16 bytes of Entity ID
  • VarStr: same as VarBytes
  • Data: VarBytes with data as bytes which is marshalled by MessagePack
  • Args: an uint16 count followed with count number of arguments as Data fields

We use real go code to show the format of each message.

Create Entity (Server -> Client)

	packet.AppendUint16(MT_CREATE_ENTITY_ON_CLIENT)
	packet.AppendUint16(gid)
	packet.AppendClientID(clientid)
	packet.AppendBool(isPlayer)
	packet.AppendEntityID(entityid)
	packet.AppendVarStr(typeName)
	packet.AppendFloat32(x)
	packet.AppendFloat32(y)
	packet.AppendFloat32(z)
	packet.AppendFloat32(yaw)
	packet.AppendData(clientData)

Client should handle messages of this type to create client entities. gid and clientid can be safely ignored by client.

Destroy Entity (Server -> Client)

	packet.AppendUint16(MT_DESTROY_ENTITY_ON_CLIENT)
	packet.AppendUint16(gid)
	packet.AppendClientID(clientid)
	packet.AppendVarStr(typeName)
	packet.AppendEntityID(entityid)

Client should handle messages of this type to destroy client entities. gid and clientid can be safely ignored by client.

RPC between server and client

Call Client Entity Method (Server -> Client)

	packet.AppendUint16(MT_CALL_ENTITY_METHOD_ON_CLIENT)
	packet.AppendUint16(gid)
	packet.AppendClientID(clientid)
	packet.AppendEntityID(entityID)
	packet.AppendVarStr(method)
	packet.AppendArgs(args)

Client should read entityid, method and args and call the target entity's method with specified arguments.

Call Server Entity Method (Client -> Server)

	packet.AppendUint16(MT_CALL_ENTITY_METHOD_FROM_CLIENT)
	packet.AppendEntityID(id)
	packet.AppendVarStr(method)
	packet.AppendArgs(args)

Client send messages of this type to call methods of server entities.

Entity Attribute Updates

Notify MapAttr Change By Key (Server -> Client)

	packet.AppendUint16(MT_NOTIFY_MAP_ATTR_CHANGE_ON_CLIENT)
	packet.AppendUint16(gid)
	packet.AppendClientID(clientid)
	packet.AppendEntityID(entityid)
	packet.AppendData(path)  // path of the map attr
	packet.AppendVarStr(key) // map attr key
	packet.AppendData(val)   // map attr value

Server send messages of this type to clients whenever a MapAttr is modified by some key.

Notify MapAttr Delete By Key (Server -> Client)

	packet.AppendUint16(MT_NOTIFY_MAP_ATTR_DEL_ON_CLIENT)
	packet.AppendUint16(gid)
	packet.AppendClientID(clientid)
	packet.AppendEntityID(entityid)
	packet.AppendData(path)
	packet.AppendVarStr(key)

Server send messages of this type to clients whenever a MapAttr's key is deleted.

Notify ListAttr Set by Index (Server -> Client)

	packet.AppendUint16(MT_NOTIFY_LIST_ATTR_CHANGE_ON_CLIENT)
	packet.AppendUint16(gid)
	packet.AppendClientID(clientid)
	packet.AppendEntityID(entityid)
	packet.AppendData(path)
	packet.AppendUint32(index)
	packet.AppendData(val)

Server send messages of this type to clients whenver a ListAttr is modified by some index.

Notify ListAttr Append (Server -> Client)

	packet.AppendUint16(MT_NOTIFY_LIST_ATTR_APPEND_ON_CLIENT)
	packet.AppendUint16(gid)
	packet.AppendClientID(clientid)
	packet.AppendEntityID(entityid)
	packet.AppendData(path)
	packet.AppendData(val)

Server send messages of this type to clients whenever a ListAttr appends some value.

Notify ListAttr Pop (Server -> Client)

	packet := gwc.packetConn.NewPacket()
	packet.AppendUint16(MT_NOTIFY_LIST_ATTR_POP_ON_CLIENT)
	packet.AppendUint16(gid)
	packet.AppendClientID(clientid)
	packet.AppendEntityID(entityid)
	packet.AppendData(path)

Server send messages of this type to clients whenever a ListAttr pops some value.

Entity Infos (Position, Yaw) Synchronization

Sync Server Entity Infos (Client -> Server)

	packet.AppendEntityID(entityID)
	packet.AppendFloat32(x)
	packet.AppendFloat32(y)
	packet.AppendFloat32(z)
	packet.AppendFloat32(yaw)

Client send this message to synchronize entity infos to server when entity position or yaw is changed on client.

Sync Client Entity Infos (Server -> Client)

This message consists of a uint16 message type (MT_SYNC_POSITION_YAW_ON_CLIENTS) and N entity infos. Each entity info is 32 bytes which consists of a 16 bytes Entity ID and 4 float32 fields, as shown below.

                // Client message handling code 
		for packet.HasUnreadPayload() {
			entityID := packet.ReadEntityID()
			x := entity.Coord(packet.ReadFloat32())
			y := entity.Coord(packet.ReadFloat32())
			z := entity.Coord(packet.ReadFloat32())
			yaw := entity.Yaw(packet.ReadFloat32())
                        // update client entity position and yaw ...
		}

Client should handle messages of this type to update client entity infos (position and yaw).