in src/Transport/WebSocketTransport.cs [43:101]
public sealed override bool WriteAsync(TransportAsyncCallbackArgs args)
{
ArraySegment<byte> buffer;
ByteBuffer mergedBuffer = null;
DateTime startTime = DateTime.UtcNow;
if (args.Buffer != null)
{
buffer = new ArraySegment<byte>(args.Buffer, args.Offset, args.Count);
}
else
{
Fx.Assert(args.ByteBufferList != null, "Buffer list should not be null when buffer is null");
if (args.ByteBufferList.Count == 1)
{
ByteBuffer byteBuffer = args.ByteBufferList[0];
buffer = new ArraySegment<byte>(byteBuffer.Buffer, byteBuffer.Offset, byteBuffer.Length);
}
else
{
// Copy all buffers into one big buffer to avoid SSL overhead
mergedBuffer = new ByteBuffer(args.Count, false, false);
for (int i = 0; i < args.ByteBufferList.Count; ++i)
{
ByteBuffer byteBuffer = args.ByteBufferList[i];
Buffer.BlockCopy(byteBuffer.Buffer, byteBuffer.Offset, mergedBuffer.Buffer, mergedBuffer.Length, byteBuffer.Length);
mergedBuffer.Append(byteBuffer.Length);
}
buffer = new ArraySegment<byte>(mergedBuffer.Buffer, 0, mergedBuffer.Length);
}
}
Task task = this.webSocket.SendAsync(buffer, WebSocketMessageType.Binary, true, CancellationToken.None);
if (task.IsCompleted)
{
this.OnWriteComplete(args, buffer, mergedBuffer, startTime);
return false;
}
task.ContinueWith(static (t, s) =>
{
var (transport, args, buffer, mergedBuffer, startTime) = (Tuple<WebSocketTransport, TransportAsyncCallbackArgs, ArraySegment<byte>, ByteBuffer, DateTime>) s;
if (t.IsFaulted)
{
args.Exception = t.Exception?.InnerException;
}
else if (t.IsCanceled)
{
args.Exception = new OperationCanceledException();
}
else
{
transport.OnWriteComplete(args, buffer, mergedBuffer, startTime);
}
args.CompletedCallback(args);
}, Tuple.Create(this, args, buffer, mergedBuffer, startTime));
return true;
}