Skip to content

Commit

Permalink
0.13.0 (#115)
Browse files Browse the repository at this point in the history
* fixed source style of WebSocket, added forst working message queue

* rewriting OnMessage to support messages by type

* use casting on Action<> to return typed value colyseus/colyseus#315

* initial version for typed room.OnMessage(). refactor error codes. #113

* implement Send() and OnMessage(). closes #113

* fixes for webgl build

* remove deprecated 'enqueuedCalls' for Connection. fixes conditional compilation for WEBGL

* fix: allow receiving messages without payload

* avoid re-allocating bytes when decoding msgpack objects

Co-authored-by: AJ <aj.3dev@gmail.com>
  • Loading branch information
endel and AJ92 committed Apr 22, 2020
1 parent b8505f9 commit 8b32c03
Show file tree
Hide file tree
Showing 19 changed files with 691 additions and 451 deletions.
119 changes: 51 additions & 68 deletions Assets/ColyseusClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ class CustomData
public string str;
}

class TypeMessage
{
public bool hello;
}

enum MessageType {
ONE = 0
};
class MessageByEnum
{
public string str;
}

public class ColyseusClient : MonoBehaviour {

// UI Buttons are attached through Unity Inspector
Expand Down Expand Up @@ -93,61 +106,19 @@ async void ConnectToServer ()
public async void CreateRoom()
{
room = await client.Create<State>(roomName, new Dictionary<string, object>() { });

m_SessionIdText.text = "sessionId: " + room.SessionId;

room.State.entities.OnAdd += OnEntityAdd;
room.State.entities.OnRemove += OnEntityRemove;
room.State.entities.OnChange += OnEntityMove;

PlayerPrefs.SetString("roomId", room.Id);
PlayerPrefs.SetString("sessionId", room.SessionId);
PlayerPrefs.Save();

room.OnLeave += (code) => Debug.Log("ROOM: ON LEAVE");
room.OnError += (message) => Debug.LogError(message);
room.OnStateChange += OnStateChangeHandler;
room.OnMessage += OnMessage;
RegisterRoomHandlers();
}

public async void JoinOrCreateRoom()
{
room = await client.JoinOrCreate<State>(roomName, new Dictionary<string, object>() { });

m_SessionIdText.text = "sessionId: " + room.SessionId;

room.State.entities.OnAdd += OnEntityAdd;
room.State.entities.OnRemove += OnEntityRemove;
room.State.entities.OnChange += OnEntityMove;

PlayerPrefs.SetString("roomId", room.Id);
PlayerPrefs.SetString("sessionId", room.SessionId);
PlayerPrefs.Save();

room.OnLeave += (code) => Debug.Log("ROOM: ON LEAVE");
room.OnError += (message) => Debug.LogError(message);
room.OnStateChange += OnStateChangeHandler;
room.OnMessage += OnMessage;
RegisterRoomHandlers();
}

public async void JoinRoom ()
{
room = await client.Join<State>(roomName, new Dictionary<string, object>() {});

m_SessionIdText.text = "sessionId: " + room.SessionId;

room.State.entities.OnAdd += OnEntityAdd;
room.State.entities.OnRemove += OnEntityRemove;
room.State.entities.OnChange += OnEntityMove;

PlayerPrefs.SetString("roomId", room.Id);
PlayerPrefs.SetString("sessionId", room.SessionId);
PlayerPrefs.Save();

room.OnLeave += (code) => Debug.Log("ROOM: ON LEAVE");
room.OnError += (message) => Debug.LogError(message);
room.OnStateChange += OnStateChangeHandler;
room.OnMessage += OnMessage;
RegisterRoomHandlers();
}

async void ReconnectRoom ()
Expand All @@ -161,19 +132,49 @@ async void ReconnectRoom ()
}

room = await client.Reconnect<State>(roomId, sessionId);

Debug.Log("Reconnected into room successfully.");
RegisterRoomHandlers();
}

public void RegisterRoomHandlers()
{
m_SessionIdText.text = "sessionId: " + room.SessionId;

room.State.entities.OnAdd += OnEntityAdd;
room.State.entities.OnRemove += OnEntityRemove;
room.State.entities.OnChange += OnEntityMove;
room.State.TriggerAll();

room.OnError += (message) => Debug.LogError(message);
PlayerPrefs.SetString("roomId", room.Id);
PlayerPrefs.SetString("sessionId", room.SessionId);
PlayerPrefs.Save();

room.OnLeave += (code) => Debug.Log("ROOM: ON LEAVE");
room.OnError += (code, message) => Debug.LogError("ERROR, code =>" + code + ", message => " + message);
room.OnStateChange += OnStateChangeHandler;
room.OnMessage += OnMessage;

room.OnMessage((Message message) =>
{
Debug.Log("Received Schema message:");
Debug.Log(message.num + ", " + message.str);
});

room.OnMessage<MessageByEnum>((byte) MessageType.ONE, (message) =>
{
Debug.Log(">> Received message by enum/number => " + message.str);
});

room.OnMessage<TypeMessage>("type", (message) =>
{
Debug.Log("Received 'type' message!");
Debug.Log(message);
});

_ = room.Send((byte)MessageType.ONE, new MessageByEnum { str = "Sending message by enum/number" });
}


async void LeaveRoom()
{
await room.Leave(false);
Expand Down Expand Up @@ -206,10 +207,9 @@ void SendMessage()
{
if (room != null)
{
room.Send("move_right");

// Sending typed data to the server
room.Send(new CustomData() {
room.Send("schema");
room.Send("move_right", new CustomData()
{
integer = 100,
str = "Hello world!"
});
Expand All @@ -220,23 +220,6 @@ void SendMessage()
}
}

void OnMessage (object msg)
{
if (msg is Message)
{
var message = (Message)msg;
Debug.Log("Received schema-encoded message:");
Debug.Log("message.num => " + message.num + ", message.str => " + message.str);
}
else
{
// msgpack-encoded message
var message = (IndexedDictionary<string, object>)msg;
Debug.Log("Received msgpack-encoded message:");
Debug.Log(message["hello"]);
}
}

void OnStateChangeHandler (State state, bool isFirstState)
{
// Setup room first state
Expand Down
2 changes: 1 addition & 1 deletion Assets/Enemy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// THIS FILE HAS BEEN GENERATED AUTOMATICALLY
// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING
//
// GENERATED USING @colyseus/schema 0.5.32
// GENERATED USING @colyseus/schema 0.5.36
//

using Colyseus.Schema;
Expand Down
2 changes: 1 addition & 1 deletion Assets/Entity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// THIS FILE HAS BEEN GENERATED AUTOMATICALLY
// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING
//
// GENERATED USING @colyseus/schema 0.5.32
// GENERATED USING @colyseus/schema 0.5.36
//

using Colyseus.Schema;
Expand Down
2 changes: 1 addition & 1 deletion Assets/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// THIS FILE HAS BEEN GENERATED AUTOMATICALLY
// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING
//
// GENERATED USING @colyseus/schema 0.5.32
// GENERATED USING @colyseus/schema 0.5.36
//

using Colyseus.Schema;
Expand Down
2 changes: 1 addition & 1 deletion Assets/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// THIS FILE HAS BEEN GENERATED AUTOMATICALLY
// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING
//
// GENERATED USING @colyseus/schema 0.5.32
// GENERATED USING @colyseus/schema 0.5.36
//

using Colyseus.Schema;
Expand Down
15 changes: 3 additions & 12 deletions Assets/Plugins/Colyseus/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,6 @@ public class MatchMakeResponse
public string error;
}

public class MatchMakeException : Exception
{
public int Code;
public MatchMakeException(string message, int code) : base(message)
{
Code = code;
}
}


/// <summary>
/// Colyseus.Client
Expand Down Expand Up @@ -177,10 +168,10 @@ public async Task<Room<T>> ConsumeSeatReservation<T>(MatchMakeResponse response,

var tcs = new TaskCompletionSource<Room<T>>();

void OnError(string message)
void OnError(int code, string message)
{
room.OnError -= OnError;
tcs.SetException(new Exception(message));
tcs.SetException(new MatchMakeException(code, message));
};

void OnJoin()
Expand Down Expand Up @@ -249,7 +240,7 @@ protected async Task<Room<T>> CreateMatchMakeRequest<T>(string method, string ro
var response = JsonUtility.FromJson<MatchMakeResponse>(req.downloadHandler.text);
if (!string.IsNullOrEmpty(response.error))
{
throw new MatchMakeException(response.error, response.code);
throw new MatchMakeException(response.code, response.error);
}

return await ConsumeSeatReservation<T>(response, headers);
Expand Down
38 changes: 18 additions & 20 deletions Assets/Plugins/Colyseus/Connection.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.IO;
using System.Collections.Generic;
using System.Threading.Tasks;
Expand All @@ -12,7 +12,7 @@ namespace Colyseus
public class Connection : WebSocket
{
public bool IsOpen = false;
protected Queue<byte[]> _enqueuedCalls = new Queue<byte[]>();
protected bool ProcessingMessageQueue = false;

public Connection(string url, Dictionary<string, string> headers) : base(url, headers)
{
Expand All @@ -25,36 +25,34 @@ private void Initialize()
OnClose += _OnClose;
}

public async Task Send(object[] data)
#if UNITY_WEBGL && !UNITY_EDITOR
#else
public async void ProcessMessageQueue()
{
var serializationOutput = new MemoryStream();
MsgPack.Serialize(data, serializationOutput, SerializationOptions.SuppressTypeInformation);
ProcessingMessageQueue = true;
while (ProcessingMessageQueue)
{
DispatchMessageQueue();

byte[] packedData = serializationOutput.ToArray ();

if (!this.IsOpen) {
_enqueuedCalls.Enqueue(packedData);

} else {

await Send(packedData);
// probably should be waiting until a new frame started or so
await Task.Delay(TimeSpan.FromSeconds(1.0f / 120.0f));
}
}
#endif

protected async void _OnOpen ()
protected void _OnOpen ()
{
IsOpen = true;

// send enqueued commands while connection wasn't open
if (_enqueuedCalls.Count > 0) {
do {
await Send(_enqueuedCalls.Dequeue());
} while (_enqueuedCalls.Count > 0);
}
#if UNITY_WEBGL && !UNITY_EDITOR
#else
ProcessMessageQueue();
#endif
}

protected void _OnClose (WebSocketCloseCode code)
{
ProcessingMessageQueue = false;
IsOpen = false;
}
}
Expand Down
24 changes: 12 additions & 12 deletions Assets/Plugins/Colyseus/Protocol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,47 @@ namespace Colyseus
public class Protocol
{
/// <summary>When client receives its unique id.</summary>
public static int USER_ID = 1;
public static byte USER_ID = 1;

//
// Room-related (9~19)
//

/// <summary>When JOIN is requested.</summary>
public static int JOIN_REQUEST = 9;
public static byte JOIN_REQUEST = 9;

/// <summary>When JOIN request is accepted.</summary>
public static int JOIN_ROOM = 10;
public static byte JOIN_ROOM = 10;

/// <summary>When JOIN request is not accepted.</summary>
public static int JOIN_ERROR = 11;
/// <summary>When an error has happened in the server-side.</summary>
public static byte ERROR = 11;

/// <summary>When server explicitly removes <see cref="Client"/> from the <see cref="Room"/></summary>
public static int LEAVE_ROOM = 12;
public static byte LEAVE_ROOM = 12;

/// <summary>When server sends data to a particular <see cref="Room"/></summary>
public static int ROOM_DATA = 13;
public static byte ROOM_DATA = 13;

/// <summary>When server sends <see cref="Room"/> state to its clients.</summary>
public static int ROOM_STATE = 14;
public static byte ROOM_STATE = 14;

/// <summary>When server sends <see cref="Room"/> state to its clients.</summary>
public static int ROOM_STATE_PATCH = 15;
public static byte ROOM_STATE_PATCH = 15;

/// <summary>When server sends a Schema-encoded message.</summary>
public static int ROOM_DATA_SCHEMA = 16;
public static byte ROOM_DATA_SCHEMA = 16;

//
// Matchmaking messages (20~30)
//
public static int ROOM_LIST = 20;
public static byte ROOM_LIST = 20;

//
// Generic messages (50~60)
//

/// <summary>When server doesn't understand a request, it returns <see cref="BAD_REQUEST"/> to the <see cref="Client"/></summary>
public static int BAD_REQUEST = 50;
public static byte BAD_REQUEST = 50;

// public Protocol (){}
}
Expand Down
Loading

0 comments on commit 8b32c03

Please sign in to comment.