using Sandbox.Network; namespace Sandbox; public abstract partial class Connection { readonly Dictionary> _responseWaiters = new(); /// /// Send a message to this connection, wait for a response /// public Task SendRequest( T t ) { var requestGuid = Guid.NewGuid(); Assert.NotNull( System ); var msg = ByteStream.Create( 256 ); msg.Write( InternalMessageType.Request ); msg.Write( requestGuid ); msg.Write( InternalMessageType.Packed ); System.Serialize( t, ref msg ); SendRawMessage( msg ); msg.Dispose(); var tcs = new TaskCompletionSource(); _responseWaiters[requestGuid] = ( o ) => tcs.SetResult( o ); return tcs.Task; } /// /// Send a response message to this connection. /// public void SendResponse( Guid requestId, T t ) { Assert.NotNull( System ); var msg = ByteStream.Create( 256 ); msg.Write( InternalMessageType.Response ); msg.Write( requestId ); msg.Write( InternalMessageType.Packed ); System.Serialize( t, ref msg ); SendRawMessage( msg ); msg.Dispose(); } /// /// A response to a message has arrived, route it to the correct async function /// internal void OnResponse( Guid responseTo, object obj ) { if ( !_responseWaiters.Remove( responseTo, out var waiter ) ) { return; } try { waiter( obj ); } catch ( Exception e ) { Log.Warning( e ); } } }