colyseus-unity-sdk icon indicating copy to clipboard operation
colyseus-unity-sdk copied to clipboard

Fixing ReconnectionToken Handling in Colyseus Unity SDK(Version 0.15.8) (FIXED)

Open SyedMuaaz opened this issue 5 months ago • 0 comments

Introduction

I recently encountered an issue with the Colyseus Unity SDK where the ReconnectionToken was not being appended to the query parameters for the reconnection request. This issue was causing the server to respond with a "seat reservation expired" error because it could not validate the missing token.

Issue Description

During the reconnection process, the WebSocketTransport.js on the server expects a "reconnectionToken" in the request parameters. However, the Unity client was not sending this token due to it not being bound in the query string, which led to failed reconnection attempts.

Steps to Reproduce

Start a Colyseus server and Unity client. Establish an initial connection and obtain a ReconnectionToken. Attempt to reconnect using the provided ReconnectionToken. Observe that the server logs indicate a missing "reconnectionToken" parameter.

Screenshots

Here are the screenshots demonstrating the issue:

Client Code Attempting Rejoin ClientRejoinRoom

Server Handling onLeave ServerOnLeave

Server Error Response Server Error Response

Server Code onConnection Server Code OnConnection

Client Code to Consume Seat Reservation Client Code To Consume Reserve Seat

Null Token Issue Null Token

Token Available in Response Token in Response

Token Added in Query String Token Added in Query

Proposed Solution

I resolved this issue by modifying the client SDK code to ensure that the ReconnectionToken is properly included in the query parameters when making a reconnection attempt. Here's the snippet where I added the token:

public async Task<ColyseusRoom<T>> ConsumeSeatReservation<T>(ColyseusMatchMakeResponse response,
            Dictionary<string, string> headers = null, ColyseusRoom<T> previousRoom = null)
        {
            ColyseusRoom<T> room = new ColyseusRoom<T>(response.room.name)
            {
                RoomId = response.room.roomId,
                SessionId = response.sessionId
            };

            Dictionary<string, object> queryString = new Dictionary<string, object>();
            queryString.Add("sessionId", room.SessionId);

            // forward reconnection token
            if (room.ReconnectionToken != null)
            {
                queryString.Add("reconnectionToken", room.ReconnectionToken);
            }
            else if (response.reconnectionToken != null) // To add reconnectionToken in the Query Prams
            {
                queryString.Add("reconnectionToken", response.reconnectionToken);
            }

And on the server-side, I ensured that the onConnection method checks for this token and handles it appropriately.

Proper Fix

The proper fix required both Client and Server changes.

  • Client should create a ReconnectToken object in "ConsumeSeatReservation" function in "ColyseusClient.cs" script and add it in "queryString" Dictionary.
  • Server should be able to get the right prams from the request in "onConnection" function in "WebSocketTransport.js" and then use "room.hasReservedSeat()" function to verify the token.

Conclusion

With this fix, the ReconnectionToken is now correctly passed to the server, and the reconnection process works as intended. I hope this solution helps others who might be facing the same issue.

Invitation for Feedback

I welcome any feedback or further improvements on this solution and encourage others to contribute their experiences or alternative approaches.

I want to create a pull request with a proper solution on client and server both, kindly let me know if I can contribute in it. Thanks

SyedMuaaz avatar Jan 31 '24 12:01 SyedMuaaz