Beispiel #1
0
        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);
                    }
                }
            }
        }