/// <summary>
        /// Sends a message synchronously, regardless of its type
        /// </summary>
        /// <param name="message"></param>
        /// <remarks>
        /// added cbrown
        /// due to the extensive use of the sockettransport, and the desire not
        /// to break existing code, this interface is being used to extend the
        /// transport protocol.
        /// usage:
        ///		IRelayTransportExtended xTend = Transport as IRelayTransportExtended;
        ///		if (null == xTend)
        ///		{
        ///			use "tradidional" handling
        ///		}
        ///		else
        ///		{
        ///			use extended handling
        ///		}
        /// </remarks>
        public void SendSyncMessage(RelayMessage message)
        {
            MemoryStream replyStream;
            ResourcePoolItem <MemoryStream> bufferItem = null;

            try
            {
                bufferItem = bufferPool.GetItem();
                // there is not need to check the type, we are FORCING sync handling
                RelayMessageFormatter.WriteRelayMessage(message, bufferItem.Item);
                bufferItem.Item.Seek(0, SeekOrigin.Begin);
                replyStream = socketClient.SendSync((int)SocketCommand.HandleSyncMessage, bufferItem.Item);
            }
            finally
            {
                if (bufferItem != null)
                {
                    bufferPool.ReleaseItem(bufferItem);
                }
            }
            if (replyStream != null)
            {
                RelayMessage replyMessage = RelayMessageFormatter.ReadRelayMessage(replyStream);
                message.ExtractResponse(replyMessage);
            }
            //this doesn't make any sense, the incoming message already
            //has error occured with no respones? fwise 5/09
            else if (message.ErrorOccurred)
            {
                message.Payload = null;
            }
        }
Пример #2
0
 void IRelayTransport.SendMessage(SerializedRelayMessage serializedMessage)
 {
     if (DoDispatchMessages)
     {
         RelayMessage message = RelayMessageFormatter.ReadRelayMessage(serializedMessage.MessageStream);
         _messageRecieved(message);
     }
 }
Пример #3
0
        /// <summary>
        /// Ends the handling of a message and returns the memory stream to send back to the client.
        /// </summary>
        /// <param name="asyncResult">The <see cref="IAsyncResult"/> returned from <see cref="BeginHandleMessage"/>.</param>
        /// <returns>Retuns a <see cref="MemoryStream"/> to send back to the client, if the stream is <see langword="null"/> an empty response is sent.</returns>
        public MemoryStream EndHandleMessage(IAsyncResult asyncResult)
        {
            MemoryStream             replyStream       = null;
            SocketHandlerAsyncResult socketAsyncResult = (SocketHandlerAsyncResult)asyncResult;

            if (socketAsyncResult.Exception != null)
            {
                if (log.IsErrorEnabled)
                {
                    log.ErrorFormat("Exception handling async message: {0}", socketAsyncResult.Exception);
                }
                throw socketAsyncResult.Exception;
            }

            //only 1 should be not null
            int replyCount = 0;

            if (socketAsyncResult.ReplyMessage != null)
            {
                replyCount++;
            }
            if (socketAsyncResult.ReplyMessages != null)
            {
                replyCount++;
            }
            if (socketAsyncResult.RuntimeInfo != null)
            {
                replyCount++;
            }
            if (replyCount > 1)
            {
                throw new InvalidOperationException(
                          string.Format("Only 1 reply at a time is supported. ReplyMessage: {0}, ReplyMessages: {1}, RuntimeInfo: {2}",
                                        socketAsyncResult.ReplyMessage,
                                        socketAsyncResult.ReplyMessages,
                                        socketAsyncResult.RuntimeInfo));
            }

            if (socketAsyncResult.ReplyMessage != null)
            {
                replyStream = RelayMessageFormatter.WriteRelayMessage(socketAsyncResult.ReplyMessage);
            }
            else if (socketAsyncResult.ReplyMessages != null)
            {
                replyStream = RelayMessageFormatter.WriteRelayMessageList(socketAsyncResult.ReplyMessages);
            }
            else if (socketAsyncResult.RuntimeInfo != null)
            {
                replyStream = (MemoryStream)RelayMessageFormatter.WriteRuntimeInfo(socketAsyncResult.RuntimeInfo);
            }

            return(replyStream);
        }
        public SerializedRelayMessage(RelayMessage message)
        {
            MessageStream = new MemoryStream();
            RelayMessageFormatter.WriteRelayMessage(message, MessageStream);
            MessageStream.Seek(0, SeekOrigin.Begin);
            MessageType            = message.MessageType;
            EnteredCurrentSystemAt = message.EnteredCurrentSystemAt;

            if (message.Payload != null && message.Payload.ByteArray != null)
            {
                PayloadLength = message.Payload.ByteArray.Length;
            }
        }
Пример #5
0
        IAsyncResult IAsyncRelayTransport.BeginSendMessageList(List <RelayMessage> messages, AsyncCallback callback, object state)
        {
            if (messages == null)
            {
                throw new ArgumentNullException("messages");
            }

            var result = new RoundTripAsyncResult <List <RelayMessage> >(callback, state)
            {
                SentMessage = messages
            };

            if (messages.Count > 0)
            {
                _asyncSocketClient.SendRoundTripAsync <List <RelayMessage> >(
                    (short)SocketCommand.HandleSyncMessages,
                    messages,
                    RelayMessageFormatter.WriteRelayMessageList,
                    args =>
                {
                    try
                    {
                        if (args.Error != null)
                        {
                            result.Error = args.Error;
                            return;
                        }

                        if (args.Response != null)
                        {
                            result.ResponseMessage = RelayMessageFormatter.ReadRelayMessageList(args.Response);
                        }
                    }
                    catch (Exception ex)
                    {
                        result.Error = ex;
                    }
                    finally
                    {
                        result.Complete(args.CompletedSynchronously);
                    }
                });
            }
            else
            {
                result.ResponseMessage = messages;
                result.Complete(true);
            }

            return(result);
        }
Пример #6
0
 private void _serializedMessageListReceive(IEnumerable <SerializedRelayMessage> messages)
 {
     if (DoDispatchMessages)
     {
         using (var stream = new MemoryStream())
         {
             foreach (var message in messages)
             {
                 message.MessageStream.WriteTo(stream);
             }
             List <RelayMessage> messageList = RelayMessageFormatter.ReadRelayMessageList(stream);
             _messageListRecieved(messageList);
         }
     }
 }
        /// <summary>
        /// Handles a new message from a <see cref="MemoryStream"/> and if appropriate translates
        /// and passes the message to the contained <see cref="RelayNode"/>.
        /// </summary>
        /// <param name="commandID"></param>
        /// <param name="messageStream"></param>
        /// <param name="messageLength"></param>
        /// <returns></returns>
        public MemoryStream HandleMessage(int commandID, MemoryStream messageStream, int messageLength)
        {
            SocketCommand       command     = SocketCommand.Unknown;
            RelayMessage        message     = null;
            List <RelayMessage> messages    = null;
            MemoryStream        replyStream = null;

            try
            {
                command = (SocketCommand)commandID;
            }
            catch
            {
                if (RelayNode.log.IsErrorEnabled)
                {
                    RelayNode.log.ErrorFormat("Unrecognized commandID {0} sent to Relay Service via socket transport", commandID);
                }
            }

            Stream reply;

            switch (command)
            {
            case SocketCommand.Unknown:
                if (RelayNode.log.IsErrorEnabled)
                {
                    RelayNode.log.Error("SocketCommand.Unknown received");
                }
                break;

            case SocketCommand.HandleOneWayMessage:
                message = RelayMessageFormatter.ReadRelayMessage(messageStream);
                _dataHandler.HandleMessage(message);
                break;

            case SocketCommand.HandleSyncMessage:
                message = RelayMessageFormatter.ReadRelayMessage(messageStream);
                message.ResultOutcome = RelayOutcome.Received;
                _dataHandler.HandleMessage(message);
                reply = RelayMessageFormatter.WriteRelayMessage(message);
                if (reply != null && reply != Stream.Null)
                {
                    replyStream = (MemoryStream)reply;
                }
                break;

            case SocketCommand.HandleOneWayMessages:
                messages = RelayMessageFormatter.ReadRelayMessageList(messageStream);
                _dataHandler.HandleMessages(messages);
                break;

            case SocketCommand.HandleSyncMessages:
                messages = RelayMessageFormatter.ReadRelayMessageList(messageStream, msg => msg.ResultOutcome = RelayOutcome.Received);
                _dataHandler.HandleMessages(messages);
                reply = RelayMessageFormatter.WriteRelayMessageList(messages);
                if (reply != null && reply != Stream.Null)
                {
                    replyStream = (MemoryStream)reply;
                }
                break;

            case SocketCommand.GetRuntimeInfo:
                ComponentRuntimeInfo[] runtimeInfo = _relayNode.GetComponentsRuntimeInfo();
                reply = RelayMessageFormatter.WriteRuntimeInfo(runtimeInfo);
                if (reply != null && reply != Stream.Null)
                {
                    replyStream = (MemoryStream)reply;
                }
                break;

            default:
                if (RelayNode.log.IsErrorEnabled)
                {
                    RelayNode.log.ErrorFormat("Unhandled command {0} sent to Relay Service via socket transport", command);
                }
                break;
            }


            return(replyStream);
        }
        IAsyncResult IAsyncRelayTransport.BeginSendMessage(RelayMessage message, bool forceRoundTrip, AsyncCallback callback, object state)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            if (message.IsTwoWayMessage)
            {
                var result = new RoundTripAsyncResult <RelayMessage>(callback, state)
                {
                    SentMessage = message
                };
                asyncSocketClient.SendRoundTripAsync <RelayMessage>(
                    (short)SocketCommand.HandleSyncMessage,
                    message,
                    RelayMessageFormatter.WriteRelayMessage,
                    args =>
                {
                    try
                    {
                        if (args.Error != null)
                        {
                            result.Error = args.Error;
                            return;
                        }

                        if (args.Response != null)
                        {
                            result.ResponseMessage = RelayMessageFormatter.ReadRelayMessage(args.Response);
                        }
                    }
                    catch (Exception ex)
                    {
                        result.Error = ex;
                    }
                    finally
                    {
                        result.Complete(args.CompletedSynchronously);
                    }
                });
                return(result);
            }
            else
            {
                var result = new SimpleAsyncResult(callback, state);
                if (forceRoundTrip)
                {
                    asyncSocketClient.SendRoundTripAsync <RelayMessage>(
                        (short)SocketCommand.HandleSyncMessage,
                        message,
                        RelayMessageFormatter.WriteRelayMessage,
                        args =>
                    {
                        result.Error = args.Error;
                        result.CompleteOperation(args.CompletedSynchronously);
                    });
                }
                else
                {
                    asyncSocketClient.SendOneWayAsync <RelayMessage>(
                        (short)SocketCommand.HandleOneWayMessage,
                        message,
                        RelayMessageFormatter.WriteRelayMessage,
                        args =>
                    {
                        result.Error = args.Error;
                        result.CompleteOperation(args.CompletedSynchronously);
                    });
                }
                return(result);
            }
        }
        /// <summary>
        /// Sends a list of messages synchronously, regardless of its type
        /// </summary>
        /// <param name="messages">The messages to send.</param>
        /// <remarks>
        /// added cbrown
        /// due to the extensive use of the sockettransport, and the desire not
        /// to break existing code, this interface is being used to extend the
        /// transport protocol.
        /// usage:
        ///		IRelayTransportExtended xTend = Transport as IRelayTransportExtended;
        ///		if (null == xTend)
        ///		{
        ///			use "tradidional" handling
        ///		}
        ///		else
        ///		{
        ///			use extended handling
        ///		}
        /// </remarks>
        public void SendSyncMessageList(List <RelayMessage> messages)
        {
            ResourcePoolItem <MemoryStream> pooledBuffer;
            MemoryStream nextMessageChunk;
            int          chunkLength = defaultChunkLength;

            if (messages.Count > 0)
            {
                chunkLength  = messages.Count;
                pooledBuffer = bufferPool.GetItem();
                try
                {
                    nextMessageChunk = pooledBuffer.Item;
                    int cursor = 0;
                    while (cursor < messages.Count)
                    {
                        int currentLocalIndexStart = cursor;
                        nextMessageChunk.Seek(0, SeekOrigin.Begin);
                        cursor += RelayMessageFormatter.WriteRelayMessageList(messages, cursor, chunkLength, nextMessageChunk);
                        MemoryStream replyStream = socketClient.SendSync((int)SocketCommand.HandleSyncMessages, nextMessageChunk);
                        if (replyStream != null)
                        {
                            List <RelayMessage> replyMessages = RelayMessageFormatter.ReadRelayMessageList(replyStream);
                            if (replyMessages.Count != messages.Count)
                            {
                                string errMsg = string.Format("Reply messages from {0} has length {1} but request messages has length {2}. Discarding replies.",
                                                              node, replyMessages.Count, messages.Count);
                                log.Error(errMsg);
#if DEBUG
                                throw new ApplicationException(errMsg);
#else
                                break;
#endif
                            }
                            for (int i = 0; i < replyMessages.Count; i++)
                            {
                                try
                                {
                                    if (replyMessages[i].Id != messages[i + currentLocalIndexStart].Id)
                                    {
                                        string errMsg = string.Format("OutMessage Receive Got Wrong Id on Reply Message. Message Sent: {0}, Message Received: {1}",
                                                                      messages[i + currentLocalIndexStart],
                                                                      replyMessages[i]);
                                        log.Error(errMsg);
#if DEBUG
                                        throw new ApplicationException(errMsg);
#endif
                                    }
                                    else
                                    {
                                        messages[i + currentLocalIndexStart].ExtractResponse(replyMessages[i]);
                                    }
                                }
                                catch (ArgumentOutOfRangeException)
                                {
                                    string errMsg = string.Format("Bad index while processing out message list for {0}. i = {1}. currentLocalIndexStart = {2}. Cursor = {3}. Message count = {4}.",
                                                                  node, i, currentLocalIndexStart, cursor, messages.Count);
                                    if (log.IsErrorEnabled)
                                    {
                                        log.Error(errMsg);
                                    }
                                    cursor = messages.Count + 1;                                     //break out of while loop as well
#if DEBUG
                                    throw new ArgumentOutOfRangeException(errMsg);
#else
                                    break;
#endif
                                }
                            }
                        }
                    }
                }
                finally
                {
                    bufferPool.ReleaseItem(pooledBuffer);
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Begins the handling of a complete message from a stream. All references
        /// to <see cref="MessageState.Message"/> must be released by the end of this method.
        /// </summary>
        /// <param name="message">The complete message that is to be handled.</param>
        /// <param name="callback">The delegate to call when complete.</param>
        /// <returns>Returns an <see cref="IAsyncResult"/>.</returns>
        /// <remarks>
        ///		<para>
        ///		All implementors must release any references to <see cref="MessageState.Message"/>
        ///		by the time that <see cref="BeginHandleMessage"/> returns.
        ///		</para>
        /// </remarks>
        public IAsyncResult BeginHandleMessage(MessageState message, AsyncCallback callback)
        {
            SocketHandlerAsyncResult result = new SocketHandlerAsyncResult(null, callback);

            //don't use callback directly, use result.Complete();
            callback = null;
            const bool wasSyncronous = true;

            //VERY IMPORTANT! don't hold any references to message or it's properties after leaving this method
            try
            {
                SocketCommand       command       = SocketCommand.Unknown;
                RelayMessage        relayMessage  = null;
                List <RelayMessage> relayMessages = null;

                try
                {
                    command = (SocketCommand)message.CommandId;
                }
                catch
                {
                    if (RelayNode.log.IsErrorEnabled)
                    {
                        RelayNode.log.ErrorFormat("Unrecognized commandID {0} sent to Relay Service via socket transport", message.CommandId);
                    }
                    result.CompleteOperation(wasSyncronous);
                    return(result);
                }

                switch (command)
                {
                case SocketCommand.Unknown:
                    if (RelayNode.log.IsErrorEnabled)
                    {
                        RelayNode.log.Error("SocketCommand.Unknown received");
                    }
                    result.CompleteOperation(wasSyncronous);
                    return(result);

                case SocketCommand.HandleOneWayMessage:
                case SocketCommand.HandleSyncMessage:
                    relayMessage = RelayMessageFormatter.ReadRelayMessage(message.Message);
                    relayMessage.ResultOutcome = RelayOutcome.Received;
                    _dataHandler.BeginHandleMessage(relayMessage, null, async => {
                        try
                        {
                            _dataHandler.EndHandleMessage(async);
                            if (command == SocketCommand.HandleSyncMessage)
                            {
                                result.ReplyMessage = relayMessage;
                            }
                        }
                        catch (Exception exc)
                        {
                            result.Exception = exc;
                        }
                        finally
                        {
                            result.CompleteOperation(async.CompletedSynchronously);
                        }
                    });
                    break;

                case SocketCommand.HandleOneWayMessages:
                case SocketCommand.HandleSyncMessages:
                    relayMessages = RelayMessageFormatter.ReadRelayMessageList(message.Message, msg => msg.ResultOutcome = RelayOutcome.Received);
                    _dataHandler.BeginHandleMessages(relayMessages, null, async =>
                    {
                        try
                        {
                            _dataHandler.EndHandleMessages(async);
                            if (command == SocketCommand.HandleSyncMessages)
                            {
                                result.ReplyMessages = relayMessages;
                            }
                        }
                        catch (Exception exc)
                        {
                            result.Exception = exc;
                        }
                        finally
                        {
                            result.CompleteOperation(async.CompletedSynchronously);
                        }
                    });
                    break;

                case SocketCommand.GetRuntimeInfo:
                    _enqueueGetComponentRuntimeInfo(result);
                    break;

                default:
                    if (RelayNode.log.IsErrorEnabled)
                    {
                        RelayNode.log.ErrorFormat("Unhandled command {0} sent to Relay Service via socket transport", command);
                    }
                    result.CompleteOperation(wasSyncronous);
                    return(result);
                }
            }
            catch (Exception exc)
            {
                result.Exception = exc;
                result.CompleteOperation(wasSyncronous);
            }

            return(result);
        }