/// <summary> /// Helper static method, allowing to duplicate a message instance. /// It will duplicate the message, ONLY if the message is marked as "TransportByReference == false" /// or mandatoryDuplication is true. /// </summary> public static Message DuplicateMessage(Message message, bool mandatoryDuplication) { //if (mandatoryDuplication == false && message.TransportByReference) //{ // return message; //} //if (message is ICloneable) //{ // return (Message)((ICloneable)message).Clone(); //} MessageContainer container; try { container = new MessageContainer(); container.SerializeMessage(message); } catch (Exception exception) { TracerHelper.TraceError("Exception in message duplication [" + exception.Message + "]."); throw; } return container.CreateMessageInstance(); }
/// <summary> /// Constructor. /// </summary> public ConversationPointToPoint(ExecutionManager executionManager, Message message, ArbiterClientId senderID, ArbiterClientId receiverID, TimeSpan timeOut) : base(executionManager, senderID, timeOut) { _receiverID = receiverID; ExecutionEntityWithReply entity = new ExecutionEntityWithReply(this, receiverID, timeOut, MessageContainer.DuplicateMessage(message, false)); ExecutionManager.AddExecutionEntity(entity); }
/// <summary> /// Change default TransportClient behaviour. /// Handle a requestMessage received from local Arbiter and send down the pipe. /// </summary> /// <param name="requestMessage"></param> protected override void OnMessageReceived(TransportMessage message) { TracerHelper.TraceEntry(); if (message.TransportInfo == null) { SystemMonitor.Error("Transport message stack can not be null."); } if (message.TransportInfo == null || message.TransportInfo.TransportInfoCount == 0 || message.TransportInfo.CurrentTransportInfo.Value.ReceiverID == null || message.TransportInfo.CurrentTransportInfo.Value.ReceiverID.HasValue == false || message.TransportInfo.CurrentTransportInfo.Value.ReceiverID.Value.Equals(this.SubscriptionClientID) == false) {// This requestMessage was sent to me, not to one of the clients on the server. SystemMonitor.Error("Error. Send messages to server-client instances."); return; } // We shall now establish the tag defining which will be the client connection receiving the requestMessage (or all). // by default send to all. string tagID = "*"; if (message.IsRequest) {// Request. if (message.TransportInfo.ForwardTransportInfoCount != 0) { if (message.TransportInfo.CurrentForwardTransportInfoAddress.HasValue) {// Has value - take it into account, if no value is present, just use the "*" pop, // and use the rest of the AdditionalForwardTransportSessionStack. tagID = message.TransportInfo.CurrentForwardTransportInfoAddress.Value.SessionTag; } // Pop in both cases - if it is null or it is value. message.TransportInfo.PopForwardTransportInfo(); } } else {// Responce. // Clear the transporting information from the last node to here. message.TransportInfo.PopTransportInfo(); // Now this is the additional marking in the case with the server - the marking of the PipeChannel. SystemMonitor.CheckError(message.TransportInfo.TransportInfoCount > 0 && message.TransportInfo.CurrentTransportInfo.Value.SenderID.Value.Id.Name == "PipeChannelID"); // Responce requestMessage, read and pop out the channel ID entry . tagID = message.TransportInfo.PopTransportInfo().Value.SenderID.Value.SessionTag; } MessageContainer container = new MessageContainer(message); TracerHelper.Trace("[" + message.GetType().Name + "], tag [" + tagID + "] length [" + container.MessageStreamLength + "]"); GeneralHelper.FireAndForget(delegate() { _transportServer.SendMessageContainer(tagID, container); }); }
/// <summary> /// Message received from the "Pipe". /// </summary> void _transport_MessageReceivedEvent(string operationContextSessionID, MessageContainer messageContainer) { TransportMessage message = (TransportMessage)messageContainer.CreateMessageInstance(); TracerHelper.Trace("[" + message.GetType().Name + "], length [" + messageContainer.MessageStreamLength + "]"); if (message.IsRequest) { // Request requestMessage. { // Mark the request requestMessage with additional fragment in the transportation stack. ArbiterClientId senderID = new ArbiterClientId("PipeChannelID", null, null); senderID.SessionTag = operationContextSessionID; message.TransportInfo.AddTransportInfoUnit(new TransportInfoUnit(Guid.NewGuid(), senderID, this.SubscriptionClientID)); } if (MandatoryRequestMessageReceiverID.HasValue) {// There is a default receiver assigned for all messages from this integrator. DoSendCustom(true, Guid.NewGuid(), null, 0, MandatoryRequestMessageReceiverID.Value, this.SubscriptionClientID, message, TimeSpan.Zero); } else {// No explicit mandatory receiver. if (message.TransportInfo.ForwardTransportInfoCount > 0) { // First pop the Session stack, than send the cleared requestMessage. ArbiterClientId?receiverID = message.TransportInfo.PopForwardTransportInfo(); DoSendCustom(true, Guid.NewGuid(), null, 0, receiverID, this.SubscriptionClientID, message, TimeSpan.Zero); } else { DoSendCustom(true, Guid.NewGuid(), null, 0, null, this.SubscriptionClientID, message, TimeSpan.Zero); } } } else {// Responce requestMessage - send back to whoever sent it to us before. // And clear off the initial request information, we are responding now to. Guid sessionID = message.TransportInfo.CurrentTransportInfo.Value.Id; ArbiterClientId?receiverID = message.TransportInfo.CurrentTransportInfo.Value.SenderID; message.TransportInfo.PopTransportInfo(); this.DoSendCustom(false, sessionID, null, 0, receiverID, this.SubscriptionClientID, message, TimeSpan.Zero); } }
/// <summary> /// Change default TransportClient behaviour. /// Handle a requestMessage received from local Arbiter and send down the pipe. /// </summary> /// <param name="requestMessage"></param> protected override void OnMessageReceived(TransportMessage message) { if (message.IsRequest == false) {// Responce requestMessage. // Clear off the transporting information from the last node to here. message.TransportInfo.PopTransportInfo(); } MessageContainer container = new MessageContainer(message); TracerHelper.Trace("[" + message.GetType().Name + "], length [" + container.MessageStreamLength + "]"); if (_transportClient != null) { _transportClient.SendMessageContainer(container); } else { SystemMonitor.OperationError("Message received after Integration Client uninitialized [" + message.GetType().Name + "].", TracerItem.PriorityEnum.Medium); } }
/// <summary> /// Entity execution has finished. /// </summary> public override void EntityExecutionFinished(ExecutionEntity entity) { ExecutionEntityWithReply entityWithReply = (ExecutionEntityWithReply)entity; if (entityWithReply.ReplyMessage != null) {// The other side replied. ArbiterClientId messageReceiver = ReceiverID; if (_receiverID.Equals(entity.ReceiverID)) {// Swap direction, receiver must now send. messageReceiver = SenderID; } ExecutionEntityWithReply replyEntity = new ExecutionEntityWithReply(this, messageReceiver, entityWithReply.TimeOut, MessageContainer.DuplicateMessage(entityWithReply.ReplyMessage, false)); ExecutionManager.AddExecutionEntity(replyEntity); } else {// We received a nothing, conversation done, die. this.Die(); } }
/// <summary> /// Handle a requestMessage received trough the transport pipe. /// </summary> /// <param name="messageContainer"></param> void _transport_MessageReceivedEvent(MessageContainer messageContainer) { TransportMessage message = (TransportMessage)messageContainer.CreateMessageInstance(); TracerHelper.Trace("[" + message.GetType().Name + "], length [" + messageContainer.MessageStreamLength + "]"); if (message.IsRequest) {// Request requestMessage. if (MandatoryRequestMessageReceiverID.HasValue) {// There is a default receiver assigned for all messages from this integrator. DoSendCustom(true, Guid.NewGuid(), null, 0, MandatoryRequestMessageReceiverID.Value, this.SubscriptionClientID, message, TimeSpan.Zero); } else {// No explicit mandatory receiver. if (message.TransportInfo.ForwardTransportInfoCount > 0) { // First pop the Session stack, than send the cleared requestMessage. ArbiterClientId? receiverID = message.TransportInfo.PopForwardTransportInfo(); DoSendCustom(true, Guid.NewGuid(), null, 0, receiverID, this.SubscriptionClientID, message, TimeSpan.Zero); } else { DoSendCustom(true, Guid.NewGuid(), null, 0, null, this.SubscriptionClientID, message, TimeSpan.Zero); } } } else {// Responce requestMessage - send back to whoever sent it to us before. // And clear off the initial request information, we are responding now to. Guid sessionID = message.TransportInfo.CurrentTransportInfo.Value.Id; ArbiterClientId? receiverID = message.TransportInfo.CurrentTransportInfo.Value.SenderID; message.TransportInfo.PopTransportInfo(); this.DoSendCustom(false, sessionID, null, 0, receiverID, this.SubscriptionClientID, message, TimeSpan.Zero); } }
/// /// </summary> public ConversationMultiPoint(ExecutionManager executionManager, Message message, ArbiterClientId senderID, IEnumerable <ArbiterClientId> receivers, TimeSpan timeOut) : base(executionManager, senderID, timeOut) { _receivers.AddRange(receivers); foreach (ArbiterClientId receiverID in receivers) { ExecutionEntity entity = new ExecutionEntity(this, receiverID, TimeSpan.Zero, MessageContainer.DuplicateMessage(message, false)); _executingEntities.Add(entity); ExecutionManager.AddExecutionEntity(entity); } }