/// <summary>
 /// 
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="receiver"></param>
 /// <param name="timeOut"></param>
 /// <param name="requestMessage"></param>
 public ExecutionEntity(IExecutor executor, ArbiterClientId receiverID, TimeSpan timeOut, Message message)
     : base(timeOut)
 {
     _executor = executor;
     _receiverID = receiverID;
     _message = message;
 }
        /// <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>
        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);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public override Message ReceiveDirectCall(Message message)
        {
            try
            {
                //Type type = entity.Message.GetType();
                //object t = Activator.CreateInstance(type);

                XmlSerializer s = new XmlSerializer(message.GetType());

                s.Serialize(_fileStream, message);
            }
            catch (Exception e)
            {
                SystemMonitor.Error("Serialization failure [" + e.Message + "]");
            }

            return null;
        }
        /// <summary>
        /// Do the filtering based on the transportSessionGuid but allow all that are starting a session now.
        /// </summary>
        /// <param name="requestMessage"></param>
        public override bool MessageAllowed(Message messageInput)
        {
            SystemMonitor.CheckError(messageInput is TransportMessage);
            TransportMessage message = (TransportMessage)messageInput;

            if (this.Enabled == false)
            {
                return true;
            }

            bool isTypeAllowed = base.MessageAllowed(message);
            bool isAddressed = (message.TransportInfo.CurrentTransportInfo.Value.ReceiverID != null);
            bool isAddressedToMe = IsAddressedToMe(message);

            if (AllowOnlyAddressedMessages)
            {// Addressed mode.
                if (isAddressed == false || isAddressedToMe == false)
                {
                    return false;
                }
            }
            else
            {// Non addressed mode.
                if (isAddressed && isAddressedToMe == false)
                {// Addressed to someone else.
                    return false;
                }
            }

            // Addressing solved - it allowed the requestMessage to pass on.
            if (message.IsRequest)
            {// Request.
                return isTypeAllowed;
            }
            else
            {// Responce - accept.
                return true;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="requestMessage"></param>
        /// <returns></returns>
        public virtual bool MessageAllowed(Message message)
        {
            if (!_enabled)
            {
                return true;
            }

            Type requiredType = message.GetType();

            foreach (Type messageType in _allowedNonAddressedMessageTypes)
            {
                if (messageType == requiredType)
                {// Type matched.
                    return true;
                }

                if (_allowChildrenTypes && requiredType.IsSubclassOf(messageType))
                {// Subclasses allowed and this is one.
                    return true;
                }
            }

            return false;
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 public MessageContainer(Message message)
 {
     SerializeMessage(message);
 }
 /// <summary>
 /// Serializes the message to the internal stream and keeps it there for future usage.
 /// </summary>
 public void SerializeMessage(Message message)
 {
     lock (_messageStream)
     {
         _messageStream.SetLength(0);
         if (message != null)
         {
             try
             {
                 BinaryFormatter formatter = new BinaryFormatter();
                 formatter.Serialize(_messageStream, message);
             }
             catch (Exception exception)
             {
                 TracerHelper.TraceError("Exception in message serialization [" + exception.Message + "].");
                 throw;
             }
         }
     }
 }
示例#10
0
        /// <summary>
        /// Find out what clients need to receive this requestMessage.
        /// </summary>
        /// <param name="requestMessage"></param>
        /// <returns></returns>
        public IEnumerable<ArbiterClientId> GatherMessageClients(Message message, ArbiterClientId senderID)
        {
            List<ArbiterClientId> clients = new List<ArbiterClientId>();
            if (_isDisposed)
            {// Possible to get disposed while operating here.
                return null;
            }

            lock (_clientsAndFilters)
            {
                foreach (IArbiterClient client in _clientsAndFilters.Keys)
                {
                    if (_clientsAndFilters[client].MessageAllowed(message))
                    {
                        clients.Add(client.SubscriptionClientID);
                    }
                }
            }
            return clients;
        }
示例#11
0
        /// <summary>
        /// Will start a shoutcast mode conversation, the sender sending to all.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="requestMessage"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public ConversationMultiPoint CreateConversation(ArbiterClientId senderID, Message message, TimeSpan timeout)
        {
            if (message is TransportMessage)
            {
                SystemMonitor.CheckError(((TransportMessage)message).TransportInfo.CurrentTransportInfo != null);
                TracerHelper.Trace("sender[" + senderID.Id.Name + "], message [" + message.GetType().Name + "] [" + ((TransportMessage)message).TransportInfo.TransportInfoCount + "]");
            }
            else
            {
                TracerHelper.Trace("sender[" + senderID.Id.Name + "], message [" + message.GetType().Name + "]");
            }

            if (GetClientByID(senderID, false) == null)
            {
                SystemMonitor.Error("Creating conversation by not present sender/owner.");
                return null;
            }

            ConversationMultiPoint conversation = new ConversationMultiPoint(_executionManager, message, senderID, GatherMessageClients(message, senderID), timeout);

            if (_isDisposed)
            {// Possible to get disposed while operating here.
                return null;
            }

            lock (_timeOutMonitor)
            {
                _timeOutMonitor.AddEntity(conversation);
            }
            return conversation;
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="requestMessage"></param>
 /// <param name="timeOut"></param>
 public void SetReply(Message message, TimeSpan timeOut)
 {
     _replyMessage = message;
     _replyTimeOut = timeOut;
 }
 public ExecutionEntityWithReply(Conversation conversation, ArbiterClientId receiverID, TimeSpan timeOut, Message message)
     : base(conversation, receiverID, timeOut, message)
 {
 }
 public abstract Message ReceiveDirectCall(Message message);
示例#15
0
        /// <summary>
        /// The direct call allows to circumvent the many steps (incl serialization) of typical message sending
        /// and make a direct call to another Arbiter member; thus making a much faster delivery. This path
        /// has a maximum optimization for speed, so tracing etc. are disabled.
        /// 
        /// Also this mechanism only works for TransportClients currently.
        /// 
        /// The mechanism does not utilize any new threads, and the execution is performed on the calling thread.
        /// 
        /// Direct calls can only be made to participants on the same arbiter, and no addressing is applied
        /// for the messages.
        /// </summary>
        public Message DirectCall(ArbiterClientId senderID, ArbiterClientId receiverID, Message message)
        {
            IArbiterClient receiver = GetClientByID(receiverID, true);
            if (receiver == null || receiver is TransportClient == false)
            {
                SystemMonitor.OperationWarning("Sender [" + senderID.Id.Print() + "] creating conversation message [" + message.GetType().Name + " ] by not present receiver [" + receiverID.Id.Print() + "] or receiver not a TransportClient");
                return null;
            }

            Message response = receiver.ReceiveDirectCall(message);
            return response;
        }