public static async Task WriteMessageAsync(Message message, IConnection connection, bool isRequest, IConnectionOrientedTransportFactorySettings settings, CancellationToken token) { // TODO: Switch to using the token as this is supposed to use remaining time var timeoutHelper = new TimeoutHelper(TimeoutHelper.GetOriginalTimeout(token)); byte[] endBytes = null; if (message != null) { MessageEncoder messageEncoder = settings.MessageEncoderFactory.Encoder; byte[] envelopeStartBytes = SingletonEncoder.EnvelopeStartBytes; bool writeStreamed; if (isRequest) { endBytes = SingletonEncoder.EnvelopeEndFramingEndBytes; writeStreamed = TransferModeHelper.IsRequestStreamed(settings.TransferMode); } else { endBytes = SingletonEncoder.EnvelopeEndBytes; writeStreamed = TransferModeHelper.IsResponseStreamed(settings.TransferMode); } if (writeStreamed) { await connection.WriteAsync(envelopeStartBytes, 0, envelopeStartBytes.Length, false, timeoutHelper.RemainingTime()); Stream connectionStream = new StreamingOutputConnectionStream(connection, settings); Stream writeTimeoutStream = new TimeoutStream(connectionStream, timeoutHelper.RemainingTime()); messageEncoder.WriteMessage(message, writeTimeoutStream); } else { ArraySegment <byte> messageData = messageEncoder.WriteMessage(message, int.MaxValue, settings.BufferManager, envelopeStartBytes.Length + IntEncoder.MaxEncodedSize); messageData = SingletonEncoder.EncodeMessageFrame(messageData); Buffer.BlockCopy(envelopeStartBytes, 0, messageData.Array, messageData.Offset - envelopeStartBytes.Length, envelopeStartBytes.Length); await connection.WriteAsync(messageData.Array, messageData.Offset - envelopeStartBytes.Length, messageData.Count + envelopeStartBytes.Length, true, timeoutHelper.RemainingTime(), settings.BufferManager); } } else if (isRequest) // context handles response end bytes { endBytes = SingletonEncoder.EndBytes; } if (endBytes != null) { await connection.WriteAsync(endBytes, 0, endBytes.Length, true, timeoutHelper.RemainingTime()); } }
protected override async Task OnSendCoreAsync(Message message, CancellationToken token) { Fx.Assert(message != null, "message should not be null."); WebSocketMessageType outgoingMessageType = GetWebSocketMessageType(message); if (IsStreamedOutput) { WebSocketStream webSocketStream = new WebSocketStream(WebSocket, outgoingMessageType, token); TimeoutStream timeoutStream = new TimeoutStream(webSocketStream, token); await MessageEncoder.WriteMessageAsync(message, timeoutStream); await webSocketStream.WriteEndOfMessageAsync(token); } else { ArraySegment <byte> messageData = EncodeMessage(message); bool success = false; try { //if (TD.WebSocketAsyncWriteStartIsEnabled()) //{ // TD.WebSocketAsyncWriteStart( // this.WebSocket.GetHashCode(), // messageData.Count, // this.RemoteAddress != null ? this.RemoteAddress.ToString() : string.Empty); //} try { await WebSocket.SendAsync(messageData, outgoingMessageType, true, token); } catch (Exception ex) { if (Fx.IsFatal(ex)) { throw; } WebSocketHelper.ThrowCorrectException(ex, TimeoutHelper.GetOriginalTimeout(token), WebSocketHelper.SendOperation); } //if (TD.WebSocketAsyncWriteStopIsEnabled()) //{ // TD.WebSocketAsyncWriteStop(this.webSocket.GetHashCode()); //} success = true; } finally { try { BufferManager.ReturnBuffer(messageData.Array); } catch (Exception ex) { if (Fx.IsFatal(ex) || success) { throw; } Fx.Exception.TraceUnhandledException(ex); } } } }