MemberAdded is an enum flag for SetOnRoomChange callback to indicate that there is a new member added to the room
const MemberAdded = 1
MemberRemoved is an enum flag for SetOnRoomChange callback to indicate that there is a member that has been removed from the room
const MemberRemoved = 2
PropertyChanged is an enum flag for SetOnRoomChange callback to indicate that one or more room properties have been changed
const PropertyChanged = 3
func AfterBroadcastRoomCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))
AfterBroadcastRoomCmd registers a callback function to be executed after broadcast room command:
Parameters
ver - Command ver sent from the client. cmd - Command ID sent from the client. payload - Command payload sent from the client. userData - User data representing the client that sent the command. next - The function to signal the command to move on to the next operation of the same ver and command ID. This function must be called at the end of all operations in the callback. If you pass an error, it will not proceed to the next operations of the same command ver and ID.
func AfterCreateRoomCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))
AfterCreateRoomCmd registers a callback function to be executed after create room command:
Parameters
ver - Command ver sent from the client. cmd - Command ID sent from the client. payload - Command payload sent from the client. userData - User data representing the client that sent the command. next - The function to signal the command to move on to the next operation of the same ver and command ID. This function must be called at the end of all operations in the callback. If you pass an error, it will not proceed to the next operations of the same command ver and ID.
func AfterGetRoomPropCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))
AfterGetRoomPropCmd registers a callback function to be executed after get room properties:
Parameters
ver - Command ver sent from the client. cmd - Command ID sent from the client. payload - Command payload sent from the client. userData - User data representing the client that sent the command. next - The function to signal the command to move on to the next operation of the same ver and command ID. This function must be called at the end of all operations in the callback. If you pass an error, it will not proceed to the next operations of the same command ver and ID.
func AfterJoinRoomCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))
AfterJoinRoomCmd registers a callback function to be executed after join room command:
Parameters
ver - Command ver sent from the client. cmd - Command ID sent from the client. payload - Command payload sent from the client. userData - User data representing the client that sent the command. next - The function to signal the command to move on to the next operation of the same ver and command ID. This function must be called at the end of all operations in the callback. If you pass an error, it will not proceed to the next operations of the same command ver and ID.
func AfterLeaveRoomCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))
AfterLeaveRoomCmd registers a callback function to be executed after leave room command:
Parameters
ver - Command ver sent from the client. cmd - Command ID sent from the client. payload - Command payload sent from the client. userData - User data representing the client that sent the command. next - The function to signal the command to move on to the next operation of the same ver and command ID. This function must be called at the end of all operations in the callback. If you pass an error, it will not proceed to the next operations of the same command ver and ID.
func AfterMessageRoomCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))
AfterMessageRoomCmd registers a callback function to be executed after message room command:
Parameters
ver - Command ver sent from the client. cmd - Command ID sent from the client. payload - Command payload sent from the client. userData - User data representing the client that sent the command. next - The function to signal the command to move on to the next operation of the same ver and command ID. This function must be called at the end of all operations in the callback. If you pass an error, it will not proceed to the next operations of the same command ver and ID.
func AfterUpdateRoomPropCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))
AfterUpdateRoomPropCmd registers a callback function to be executed after update room properties:
Parameters
ver - Command ver sent from the client. cmd - Command ID sent from the client. payload - Command payload sent from the client. userData - User data representing the client that sent the command. next - The function to signal the command to move on to the next operation of the same ver and command ID. This function must be called at the end of all operations in the callback. If you pass an error, it will not proceed to the next operations of the same command ver and ID.
func Announce(roomID string, memberIDs []string, ver uint8, cmd uint16, message []byte, reliable bool)
Announce Sends a message to selected members to the room without having a "sender" - This function must NOT be called by user
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] All announce payloads have leading 4-byte-long header. The client must skip the first 4 bytes. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID. memberIDs - An array of member user IDs to send message to. senderUser - User to send broadcast. ver - Command version to be used as broadcast message. cmd - Command ID to be used as broadcast message. message - Message byte array. reliable - If true, UDP will be RUDP.
func BeforeBroadcastRoomCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))
BeforeBroadcastRoomCmd registers a callback function to be executed before broadcast room command:
Parameters
ver - Command ver sent from the client. cmd - Command ID sent from the client. payload - Command payload sent from the client. userData - User data representing the client that sent the command. next - The function to signal the command to move on to the next operation of the same ver and command ID. This function must be called at the end of all operations in the callback. If you pass an error, it will not proceed to the next operations of the same command ver and ID.
func BeforeCreateRoomCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))
BeforeCreateRoomCmd registers a callback function to be executed before create room command:
Parameters
ver - Command ver sent from the client. cmd - Command ID sent from the client. payload - Command payload sent from the client. next - The function to signal the command to move on to the next operation of the same ver and command ID. This function must be called at the end of all operations in the callback. If you pass an error, it will not proceed to the next operations of the same command ver and ID.
func BeforeGetRoomPropCmd(callback func(ver uint8, cmd uint16, payloa []byte, userData *user.User, next func(error)))
BeforeGetRoomPropCmd registers a callback function to be executed before get room properties:
Parameters
ver - Command ver sent from the client. cmd - Command ID sent from the client. payload - Command payload sent from the client. userData - User data representing the client that sent the command. next - The function to signal the command to move on to the next operation of the same ver and command ID. This function must be called at the end of all operations in the callback. If you pass an error, it will not proceed to the next operations of the same command ver and ID.
func BeforeJoinRoomCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))
BeforeJoinRoomCmd registers a callback function to be executed before join room command:
Parameters
ver - Command ver sent from the client. cmd - Command ID sent from the client. payload - Command payload sent from the client. userData - User data representing the client that sent the command. next - The function to signal the command to move on to the next operation of the same ver and command ID. This function must be called at the end of all operations in the callback. If you pass an error, it will not proceed to the next operations of the same command ver and ID.
func BeforeLeaveRoomCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))
BeforeLeaveRoomCmd registers a callback function to be executed before leave room command:
Parameters
ver - Command ver sent from the client. cmd - Command ID sent from the client. payload - Command payload sent from the client. userData - User data representing the client that sent the command. next - The function to signal the command to move on to the next operation of the same ver and command ID. This function must be called at the end of all operations in the callback. If you pass an error, it will not proceed to the next operations of the same command ver and ID.
func BeforeMessageRoomCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))
BeforeMessageRoomCmd registers a callback function to be executed before message room command:
Parameters
ver - Command ver sent from the client. cmd - Command ID sent from the client. payload - Command payload sent from the client. userData - User data representing the client that sent the command. next - The function to signal the command to move on to the next operation of the same ver and command ID. This function must be called at the end of all operations in the callback. If you pass an error, it will not proceed to the next operations of the same command ver and ID.
func BeforeUpdateRoomPropCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))
BeforeUpdateRoomPropCmd registers a callback function to be executed before update room properties:
Parameters
ver - Command ver sent from the client. cmd - Command ID sent from the client. payload - Command payload sent from the client. userData - User data representing the client that sent the command. next - The function to signal the command to move on to the next operation of the same ver and command ID. This function must be called at the end of all operations in the callback. If you pass an error, it will not proceed to the next operations of the same command ver and ID.
func Broadcast(roomID string, senderUser *user.User, ver uint8, cmd uint16, message []byte, reliable bool)
Broadcast Sends a broadcast message to the other members in the room
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] Multiple broadcast payloads maybe combined and the client must parse the combined payloads BytesToBytesList of Diarkis client SDK. [IMPORTANT] Built-in events such as OnMemberBroadcast handles the separation of combined payloads internally, so the application does not need to handle it by using BytesToBytesList. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID. senderUser - User to send broadcast. ver - Command version to be used as broadcast message. cmd - Command ID to be used as broadcast message. message - Message byte array. reliable - If true, UDP will be RUDP.
func CancelReservation(roomID string, userData *user.User, memberIDs []string, mustBeOwner bool) error
CancelReservation removes reservation per members
[IMPORTANT] This function does not work if the room is not on the same server. [NOTE] Uses mutex lock internally.
Error Cases
┌───────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐ │ Error │ Reason │ ╞═══════════════════════════════╪════════════════════════════════════════════════════════════════════════════════╡ │ Room and/or its owner missing │ It is not possible to cancel reservations if room and/or its owner is missing. │ ├───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ Must be owner │ If mustBeOwner is true, only the room owner is allowed to cancel reservations. │ ├───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ Room not found │ Reservations cannot be canceled if the room is missing. │ ├───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ No reservation │ Cannot cancel reservations if there is no reservation. │ └───────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘
The possible error evaluations:
room.IsCancelReserveError(err error) // Failed to cancel a reservation of a room
Parameters
room ID - Target room ID to cancel a reservation. userData - Owner user to cancel the reservation. memberIDs - An array of user IDs to cancel the reservation for. mustBeOwner - If true userData must be the room owner
func CancelReservationRemote(roomID string, userData *user.User, memberIDs []string, mustBeOwner bool, cb func(error))
CancelReservationRemote removes reservation per members
[IMPORTANT] This function works even if the room is not on the same server. [IMPORTANT] The callback may be invoked on the server where the room is not held. Do not attempt to use functions that works only if the room is on the same server. [NOTE] This function is asynchronous.
Error Cases
┌───────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐ │ Error │ Reason │ ╞═══════════════════════════════╪════════════════════════════════════════════════════════════════════════════════╡ │ Room and/or its owner missing │ It is not possible to cancel reservations if room and/or its owner is missing. │ ├───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ Must be owner │ If mustBeOwner is true, only the room owner is allowed to cancel reservations. │ ├───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ Room not found │ Reservations cannot be canceled if the room is missing. │ ├───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ No reservation │ Cannot cancel reservations if there is no reservation. │ └───────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘
The possible error evaluations:
Besides the following errors, there are Mesh module errors as well.
room.IsCancelReserveError(err error) // Failed to cancel a reservation of a room
Parameters
roomID - Target room ID to cancel a reservation. userData - Owner user to cancel the reservation. memberIDs - An array of user IDs to cancel the reservation for. mustBeOwner - If true userData must be the room owner. cb - Callback function to be invoked when the cancel operation is completed.
func ChangeTTL(roomID string, ttl int64) bool
ChangeTTL changes TTL of the targeted room
[IMPORTANT] This function does NOT work if the room is not on the same server. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID to change its TTL. ttl - New TTL of the room.
func DebugDataDump() []map[string]interface{}
DebugDataDump returns an array of all rooms on the server.
[IMPORTANT] This is for debug purpose only.
func DeleteRoom(roomID string, userData *user.User, ver uint8, cmd uint16, message []byte)
DeleteRoom deletes the target room regardless of the room being not empty and sends notification message to its members.
[IMPORTANT] This function does NOT work if the room is not on the same server. [NOTE] All the members of the room will be automatically kicked out of the room. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID to delete. userData - User that performs the deletion of the room. ver - Command version to send the notification as. cmd - Command ID to send the notification as. message - Message byte array to be sent to the members.
func EnableStateSync( roomID string, updateVer, removeVer uint8, updateCmd, removeCmd uint16, syncInterval, syncAllDelay, ttl int64, combineLimit uint8) bool
EnableStateSync enables and starts state-based synchronization with its members.
All members of the room may update states via UpdateStateByRoomID and they will be synchronized at the interval (in milliseconds) given.
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] You may enable reliable and unreliable state sync simultaneously. [IMPORTANT] If you migrate the room, you MUST use EnableStateSync again with the new roomID. [NOTE] Uses mutex lock internally.
Parameters
roomID - The target room ID of the room to enable sate synchronization. updateVer - Server push command version for property update used when the server sends updates to the member clients. removeVer - Server push command version for property removal used when the server sends removals to the member clients. updateCmd - Server push command ID for property update used when the server sends updates to the member clients. removeCmd - Server push command ID for property removal used when the user sends removals to the member clients. syncInterval - State propagation to all members is handled at a certain interval in milliseconds. syncInterval controls the interval in milliseconds for it. Minimum syncInterval value is 17 milliseconds. syncAllDelay - Delays the invocation of synchronization of all properties in milliseconds. Minimum syncAllDelay is 0 milliseconds. ttl - TTL of each state. If a state does not get updated for more than TTL, the property will be removed internally to save memory. TTL is in milliseconds and the minimum allowed value is 500. By passing TTL lower than the minimum value of 500, you will disable TTL function for properties. combineLimit - Maximum number of outbound synchronization packets to be combined per member. Default is 30.
func Exists(roomID string) bool
Exists return true if the given room ID's room still exists
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID to check if the room exists or not.
func ExposeCommands()
ExposeCommands Exposes TCP or UDP/RUDP commands to execute room functions from the client
This function exposes the following commands to the client:
func ExposePufferCommands()
ExposePufferCommands Exposes TCP or UDP/RUDP puffer commands to execute room functions from the client
This function exposes the following commands to the client:
func GetAllRoomIDsOnNode() []string
GetAllRoomIDsOnNode returns all valid room IDs on the current node
[NOTE] Uses mutex lock internally.
func GetChatHistory(roomID string) [][]string
GetChatHistory returns chat history data as an array
[IMPORTANT] This function does NOT work if the room is not on the same server. [NOTE] Uses mutex lock internally.
func GetCreatedTime(roomID string) int64
GetCreatedTime returns the created time (in seconds) of the room
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [NOTE] Uses mutex lock internally.
func GetMemberByID(roomID string, id string) *user.User
GetMemberByID returns member user by room ID and user ID
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID to get the member *user.User from. id - Target user ID to get *user.User of.
func GetMemberIDs(roomID string) []string
GetMemberIDs returns the list of member IDs (not SIDs)
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [NOTE] Uses mutex lock internally for both room and user.
Parameters
roomID - Target room ID to get the list of member user IDs.
func GetMemberIDsAndOwner(roomID string) ([]string, string, string)
GetMemberIDsAndOwner returns an array of all member IDs and owner ID and ownerSID
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [NOTE] Uses mutex lock internally for both room and user.
Parameters
roomID - Target room ID to get the list of member user IDs and its owner user ID from. Returns member user IDs as an array, owner user ID, and owner user SID.
func GetMemberSIDs(roomID string) []string
GetMemberSIDs returns the list of member SIDs
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID to get a list of member SIDs.
func GetMemberSIDsAndOwner(roomID string) ([]string, string, string)
GetMemberSIDsAndOwner returns an array of all member IDs and owner ID and owner SID
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [NOTE] Uses mutex lock internally for both room and user.
Parameters
roomID - Target room ID to get the list of member SIDs, owner user ID, and owner SID.
Returns an array of member user SIDs, owner user ID, and owner SID.
func GetMemberUsers(roomID string) []*user.User
GetMemberUsers returns the list of member user struct instances
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [NOTE] Uses mutex lock internally. [NOTE] Returned *user.User may be nil if the user has disconnected.
Parameters
roomID - Target room ID to get the list of member userData.
func GetMemberUsersAndOwnerUser(roomID string) ([]*user.User, *user.User)
GetMemberUsersAndOwnerUser returns an array of all member IDs and owner ID
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [NOTE] Uses mutex lock internally. [NOTE] Returned *user.User may be nil if the user has disconnected.
Parameters
roomID - Target room ID to get member *user.User and owner *user.User.
Returns member *user.User as an array and owner *user.User.
func GetNumberOfRoomMembers(roomID string, callback func(err error, currentMembers int, maxMembers int))
GetNumberOfRoomMembers retrieves number of room members.
This can be executed by anyone and they do not have to be part of the room.
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [IMPORTANT] This function works for all users including the users that are not members of the target room.
Parameters
roomID - Target room ID to get the number of members from. callback - Callback to be invoked when the number of current members and max members retrieved. func(err error, currentMembers int, maxMembers int)
func GetProperties(roomID string) map[string]interface{}
GetProperties returns properties of a room
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [IMPORTANT] The fetched property is of map[string]interface{} type. Make sure to use util.GetAsInt, util.GetAsBytes etc. [NOTE] Uses mutex lock internally.
Example
properties := room.GetProperties(roomID) counter, ok := util.GetAsInt(properties, "counter") if !ok { // incorrect data type or the value does not exist } message, ok := util.GetAsBytes(properties, "message") if !ok { // incorrect data type or the value does not exist } flag, ok := util.GetAsBool(properties, "flag") if !ok { // incorrect data type or the value does not exist }
Parameters
roomID - Target room ID of the properties.
func GetProperty(roomID string, name string) interface{}
GetProperty returns a property of the given room and property name. Returns nil if not found.
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [IMPORTANT] The fetched property is of interface{} type. Make sure to use util.ToInt, util.ToBytes etc. [NOTE] Uses mutex lock internally.
Example
property := room.GetProperty(roomID, "counter") // assuming "counter" is an int counter, ok := util.ToInt(property) if !ok { // incorrect data type or the value does not exist }
Parameters
roomID - Target room ID of the properties. name - Property name to retrieve.
func GetRemoteProperties(roomID string, cb func(err error, properties map[string]interface{}))
GetRemoteProperties returns properties of a room
[IMPORTANT] This function works even if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [IMPORTANT] The fetched property is of map[string]interface{} type. Make sure to use util.GetAsInt, util.GetAsBytes etc. [IMPORTANT] The callback may be invoked on the server where the room is not held. Do not use functions that require the room to be on the same server. [NOTE] This function is asynchronous.
Example
room.GetRemoteProperties(roomID func(err error, properties map[string]interface{}) { if err != nil { // handle error here... } // assuming "counter" is an int counter, ok := util.GetAsInt(properties, "counter") if !ok { // incorrect data type of the value does not exist } message, ok := util.GetAsBytes(properties, "message") if !ok { // incorrect data type of the value does not exist } flag, ok := util.GetAsBool(properties, "bool") if !ok { // incorrect data type of the value does not exist } })
Parameters
roomID - Target room ID of the properties. cb - A callback to be invoked when the properties have been fetched.
func GetRemoteProperty(roomID string, name string, cb func(err error, property interface{}))
GetRemoteProperty returns a property of the given room and property name. Returns nil if not found.
[IMPORTANT] This function works even if the room is not on the same server. [IMPORTANT] The fetched property is of interface{} type. Make sure to use util.ToInt, util.ToBytes etc. In order to read the data with the correct data type. [IMPORTANT] The callback may be invoked on the server where the room is not held. Do not use functions that require the room to be on the same server. [NOTE] This function asynchronous.
Operation example:
room.GetRemoteProperty(roomID, "counter", func(err error, property interface{}) { if err != nil { // handle error here... } // assuming "counter" is an int counter, ok := util.ToInt(property) if !ok { // incorrect data type or "counter" does not exist... } }) roomID - Target room ID of the properties. name - Property name to retrieve. cb - A callback to be invoked when the property has been fetched.
func GetRoomID(userData *user.User) string
GetRoomID returns roomID that the user has joined
[IMPORTANT] This function can be used only on the server that the room exists. [NOTE] Uses mutex lock internally.
Parameters
userData - Target user to get the room ID that the user is currently member of.
func GetRoomNodeAddressList(roomID string) ([]string, error)
GetRoomNodeAddressList returns a list of internal node addresses that the room is stored
roomID - Target room ID to extract the server internal node addresses from.
Returns a list of server internal node addresses of the room and error if it fails.
func GetRoomOwnerID(roomID string) string
GetRoomOwnerID returns the user ID of the owner of the room
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID to get the owner from.
func IncrProperty(roomID string, propName string, delta int64) (int64, bool)
IncrProperty increments int64 property by given delta and returns the incremented value.
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function DOES update room's internal TTL.
If the property does not exist, it creates the property.
[NOTE] Uses mutex lock internally.
Cases for return value false
┌──────────────────┬──────────────────────────────────────────────────────┐ │ Error │ Reason │ ╞══════════════════╪══════════════════════════════════════════════════════╡ │ Room not found │ Either invalid room ID given or room does not exist. │ │ Property Corrupt │ Target property data type is not int64. │ └──────────────────┴──────────────────────────────────────────────────────┘
Parameters
roomID - Target room ID. propName - Target property name. delta - Delta value to increment by.
Usage Example
updatedHP, updated := room.IncrProperty(roomID, "HP", damage)
func IsCancelReserveError(err error) bool
IsCancelReserveError returns true if the given error is or contains a RoomCancelReserveError.
func IsFailureError(err error) bool
IsFailureError returns true if the given error is or contains a generic RoomFailureError.
func IsJoinError(err error) bool
IsJoinError returns true if the given error is or contains a RoomJoinError.
func IsLeaveError(err error) bool
IsLeaveError returns true if the given error is or contains a RoomLeaveError.
func IsNewRoomError(err error) bool
IsNewRoomError returns true if the given error is or contains a RoomNewError.
func IsReserveError(err error) bool
IsReserveError returns true if the given error is or contains a RoomReserveError.
func IsReserved(roomID string, uid string) bool
IsReserved returns true if the given uid (User ID) has a reservation with the given room.
[NOTE] Uses mutex lock internally.
func IsRoomFull(roomID string) bool
IsRoomFull returns true if the room is full.
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID to check.
func IsStateUpdateError(err error) bool
IsStateUpdateError returns true if the given error is or contains a RoomStateUpdateError.
func IsStateUpsertError(err error) bool
IsStateUpsertError returns true if the given error is or contains a RoomStateUpsertError.
func IsUserInRoom(roomID string, userData *user.User) bool
IsUserInRoom returns true if the user is in the room
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID to check. userData - Target user to see if the user is in the room.
func Join(roomID string, userData *user.User, ver uint8, cmd uint16, message []byte, callback JoinRoomCallback)
Join joins a room and notify the other members of the room on joining the room.
[NOTE] Uses mutex lock internally. [NOTE] If message is empty, Broadcast will not be sent. [NOTE] This function is asynchronous. What this means is that it involves server-to-server communication internally. [IMPORTANT] The room to join may not be on the same server process and if that is the case, the client will move to where the room is. That means the client will re-connect to a different Diarkis server in the Diarkis cluster. This is handled by Diarkis client SDK. The join will be completed when the user successfully changes the server. [IMPORTANT] The callback is called on the original server that the user client is connected to and the room to join may not be on the same server. Please do not read and/or write room properties in the callback as the room may not be accessible and creates a bug in your application code. Do not use functions that require the room to be on the same server to work. [IMPORTANT] This function works even if the room is on a different server.
Error Cases
┌─────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐ │ Error │ Reason │ ╞═════════════════════════════════════════╪════════════════════════════════════════════════════════════════════════════════╡ │ User is already in another room │ The user is not allowed to join more than one room at a time. │ ├─────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ Node of room not found │ Server of the room is not available in the Diarkis cluster. │ ├─────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ Failed to transfer user │ Transferring the user to the server of the room failed. │ ├─────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ Room not found │ Room to join not found. │ ├─────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ Room join rejected │ SetOnJoinByID and/or SetJoinCondition callback(s) rejected the user to join. │ ├─────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ Not allowed to join without reservation │ The room is room including reservation and the user does not have reservation. │ └─────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘
The possible error evaluations:
Besides the following errors, there are Mesh module errors as well.
room.IsJoinError(err error) // Failed to join a room
roomID - Target room ID to join. userData - User to join the room. ver - Command version to be used for successful join message sent to other room members. cmd - Command ID to be used for successful join message sent to other room members. message - Message byte array to be sent as successful message to other room members. If message is either nil or empty, the message will not be sent. callback - Callback to be invoked when join operation completes (both success and failure). [IMPORTANT] When the user needs to re-connect, the callback is invoked BEFORE the re-connect. In order to capture the actual completion of joining the room, use room.SetOnJoinCompleteByID.
Join operation on the server may send multiple packets to the client.
Here are the details on each packet sent from the server and their order.
▶︎ Re-connect instruction push
This packet is sent from the server when the server requires the client to re-connect to another server.
▶︎ On join response
This packet is always sent from the server when join operation is completed.
ver = 1 cmd = 101
Command ver and ID for on join packet is as shown above:
▶︎ With re-connect instruction:
Join request → Re-connect instruction push → On join response → On member join push
┌──────────────────────────┐ ┌──────────────────┐ │ UDP/TCP server A │ │ UDP/TCP server B │──────────────┐ └──────────────────────────┘ └──────────────────┘ │ ▲ │ │ │ <1> Join request │ │ │ │ │ │ <2> Re-connect instruction push │ │ │ │ │ <3> On join response │ ╭────────╮◀︎───┘ │ │ <4> On member join push │ Client │◀︎───────────────────────────────────────┘ │ ╰────────╯◀︎───────────────────────────────────────────────────────────────────┤ ╭────────╮╮╮ │ Other room members│ Client │││◀︎───────────────────────────────────────────────────────────┘ ╰────────╯╯╯
▶︎ Without re-connect instruction:
Join request → On join response → On member join push
┌────────────────────────────────────┐ ┌─▶︎ │ UDP/TCP server A │────┐ │ └────────────────────────────────────┘ │ │ │ │ │ <1> Join request │ │ │ │ <2> On join response │ │ ▼ │ <3> On member join push │ ╭────────╮ │ └──────────────────│ Client │◀︎────────────────┤ ╰────────╯ │ ╭────────╮╮╮ │ Other room members│ Client │││◀︎──────────────┘ ╰────────╯╯╯
The order of packet and callback change when re-connect or not.
When the user joins a room that exists on a different server, the client is required to re-connect to the server where the room is. Diarkis handles this internally, but it is useful to understand the mechanism behind it.
The diagram below shows the sequence of operations and callbacks as well as where they are executed.
The number in <> indicates the order of execution of callbacks and operations.
┌──────────────────┐ ┌────────────────────────┐ <7> On member join push waits for on join response │ UDP/TCP server A │ │ UDP/TCP server B │─────────────────────────────────────┐ │ │ <2> Join operation │ │ │ │ │─────────────────────▶︎│ │ <6> On join response waits for │ │ │ │ │ SetOnJoinCompleteByID execution │ │ │◀︎─────────────────────│ [ Room A exists here ] │─────────────────────────────┐ │ └──────────────────┘ <3> Join operation └────────────────────────┘ │ │ ▲ callback is ▲ <5> Callback of SetOnJoinCompleteByID is │ │ │ executed on server A │ executed on server B │ │ │ │ │ │ │ <1> Join request │ <4> Re-connect │ │ │ │ Client re-connects to where the room is │ │ ╭────────╮ │ │ │ │ Client │────────────────────────────────────┘ │ │ ╰────────╯◀︎──────────────────────────────────────────────────────────────────────────────────┘ │ ▲ │ │ │ └────────────────────────────────────────────────────────────────────────────────────────────────┤ ╭────────╮╮╮ │ Other room members│ Client │││◀︎─────────────────────────────────────────────────────────────────────────┘ ╰────────╯╯╯
Join operation and its sequences are different when the room to join is on the same server or on a different server.
▶︎ Same Server Join
The sequence below is join operation sequence where the room is on the same server as the user. [ Room is here ] ╭────────╮ ┌──────────┐ │ Client │ │ Server A │ ╰────────╯ └──────────┘ │ │ ┝━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━▶︎[ Join Request ] │ │ │ [ room.SetJoinCondition ] │ │ │ ┌────────┴───┐ │ │ │ [ Join Failure Response ]◀︎━━━━━[ Room Join Failed ] │ --- ( JoinRoomCallback ) │ │ │ │ │ │ │ [ room.SetOnJoinByID ] │ │ │ ┌────────┴───┐ │ │ │ [ Join Failure Response ]◀︎━━━━━━━━━━━━━━━━[ Room Join Failed ] │ --- ( JoinRoomCallback ) │ │ │ │ │ [ Reservation Check ] │ │ │ ┌────────┴───┐ │ │ │ [ Join Failure Response ]◀︎━━━━━━━━━━━━━━━━━━━━[ Room Join Failed ] │ --- ( JoinRoomCallback ) │ │ │ [ room.SetOnJoinByID ] │ │ │ ┌────────┴───┐ │ │ │ [ Join Failure Response ]◀︎━━━━━━━━━━━━━━━━━━━━━━━━[ Room Join Failed ] │ --- ( JoinRoomCallback ) │ │ │ [ room.SetOnRoomChange ] │ │ │ [ room.SetOnJoinCompleteByID ] │ │ │ [ Join Success ] --- ( JoinRoomCallback ) │ │ [ On Join Response ]◀︎━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┥ │ │ [ On Member Join ]◀︎━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┥ On Member Join will be sent to all members. │ │ ▽ ▽
▶︎ Remote Server Join
The sequence below is the operation sequence where the room is on a different server from the user. [ Room is here ] ╭────────╮ ┌──────────┐ ┌──────────┐ │ Client │ │ Server A │ │ Server B │ ╰────────╯ └──────────┘ └──────────┘ │ │ │ ┝━━━━━━━━▶︎[ Join Request ] │ │ │ │ │ ├────────▶︎[ Join Request ] │ │ │ │ │ [ room.SetJoinCondition ] │ │ │ │ │ ┌───┴───┐ │ │ │ │ │ [ Join Failure ]◀︎─────┘ │ --- ( JoinRoomCallback ) on Server A │ │ │ [ Join Failure Response ]◀︎━━━━┥ │ │ │ │ │ │ [ room.SetOnJoinByID ] │ │ │ │ │ ┌───┴───┐ │ │ │ │ │ [ Join Failure ]◀︎─────────┘ │ --- ( JoinRoomCallback ) on Server A │ │ │ [ Join Failure Response ]◀︎━━━━┥ │ │ │ │ │ │ [ Reservation Check ] │ │ │ │ │ ┌───┴───┐ │ │ │ │ │ [ Join Failure ]◀︎─────────────┘ │ --- ( JoinRoomCallback ) on Server A │ │ │ [ Join Failure Response ]◀︎━━━━┥ │ │ │ │ │ │ [ room.SetOnJoinByID ] │ │ │ │ │ ┌───┴───┐ │ │ │ │ │ [ Join Failure ]◀︎─────────────────┘ │ --- ( JoinRoomCallback ) on Server A │ │ │ [ Join Failure Response ]◀︎━━━━┥ │ │ │ │ │ │ [ room.SetOnRoomChange ] │ │ │ │ [ Join Success ]◀︎────────────────────────┤ --- ( JoinRoomCallback ) on Server A │ │ │ [ Re-connect Instruction ]◀︎━━━┥ Disconnect from Server A. │ │ │ │ ┝━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━▶︎[ Re-connect ] │ │ │ [ On Connect ]◀︎━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┥ │ │ │ │ │ [ room.SetOnJoinCompleteByID ] │ │ │ │ │ [ Join Success ] │ │ │ [ On Join Response ]◀︎━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┥ │ │ │ [ On Member Join ]◀︎━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┥ On Member Join will be sent to all members. │ │ │ ▽ ▽ ▽
func Leave(roomID string, userData *user.User, ver uint8, cmd uint16, message []byte) error
Leave Leaves from a room and notify the other members on leaving. If message is empty Broadcast will not be sent.
[NOTE] Uses mutex lock internally. [IMPORTANT] This function does not work if the room is not on the same server. [IMPORTANT] When a member user of a room disconnects unexpectedly, the room will automatically detect the leave of the user and sends on leave message to the reset of the member users. The message contains room ID and the user ID that disconnected. In order to have custom message for this behavior, use SetOnDiscardCustomMessage.
Error Cases
┌──────────────────────────┬─────────────────────────────────────────────────────┐ │ Error │ Reason │ ╞══════════════════════════╪═════════════════════════════════════════════════════╡ │ Room not found │ Room to leave from is not found. │ ├──────────────────────────┼─────────────────────────────────────────────────────┤ │ The user is not a member │ The user is not a member of the room to leave from. │ └──────────────────────────┴─────────────────────────────────────────────────────┘
The possible error evaluations:
room.IsLeaveError(err error) // Failed to leave from a room
Parameters
roomID string - Target room ID to leave from. userData *user.User - User that will be leaving the room. ver uint8 - Command version to be used for message sent when leave is successful. cmd uint16 - Command ID to be used for message sent when leave is successful. message []byte - Message byte array to be sent as successful message to other room members. If message is either nil or empty, the message will not be sent.
func Message(roomID string, memberIDs []string, senderUser *user.User, ver uint8, cmd uint16, message []byte, reliable bool)
Message Sends a message to selected members of the room
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] All message payloads have leading 4-byte-long header. The client must skip the first 4 bytes. [IMPORTANT] Built-in events such as OnMemberMessage handles the separation of combined payloads internally, so the application does not need to handle it by using BytesToBytesList. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID. memberIDs - An array of member user IDs to send message to. senderUser - User to send broadcast. ver - Command version to be used as broadcast message. cmd - Command ID to be used as broadcast message. message - Message byte array. reliable - If true, UDP will be RUDP.
func MigrateRoom(ver uint8, cmd uint16, userData *user.User, callback func(err error, newRoomID string, oldRoomID string))
MigrateRoom migrates a room to another node and moves its members to the new room.
This is intended to be used when the current node is about to shutdown (in offline state), but you need to keep the current room.
[IMPORTANT] This function does not work if the room is not on the same server. [IMPORTANT] Migration will change the room ID. [IMPORTANT] The callback may be invoked on the server where the room is not held. Do not use functions that requires the room to be on the same server. [NOTE] Uses mutex lock internally. [NOTE] This function is asynchronous.
Error Cases
┌─────────────────────────────────────────┬────────────────────────────────────────────────────────────────────┐ │ Error │ Reason │ ╞═════════════════════════════════════════╪════════════════════════════════════════════════════════════════════╡ │ Node (server) to migrate room not found │ The server to migrate the room to is not found. │ │ Must be owner │ Only the room owner is allowed to perform room migration. │ │ User transfer failed │ The owner user failed to transfer to another server for migration. │ └─────────────────────────────────────────┴────────────────────────────────────────────────────────────────────┘
Parameters
ver - Command ver to send the new migrated room ID to all members as migration instruction. cmd - Command ID to send the new migrated room ID to all members as migration instruction. userData - Owner user to perform the migration. callback - Invoked when migration operation is completed.
When a room is migrated to another server, the users of the room will be re-connected to the server where the room is migrated. This is handled by Diarkis internally, but it is useful to understand the mechanism of it.
The diagram below shows the sequence of operations and callbacks as well as where they are executed.
The number in < > indicates the order of execution of callbacks and operations.
┌────────────────────────┐ ┌────────────────────────┐ │ UDP/TCP server A │ <2> Migrate │ UDP TCP server B │ │ │──────────────────▶︎│ │ │ [ Room A exists here ] │ │ [ Room A migrated ] │ <3> SetOnMigrated is executed on server B │ │ │ │ Re-join will take place └────────────────────────┘ └────────────────────────┘ AFTER the execution of SetOnMigrated ▲ │ ▲ │ └───────────┐ │ │ <1> Migrate │ │ <5> Re-join: │ │ │ Each member must leave the previous room (room before the migration) and │ │ │ join the new migrated room by the room ID pushed from the server. │ │ │ (All members of the room will reconnect asynchronously) │ ┌───────────────┘ │ │ │ <4> New migrated room ID notification │ │ │ (All members of the room will receive │ │ │ the new migrated room ID asynchronously) │ │ ▼ │ ╭────────╮ │ │ Client │───────────────────────────────────────────────────┘ ╰────────╯(Client re-connects to where the migrated room is via executing Join)
The owner of the room will NOT receive on join event response (cmd:101) from the server. Instead, the owner will receive on migration complete event push (cmd:20) from the server when the owner user completes the server re-connection.
╭────────╮ ┌──────────┐ ┌──────────┐ │ Client │ │ Server A │ │ Server B │ ╰────────╯ └──────────┘ └──────────┘ │ │ │ ┝━━━━━━━━━━━━━━━━━▶︎[ Migration Request ] │ │ │ │ │ ├───────────▶︎[ Migration ] Room is copied here with the new room ID. │ │ │ │ │ [ SetOnMigrated Callback Invoked ] │ │ │ │ [ Migration Confirmation ]◀︎───────┤ │ │ │ [ Migration Instruction ]◀︎━━━━━━━━┥(ver: custom) │ Migration Instruction contains the new room ID. │ │(cmd: custom) │ │ │ │ ┝━━━━━━━━━━━━▶︎[ Leave From Previous Room ] │ The user leaves the previous room. │ │ │ │ │ │ [ Leave Confirmation ]◀︎━━━━━━━━━━━┥ │ │ │ │ ┝━━━━━━━▶︎[ Join Request To Migrated Room ] │ The user joins the new migrated room. │ │ │ │ ├────────────▶︎[ Join ] │ │ │ │ [ Join Confirmation ]◀︎─────────┤ │ │ │ [ Re-connect Instruction ]◀︎━━━━━━━┥ │ │ │ │ ┝━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━▶︎[ Re-connect ] │ │ │ │ │ │ [ Migration Confirmation ]◀︎━━━━━━━━━━━━━━━━━━━━━━━━━┥ For owner user: cmd=20 on migration complete │ │ │ ▽ ▽ ▽
Non-owner user WILL receive on join event response (cmd:101) from the server when completing the server re-connection.
╭────────╮ ┌──────────┐ ┌──────────┐ │ Client │ │ Server A │ │ Server B │ ╰────────╯ └──────────┘ └──────────┘ │ │ │ ┝━━━━━━━━━━━━━━━━━▶︎[ Migration Request ] │ │ │ │ │ ├───────────▶︎[ Migration ] Room is copied here with the new room ID. │ │ │ │ │ [ SetOnMigrated Callback Invoked ] │ │ │ │ [ Migration Confirmation ]◀︎───────┤ │ │ │ [ Migration Instruction ]◀︎━━━━━━━━┥(ver: custom) │ Migration Instruction contains the new room ID. │ │(cmd: custom) │ │ │ │ ┝━━━━━━━━━━━━▶︎[ Leave From Previous Room ] │ The user leaves the previous room. │ │ │ │ │ │ [ Leave Confirmation ]◀︎━━━━━━━━━━━┥ │ │ │ │ ┝━━━━━━━▶︎[ Join Request To Migrated Room ] │ The user joins the new migrated room. │ │ │ │ ├────────────▶︎[ Join ] │ │ │ │ [ Join Confirmation ]◀︎─────────┤ │ │ │ [ Re-connect Instruction ]◀︎━━━━━━━┥ │ │ │ │ ┝━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━▶︎[ Re-connect ] │ │ │ │ │ │ [ Join Confirmation ]◀︎━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┥ Treat join confirmation as migration confirmation. │ │ │ ▽ ▽ ▽
func NewRoom(userData *user.User, maxMembers int, allowEmpty bool, join bool, ttl int64, interval int64) (string, error)
NewRoom Creates a new room
[NOTE] Uses mutex lock internally. [NOTE] This function creates a new room on the same server as it is invoked.
Error Cases:
┌───────────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────┐ │ Error │ Reason │ ╞═══════════════════════════════╪═══════════════════════════════════════════════════════════════════════════════════════════╡ │ allowEmpty and join are false │ If allowEmpty and join are bot false, the room will be deleted immediately. │ ├───────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────┤ │ Server is offline │ The server is in offline state (getting ready to shutdown) │ │ │ and creating new rooms is not allowed. │ ├───────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────┤ │ Invalid TTL │ TTL must be greater than 0 second. │ ├───────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────┤ │ User in another room │ You may not join more than one room at a time. │ ├───────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────┤ │ Max member is invalid │ The range of max member is from 2 to 1000. │ └───────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────┘
The possible error evaluations:
room.IsNewRoomError(err error) // Room module failed to create a new room
Parameters
userData - User data struct. If you do not have user available, you may use a dummy user created by user.CreateBlankUser. Using a dummy user allows you to create an empty room without having the access to a user. With a dummy user, you must have allowEmpty=true, join=false. maxMembers - Maximum number of members allowed to join the room allowEmpty - If true, the room will not be deleted until TTL expires even if all members leave join - If true, the creator user will join the room automatically ttl - TTL of the room when it is empty in seconds. The value must be greater than 0. Minimum is 10 seconds interval - Broadcast interval in milliseconds. Interval below 100ms will be forced to 0. If it's 0, no packet merge
func Relay(roomID string, sender *user.User, ver uint8, cmd uint16, message []byte, reliable bool) bool
Relay sends a message to all members of the room except for the sender.
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] Unlike Broadcast, Message, and Announce, Relay does not combine multiple messages. Therefore, the message sent does not have to be separated by BytesToBytesList on the client side. [IMPORTANT] Unlike Broadcast, Message, and Announce, Relay does not send the message to the sender user. [NOTE] Uses mutex lock internally.
Parameters
roomID - Room ID of the room to send relay message to. sender - Sender user. The sender user must be a member of the room. ver - Command version of the message sent to the members of the room. cmd - Command ID of the message sent to the members of the room. message - Message to be sent to the members of the room. reliable - If true, the message will be sent as an RUDP if the network protocol is UDP. If the network protocol used is TCP, this flag is ignored.
func RelayTo(roomID string, sender *user.User, members []string, ver uint8, cmd uint16, message []byte, reliable bool) bool
RelayTo sends a message to selected members of the room except for the sender.
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] Unlike Broadcast, Message, and Announce, RelayTo does not combine multiple messages. Therefore, the message sent does not have to be separated by BytesToBytesList on the client side. [IMPORTANT] Unlike Broadcast, Message, and Announce, Relay does not send the message to the sender user. [NOTE] Uses mutex lock internally.
Parameters
roomID - Room ID of the room to send relay message to. sender - Sender user. The sender user must be a member of the room. members - An array of target member user IDs to send relay message to. ver - Command version of the message sent to the members of the room. cmd - Command ID of the message sent to the members of the room. message - Message to be sent to the members of the room. reliable - If true, the message will be sent as an RUDP if the network protocol is UDP. If the network protocol used is TCP, this flag is ignored.
func RemoveStateByRoomID(roomID string, userData *user.User, key string, reliable bool) bool
RemoveStateByRoomID removes a state property and synchronize its removal to all members of the room.
ver and cmd will be used as command ver and command ID when synchronizing with the room members.
User must be a member of the room to use this function.
[IMPORTANT] This function does NOT work if the room is not on the same server. [NOTE] Uses mutex lock internally.
Parameters
roomID - The target room ID of the room to remove a state from. userData - Room member user to perform state removal. key - State key to be removed. reliable - If true, synchronization for UDP communication will be RUDP.
func Reserve(roomID string, userData *user.User, memberIDs []string, mustBeOwner bool) error
Reserve the user may reserve a slot in a room so that it will be guaranteed to join the room later.
[IMPORTANT] This function does not work if the room is not on the same server. [NOTE] Uses mutex lock internally.
Error Cases
┌──────────────────────────────┬──────────────────────────────────────────────────────────────────────────────┐ │ Error │ Reason │ ╞══════════════════════════════╪══════════════════════════════════════════════════════════════════════════════╡ │ memberIDs array is empty │ No member IDs to make reservations with. │ ├──────────────────────────────┼──────────────────────────────────────────────────────────────────────────────┤ │ Room or room owner not found │ Cannot make a reservation if the room and/or its owner is missing. │ ├──────────────────────────────┼──────────────────────────────────────────────────────────────────────────────┤ │ Must be owner │ If mustBeOwner is true, only the room owner is allowed to make reservations. │ ├──────────────────────────────┼──────────────────────────────────────────────────────────────────────────────┤ │ Room not found │ Cannot make a reservation if the room is missing. │ ├──────────────────────────────┼──────────────────────────────────────────────────────────────────────────────┤ │ Exceeds max members │ Make reservations that exceeds max members of the room is not allowed. │ ├──────────────────────────────┼──────────────────────────────────────────────────────────────────────────────┤ │ Reservation is full │ There is no more room for reservations. │ └──────────────────────────────┴──────────────────────────────────────────────────────────────────────────────┘
The possible error evaluations:
room.IsReserveError(err error) // Failed to make a reservation of a room
Parameters
roomID - Target room ID to make a reservation. userData - Owner user of the room to make a reservation. memberIDs - An array of user IDs to make a reservation for. mustBeOwner - If true, userData must be the owner of the room.
func SetChatHistoryLimit(roomID string, limit int) bool
SetChatHistoryLimit sets the chat history maximum length
[IMPORTANT] This function does NOT work if the room is not on the same server. [NOTE] Uses mutex lock internally.
func SetJoinCondition(cond func(roomID string, userData *user.User) error)
SetJoinCondition registers a condition function to control room join. Returning an error will cause room join to fail
Join condition is NOT protected by mutex lock.
SetJoinCondition(condition func(roomID string, userData *user.User)) cond func(roomID string, userData *user.User) error - Custom function to be invoked before room join to evaluate join conditions.
func SetOnAnnounce(roomID string, cb func(string, uint8, uint16, []byte)) bool
SetOnAnnounce assigns a listener callback on Announce of room
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [IMPORTANT] This function does NOT work if the room is not on the same server. [NOTE] Uses mutex lock internally. [NOTE] ver and cmd passed to the callback are the ver and cmd used to send Broadcast or Message.
It captures Broadcast and Message as well
roomID string - Target room ID. cb - func(roomID, ver uint8, cmd uint16, message []byte) - Callback to be invoked on every Broadcast and Message. Usage Example: Useful when capturing and sending the message data to external database or service.
func SetOnChatMessage(roomID string, callback func(*user.User, string) bool) bool
SetOnChatMessage assigns a callback to be invoked before synchronizing a chat message.
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [IMPORTANT] This function does NOT work if the room is not on the same server. [NOTE] Uses mutex lock internally.
Return false will reject the incoming chat message and rejected chat message will NOT be sent to other members.
func SetOnClock(roomID string, name string, interval int64, callback func(roomID string)) bool
SetOnClock assigns a custom callback to be invoked at a given interval until it is stopped by ClockStop callback
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID of the room to have a clock callback loop name - Unique name of the clock callback. Duplicates will be ignored interval - Clock interval in seconds callback - Callback function to be invoked
func SetOnClockStop(roomID string, name string, callback func(string)) bool
SetOnClockStop assigns a callback to be invoked when a clock callback is stopped by StopClock
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID of the room to stop the clock callback name - Unique name of the clock to stop callback - Callback function to be invoked when clock is stopped by StopClock
func SetOnCustomUserDiscardByID(roomID string, callback func(roomID string, userData *user.User) (uint8, uint16, []byte)) bool
SetOnCustomUserDiscardByID registers a callback to be executed when a room member disconnects unexpected.
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [CRITICALLY IMPORTANT] If the callback blocks, it will NOT allow the room to execute Leave when the user is disconnected. [NOTE] Uses mutex lock internally.
The purpose of this callback is to use custom command ver, cmd, and message data to be sent to other members.
func SetOnDiscardCustomMessage(custom func(string, string, string) []byte) bool
SetOnDiscardCustomMessage sets a custom function to create a custom message on user discard to be sent to members The callback receives roomID string, user ID string, user SID string
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. custom func(roomID string, userID string, userSID string) []byte - Custom function to create a custom message byte array to be sent to other members. When the member client disconnects and leave.
func SetOnJoinByID(roomID string, callback func(roomID string, userData *user.User) bool) bool
SetOnJoinByID registers a callback to be executed just before the join operation to evaluate, if the user should join or not.
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [CRITICALLY IMPORTANT] If the callback blocks, the room will NOT execute Join that follows. [NOTE] Uses mutex lock internally.
Returning value false will cause the join operation to fail.
When joining a room that is on a different server, the client is required to re-connect to the server where the room is. This is handle by Diarkis internally.
Diagram below shows where the callback of SetOnJoinByID is executed.
┌──────────────────┐ ┌────────────────────────┐ │ UDP/TCP server A │ <2> Join │ UDP/TCP server B │ │ │───────────▶︎│ [ Room A exists here ] │ └──────────────────┘ └────────────────────────┘ ▲ <3> Callback of SetOnJoinByID is executed on server B │ │ <1> Join │ ╭────────╮ │ Client │ ╰────────╯
func SetOnJoinCompleteByID(roomID string, callback func(roomID string, userData *user.User)) bool
SetOnJoinCompleteByID registers a callback on join operation complete.
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [NOTE] Uses mutex lock internally.
When joining a room that is on a different server, the client is required to re-connect to the server where the room is. This is handle by Diarkis internally.
The diagram below explains where the callback of SetOnJoinCompleteByID is executed when the client re-connects:
The number in < > indicates the order of execution of callbacks and operations.
┌──────────────────┐ ┌────────────────────────┐ │ UDP/TCP server A │ <2> Join │ UDP/TCP server B │ │ │───────────▶︎│ [ Room A exists here ] │ └──────────────────┘ └────────────────────────┘ ▲ ▲ <4> Callback of SetOnJoinCompleteByID is on server B │ │ │ <1> Join │ <3> Re-connect │ │ ╭────────╮ │ │ Client │────────────────────────────────┘ ╰────────╯ Client re-connects to where the room is SetOnJoinCompleteByID waits until the client completes re-connection to the new server and finishes the join operation.
func SetOnLeaveByID(roomID string, callback func(roomID string, userData *user.User)) bool
SetOnLeaveByID registers a callback on leave
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [CRITICALLY IMPORTANT] The callbacks are invoked in room.Leave function. If a callback blocks, room.Leave will block also. [NOTE] Uses mutex lock internally.
func SetOnMigrated(callback func(currentRoomID string, previousRoomID string))
SetOnMigrated registers a callback on migrated. The callbacks will be invoked on the server node where the room is migrated to
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. callback - A callback to be invoked when migration is successful.
func SetOnRoomChange(cb func(string, int, []string, map[string]interface{})) bool
SetOnRoomChange registers a callback function on room change such as create, join, leave, property updates
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [IMPORTANT] This function does NOT work if the room is not on the same server.
Parameters
cb - Callback cb func(roomID string, changeEvent int, memberUserIDs []string, roomProperties map[string]interface{}) changeEvent is an enum value that tells us what change took place: room.MemberAdded, room.MemberRemoved, room.PropertyChanged
func SetOnRoomChangeByID(roomID string, cb func(roomID string, changeEvent int, memberIDs []string, properties map[string]interface{})) bool
SetOnRoomChangeByID registers a callback function on room change such as create, join, leave, property updates
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [IMPORTANT] This function does NOT work if the room is not on the same server. changeEvent is an enum value that tells us what change took place: room.MemberAdded, room.MemberRemoved, room.PropertyChanged cb func(roomID string, changeEvent int, memberUserIDs []string, roomProperties map[string]interface{})
func SetOnRoomDiscard(cb func(roomID string)) bool
SetOnRoomDiscard registers a callback function on room deletions
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. cb func(roomID string) - Function to be invoked on room's deletion.
func SetOnRoomDiscardByID(roomID string, callback func(roomID string)) bool
SetOnRoomDiscardByID registers a callback on room deletion by room ID
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [IMPORTANT] This function does NOT work if the room is not on the same server. [NOTE] Uses mutex lock internally.
func SetOnRoomOwnerChange(cb func(roomID string, ownerID string))
SetOnRoomOwnerChange sets a callback for room owner change
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] The owner ID may be an empty string. [NOTE] Uses mutex lock internally.
Parameters
cb func(roomID string, ownerID string) - Callback to be invoked when the room owner changes.
func SetOnRoomPropertyUpdate(cb func(roomID string, props map[string]interface{}))
SetOnRoomPropertyUpdate sets a callback for room property updates.
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [IMPORTANT] This function does NOT work if the room is not on the same server. [NOTE] Uses mutex lock internally.
Parameters
cb func(roomID string, properties map[string]interface{}) - Callback to be invoked when room property changes.
func SetOnTick(roomID string, callback func(string)) bool
SetOnTick registers a callback on every 5 seconds tick on a room
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [IMPORTANT] If you access room properties in the callback, it updates the TTL of the room internally. It means that as long as the callback keeps accessing the properties, it will keep the room from being deleted beyond its TTL. [NOTE] Uses mutex lock internally.
Parameters
roomID string - Target room ID to set a tick callback. callback func(roomID string) - Callback to be invoked at every tick.
Usage Example: Use this to call matching.Add so that you may keep the room available for matchmaking as long as you with.
func SetOnTickStop(roomID string, callback func(string)) bool
SetOnTickStop assigns a callback to be invoked when room tick stops
[CRITICALLY IMPORTANT] Using pointer variables that are defined outside of the callback closure in the callback closure will cause those pointers to be not garbage collected leading to memory leak. [NOTE] Uses mutex lock internally.
Parameters
roomID string - Target room ID callback func(string) - Callback to be invoked on tick stop. The callback passes roomID
func SetProperty(roomID string, name string, value interface{}) bool
SetProperty assigns a value to the target room associated with the given name. If the property already exists, it will overwrite it.
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [IMPORTANT] Room properties do NOT support structs. [IMPORTANT] Numeric properties will be float64. Use util.ToInt, ToUint etc. To convert to proper data type. [IMPORTANT] Array properties will be []interface{}. Must apply type assertion per element. [IMPORTANT] Byte array properties will be converted to base64 encoded string. Use util.ToBytes() to convert it back. [NOTE] If there is a value associated with the name, the value will be replace. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID name - Property name to set the value as value - Property value to be associated with the name
func SetRollbackOnJoinFailureByID(roomID string, callback func(roomID string, userData *user.User)) bool
SetRollbackOnJoinFailureByID registers a callback to perform rollback operations on join failure
[NOTE] Uses mutex lock internally.
func Setup()
Setup Sets up room package but without any server association
func SetupAsTCPServer()
SetupAsTCPServer Sets up room package
func SetupAsUDPServer()
SetupAsUDPServer Sets up room package
func SetupBackup(backupNum int)
SetupBackup Enables room data backup to different nodes - maximum backup nodes you can set is 2
backupNum int - Number of backup servers.
func StopClock(roomID string, name string) bool
StopClock stops a clock callback loop
[NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID of the room to stop the clock callback name - Unique name of the clock to stop
func StopTick(roomID string)
StopTick stops room's tick event loop
[NOTE] Uses mutex lock internally.
func SyncAllStatesByRoomID(roomID string, userData *user.User, reliable bool) bool
SyncAllStatesByRoomID synchronizes all existing states to the target user client.
Invoking this function will forcefully send all existing states to the targeted user client.
[IMPORTANT] This function does NOT work if the room is not on the same server. [NOTE] Uses mutex lock internally.
Parameters
roomID - The target room ID of the room. userData - Room member user to receive all state synchronizations. reliable - If true, synchronization for UDP communication will be RUDP.
func SyncChatMessage(roomID string, userData *user.User, ver uint8, cmd uint16, message string) bool
SyncChatMessage records the chat message data and synchronize the chat message with room members
[IMPORTANT] This function does NOT work if the room is not on the same server. [NOTE] Uses mutex lock internally.
func SyncCreateTime(roomID string, ver uint8, cmd uint16, memberIDs []string)
SyncCreateTime sends room's created time (in seconds) to the selected (or all) members of the room
[IMPORTANT] This function does NOT work if the room is not on the same server. [NOTE] Uses mutex lock internally.
Parameters
roomID - Target room ID. ver - Command version to be used for the message. cmd - Command ID to be used for the message. memberIDs - An array of member user IDs to sync the room creation time.
func UpdateProperties(roomID string, operation func(properties map[string]interface{}) bool) map[string]interface{}
UpdateProperties updates or creates properties of a room and returns the updated or created properties.
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function DOES update room's internal TTL. [IMPORTANT] Room properties do NOT support structs. [IMPORTANT] Numeric properties will be float64. Use util.ToInt, ToUint etc. To convert to proper data type. [IMPORTANT] Array properties will be []interface{}. Must apply type assertion per element. [IMPORTANT] Byte array properties will be converted to base64 encoded string. Use util.ToBytes() to convert it back. [IMPORTANT] Operation function is protected by mutex lock, using another mutex lock within the function may cause a deadlock. [NOTE] Uses mutex lock internally.
Operation example:
var updateErr error _ := room.UpdateProperties(roomID, func(properties map[string]interface{}) { capsule := datacapsule.NewCapsule() err := capsule.Import(properties["roomPropertyCapsule"].(map[string]interface{})) if err != nil { // this is how to propagate an error updateErr = err return } counter := capsule.GetAsInt("counter") counter++ capsule.SetAsInt("counter", counter) properties["roomPropertyCapsule"] = capsule.Export() }) if updateErr != nil { // handle update error here }
Use datacapsule.Capsule as property:
capsule := datacapsule.NewCapsule() capsule.SetAsInt8("memberNum", memberNum) properties["memberNum"] = capsule.Export() // setting capsule as a property
Parameters
roomID - Room ID to update its properties. operation - Callback function to perform update operations and returns updated properties as a map. Must return true, when property (properties) is updated and false when there is no update.
func UpdateStateByRoomID(roomID string, userData *user.User, key string, value []byte, linkToUser, reliable bool) error
UpdateStateByRoomID updates/creates a state property and synchronize its value to all members of the room.
ver and cmd will be used as command ver and command ID when synchronizing with the room members.
User must be a member of the room to use this function.
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] Size of the state value and key combined should not exceed 40 bytes in length. [IMPORTANT] If a state is updated multiple times before synchronized, only the last updated value will be synchronized. [NOTE] Uses mutex lock internally.
Error Cases:
┌─────────────────────────────────────┬──────────────────────────────────────────────────────────────────┐ │ Error │ Reason │ ╞═════════════════════════════════════╪══════════════════════════════════════════════════════════════════╡ │ Room not found │ The room tarted to update its state not found or does not exist. │ ├─────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤ │ Room state synchronizer not started │ EnableStateSync must be called to enable state synchronization. │ ├─────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤ │ User must be a member of the room │ The user that updates room state must be a member of the room. │ ├─────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤ │ Invalid value │ The value must not be nil or an empty byte array. │ └─────────────────────────────────────┴──────────────────────────────────────────────────────────────────┘
The possible error evaluations:
room.IsStateUpdateError(err error) // Failed to update a room state
Parameters
roomID - Target room ID of the room to update its state. userData - The user that is updating a state of the target room. If linkToUser flag is set to true, the state will be associated to the user and will be removed when the user leaves the room. key - Key represents the name of the state to be updated. value - Value is used to replace the previous state value. linkToUser - If the flag is set to true, the state will be linked to the user given. When the linked user leaves the room all linked states will be removed. reliable - If true, synchronization for UDP communication will be RUDP.
func UpsertStateByRoomID(roomID string, userData *user.User, key string, reliable bool, cb func(exists bool, current []byte) []byte) error
UpsertStateByRoomID updates/creates a state property and synchronize its value to all members of the room.
ver and cmd will be used as command ver and command ID when synchronizing with the room members.
User must be a member of the room to use this function.
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] Size of the state value and key combined should not exceed 40 bytes in length. [IMPORTANT] If a state is updated multiple times before synchronized, only the last updated value will be synchronized. [IMPORTANT] The callback is invoked while the mutex lock is held and release when the callback finishes its execution. [NOTE] Uses mutex lock internally.
Error Cases:
┌───────────────────────────────────────┬────────────────────────────────────────────────────────────────────────┐ │ Error │ Reason │ ╞═══════════════════════════════════════╪════════════════════════════════════════════════════════════════════════╡ │ Room not found │ The room tarted to update its state not found or does not exist. │ ├───────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┤ │ Room state synchronizer not started │ EnableStateSync must be called to enable state synchronization. │ ├───────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┤ │ User must be a member of the room │ The user that updates room state must be a member of the room. │ ├───────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┤ │ State value is not updated nor stored │ Upsert callback's return value must not be nil or an empty byte array. │ └───────────────────────────────────────┴────────────────────────────────────────────────────────────────────────┘
The possible error evaluations:
room.IsStateUpsertError(err error) // Failed to upsert a room state
Parameters
roomID - Target room ID of the room to update its state. userData - The user that is updating a state of the target room. If linkToUser flag is set to true, the state will be associated to the user and will be removed when the user leaves the room. key - Key represents the name of the state to be updated. cb - Callback function to perform upsert operation. The returned value will be used to upsert the value for the key. If the returned value's length is 0, it will not upsert at all. func(exists bool, current []byte) []byte exists - If true, the state of the given key exists. current - The current value of the state. The returned byte array of the callback will be the value of the state. reliable - If true, synchronization for UDP communication will be RUDP.
UpsertStateByRoomID is useful when you need to reference the value of a state that already exists and update its value based on the current value without the risk of race conditions. The concept is very similar to select for update SQL query.
// this will be the damage inflicted on the state called HP damage := uint32(-40) err := room.UpsertStateByRoomID(roomID, userData, "HP", true, func(exists bool, currentValue []byte) (updatedValue []byte) { // HP state does not exist yet, initialize it if !exists { // initial HP is 100 hp := uint32(100) // state value must be a byte array bytes := make([]byte, 4) binary.BigEndian.PutUint32(bytes, hp) // returning bytes will set bytes as HP state's value return bytes } // calculate HP state's new value currentHP := binary.BigEndian.Uint32(currentValue) currentHP += damage // encode the updated HP back to byte array bytes := make([]byte, 4) binary.BigEndian.PutUint32(bytes, currentHP) // returning bytes will set bytes as HP state's value return bytes }) if err != nil {
UpsertStateByRoomID failed, handle the error here...
}
DataDump implies a payload format for the dump room data command
type DataDump struct { ID string `json:"RoomID"` MaxMembers int `json:"MaxMembers"` AllowEmpty bool `json:"AllowEmpty"` MemberIDs map[string]string `json:"MemberIDs"` Properties map[string]interface{} `json:"Properties"` }
JoinRoomCallback is callback function for room.Join.
[IMPORTANT] This callback function is invoked on the server where the user is "originally" connected. room.Join may move the user to a different server if the room that the user is joining is not on the same server. When the user is moved to another server, this callback function is invoked on the server where the user was originally connected.
type JoinRoomCallback func(err error, memberIDs []string, ownerID string, createdTime int64)
Room Room data structure
type Room struct { ID string MaxMembers int AllowEmpty bool // an array of member SIDs Members []string // ID as key and SID as value MemberIDs map[string]string // contains filtered or unexported fields }
func GetRoomByID(roomID string) *Room
GetRoomByID returns a room
[IMPORTANT] This function does NOT work if the room is not on the same server. [IMPORTANT] This function does NOT update room's internal TTL. [NOTE] Uses mutex lock internally. [NOTE] This will not update TTL of the room.
Parameters
roomID - Target room ID to get the room object.