/// <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; } }
void IRelayTransport.SendMessage(SerializedRelayMessage serializedMessage) { if (DoDispatchMessages) { RelayMessage message = RelayMessageFormatter.ReadRelayMessage(serializedMessage.MessageStream); _messageRecieved(message); } }
/// <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> /// 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); }