chronoxor / NetCoreServer

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and 10K connections problem solution
https://chronoxor.github.io/NetCoreServer
MIT License
2.64k stars 550 forks source link

Task-based TCP sockets #225

Open wave9d opened 1 year ago

wave9d commented 1 year ago

I am trying to use the TCP session class together with the my own service layer which is based on the async/await pattern (all functions of the service layer return Tasks), is there any implementation of the TCP Session that is compatible with async/await (so far I've seen that OnReceived returns only void)

chronoxor commented 1 year ago

Task are slower than event model on which NetCoreServer is based. But it's not difficult to build Tasks-based server/client on top of NetCoreServer using TaskCompletionSource:

        // Client requests cache fields
        private Dictionary<Guid, TaskCompletionSource<SimpleResponse> _requestsByIdSimpleResponse;

        public Task<SimpleResponse> Request(SimpleRequest value)
        {
            TaskCompletionSource<SimpleResponse> source = new TaskCompletionSource<SimpleResponse>();
            Task<SimpleResponse> task = source.Task;

            // Register the request
            if (Send(value))
                _requestsByIdSimpleResponse.Add(value.id, new Tuple<DateTime, TimeSpan, TaskCompletionSource<global::com.chronoxor.simple.SimpleResponse>>(Timestamp, timeout, source));
            else
                source.SetException(new Exception("Send request failed!"));

            return task;            
        }

        public bool OnReceiveResponse(SimpleResponse response)
        {
            if (_requestsByIdSimpleResponse.TryGetValue(response.id, out TaskCompletionSource<global::com.chronoxor.simple.SimpleResponse source))
            {
                source.SetResult(response);
                _requestsByIdSimpleResponse.Remove(response.id);
                return true;
            }

            return false;            
        }