Open KamilTheDev opened 1 month ago
i have no code snippet of what u are trying to achieve,
but this is an example to how u can do it
public async Task<(string playerData, string clanData)> GetPlayerAndClanAsync(object someObject)
{
var playerTaskCompletion = new TaskCompletionSource<string>();
var clanTaskCompletion = new TaskCompletionSource<string>();
// Emit get-player event and set the response to playerTaskCompletion
socket.Emit("get-player", (response) =>
{
string playerData = response.GetValue<string>();
playerTaskCompletion.TrySetResult(playerData);
}, someObject);
// Emit get-clan event and set the response to clanTaskCompletion
socket.Emit("get-clan", (response) =>
{
string clanData = response.GetValue<string>();
clanTaskCompletion.TrySetResult(clanData);
}, someObject);
// Await both tasks and return the tuple with both results
string playerResult = await playerTaskCompletion.Task;
string clanResult = await clanTaskCompletion.Task;
return (playerResult, clanResult);
}
usage:
var (playerData, clanData) = await socketManager.GetPlayerAndClanAsync(someObject);
Console.WriteLine($"Player Data: {playerData}");
Console.WriteLine($"Clan Data: {clanData}");
adjust the code to meet ur needs
I imagine it might be from having one socket.emit
being executed in Unity thread, and the other socket.emit
is not. I was playing around with different ways.
void Start()
{
// Connect to the server
socket.Connect();
Debug.Log("socket.Connect is called.");
// Handle connection event
socket.OnConnected += (sender, e) =>
{
UnityThread.executeInUpdate(() => OnConnected?.Invoke());
socket.Emit("player-data", (response) =>
{
UnityThread.executeInUpdate(() =>
{
Debug.Log("Player data response: " + response.GetValue<string>();
});
});
};
}
public async void ExampleOnConnectedSubscriber()
{
SocketIOResponse response = await EmitAsync("clan-data");
Debug.Log("Clan data response: " + response.GetValue<string>());
}
public static async ValueTask<SocketIOResponse> EmitAsync(string eventName, object data = null)
{
var tcs = new TaskCompletionSource<SocketIOResponse>();
await Instance.socket.EmitAsync(eventName, (response) =>
{
tcs.SetResult(response);
}, data);
return await tcs.Task;
}
I think ensuring they are both executed in either socket or Unity thread fixes the issue. I was also testing the idea of being able to simply await
the socket callback.
For example, I don't really like the syntax, especially if you need to make more emits inside:
socket.Emit("player-data", (response) =>
{
UnityThread.executeInUpdate(() =>
{
playerText.text = response.GetValue<string>();
socket.Emit("other-data", (response) =>
{
UnityThread.executeInUpdate(() =>
{
otherText.text = response.GetValue<string>();
});
});
});
});
I much rather:
SocketIOResponse playerResponse = await EmitAsync("player-data");
playerText.text = playerResponse.GetValue<string>();
SocketIOResponse otherResponse= await EmitAsync("other-data");
otherText.text = otherResponse.GetValue<string>();
Is the way I implemented EmitAsync
the correct way to be able to directly await the callback?
try to not use unity thread when fetching ur needed data (get-player and get-clan), then after retrieving ur data run use unity thread
var (playerData, clanData) = await socketManager.GetPlayerAndClanAsync(someObject);
UnityThread.executeInUpdate(() =>
{
// TODO
});
i have no code snippet of what u are trying to achieve,
but this is an example to how u can do it
public async Task<(string playerData, string clanData)> GetPlayerAndClanAsync(object someObject) { var playerTaskCompletion = new TaskCompletionSource<string>(); var clanTaskCompletion = new TaskCompletionSource<string>(); // Emit get-player event and set the response to playerTaskCompletion socket.Emit("get-player", (response) => { string playerData = response.GetValue<string>(); playerTaskCompletion.TrySetResult(playerData); }, someObject); // Emit get-clan event and set the response to clanTaskCompletion socket.Emit("get-clan", (response) => { string clanData = response.GetValue<string>(); clanTaskCompletion.TrySetResult(clanData); }, someObject); // Await both tasks and return the tuple with both results string playerResult = await playerTaskCompletion.Task; string clanResult = await clanTaskCompletion.Task; return (playerResult, clanResult); }
usage:
var (playerData, clanData) = await socketManager.GetPlayerAndClanAsync(someObject); Console.WriteLine($"Player Data: {playerData}"); Console.WriteLine($"Clan Data: {clanData}");
adjust the code to meet ur needs
I've been having a very strange problem, in
socket.OnConnected
event, I'm emitting 2 events:get-player
andget-clan
that have a callback that processes the result from the server.Sometimes rarely, the
get-clan
event is actually receiving the player data (that would be forget-player
), and theget-player
callback is never called. Other times,get-player
will get the player data, but the callback forget-clan
is never called. I have server logs that indicate the server is always getting the right data for each event, and in the cases where client never gets theget-player
orget-clan
callback called, the server did receive the request.Is there any potential ways to accidently create issues when emitting different events with ack callbacks at the same time? Perhaps I'm doing something that I shouldn't.