emitWithAck missing
Closed this issue · 5 comments
I spent a little bit looking into the methods internally here and found a really nice feature seems to be missing or perhaps I am not seeing where/how it is implemented which is emitWithAck.
emitWithAck allows to send data to the server and then get back data as a promise. I REALLY could use this part of socket.io in my Unity project as right now I am having to resort to callback hell in order to pull off what I'm needing done.
Thanks for the help or consideration!
await socket.EmitAsync("getMD5", response => {
string text = response.GetValue<string>();
JSONObject jsonObject = new JSONObject(text);
return jsonObject["data"]["test"].stringValue;
}, theData);
This is so close to being perfect, but the return from EmitAsync is void so it doesn't allow for passing the result back to the containing method, and I can't assign to a variable outside response function as despite EmitAsync being async, me trying to use the value after the EmitAsync results in empty variable (see below).
string res = "";
await socket.EmitAsync("getMD5", response => {
string text = response.GetValue<string>();
JSONObject jsonObject = new JSONObject(text);
res = jsonObject["data"]["test"].stringValue;
}, theData);
Debug.Log(res); <== This is empty.
I might just change the source for EmitAsync to allow for a return type that is not void which should result in what I need to accomplish but still would be nice feature to not have to go in and modify the source.
Cheers!
use TaskCompletionSource
:
using System.Threading.Tasks;
public class YourClass
{
public async Task<string> GetResultAsync()
{
var tcs = new TaskCompletionSource<string>();
await socket.EmitAsync("getMD5", response =>
{
string text = response.GetValue<string>();
JSONObject jsonObject = new JSONObject(text);
string res = jsonObject["data"]["test"].stringValue;
tcs.SetResult(res);
}, theData);
return await tcs.Task;
}
}
or this is better in term of performance
public async ValueTask<string> GetResultAsync()
{
var tcs = new TaskCompletionSource<string>();
await socket.EmitAsync("getMD5", response =>
{
string text = response.GetValue<string>();
JSONObject jsonObject = new JSONObject(text);
string res = jsonObject["data"]["test"].stringValue;
tcs.SetResult(res);
}, theData);
return await tcs.Task;
}
usage:
public async Task UseGetResultAsync()
{
YourClass instance = new YourClass();
string result = await instance.GetResultAsync();
// Use the 'result' here, it will contain the value from the callback.
Debug.Log(result);
}
if not working check with @doghappy at: https://github.com/doghappy/socket.io-client-csharp
Hey, I was able to get what I needed in another fashion but this is looking mighty handy, I will do some unit testing probably tomorrow and try it out and get back here on how that goes, this could prove useful in the future for sure, thanks!
I just tried the second example, here it is modified as I used it;
`public async ValueTask GetResultAsync()
{
var tcs = new TaskCompletionSource();
await socket.EmitAsync("test", response =>
{
string text = response.GetValue<string>();
JSONObject jsonObject = new JSONObject(text);
string res = jsonObject["test"].stringValue;
Debug.Log(res);
tcs.SetResult(res);
}, theData);
return await tcs.Task;
}`
And I used this part;
public async Task UseGetResultAsync() { //YourClass instance = new YourClass(); Debug.Log("MARK"); string result = await GetResultAsync(); // Use the 'result' here, it will contain the value from the callback. Debug.Log(result); }
I called UseGetResultAsync() from Start() and since it is in the same class I removed the instance bit.
This resulted in no data being output in console for "res", MARK shows up and "result" does not.
I have the "test" command same as before on the server and the server outputs on it's console as expected,
so it is being called by the above code but for some reason no data is received back it seems, so I'm not exactly
sure what is going on there. I also tried faking a result by assigning a string to tcs.SetResult("Hello") and got no response either and considering I am getting no errors, I believe I have all using statements that I need.
I ended up making a class for the code I needed and just having the EmitAsync assign to a variable in the class and used INotifyPropertyChanged to fire off an event when the value changed and listened for the event in my main code from the instance of the class object, so that worked out better than I had originally thought.
Thanks for the attempted solution, it may be fine and I just did something wrong somewhere, not sure.
Forgot to close..