Example #1
0
        public void RegisterListener(int messageId, ClientMessageListener listener)
        {
            if (!messageListenerDic.TryGetValue(messageId, out var list))
            {
                list = ListPool <ClientMessageListener> .Get();

                messageListenerDic.Add(messageId, list);
            }

            list.Add(listener);
        }
Example #2
0
 public void UnregisterListener(int messageId, ClientMessageListener listener)
 {
     if (messageListenerDic.TryGetValue(messageId, out var list))
     {
         if (list.Remove(listener))
         {
             if (list.Count == 0)
             {
                 messageListenerDic.Remove(messageId);
                 ListPool <ClientMessageListener> .Release(list);
             }
         }
     }
 }
        /// <summary>
        /// Operation method that sends a message to the Server. The message is interpreted and handled by
        /// the Metadata Adapter associated to the current Session. This operation supports in-order
        /// guaranteed message delivery with automatic batching. In other words, messages are guaranteed
        /// to arrive exactly once and respecting the original order, whatever is the underlying transport
        /// (HTTP or WebSockets). Furthermore, high frequency messages are automatically batched, if necessary,
        /// to reduce network round trips. <br/>
        /// Upon subsequent calls to the method, the sequential management of the involved messages is guaranteed.
        /// The ordering is determined by the order in which the calls to sendMessage are issued.
        /// However, any message that, for any reason, doesn't reach the Server can be discarded by the Server
        /// if this causes the subsequent message to be kept waiting for longer than a configurable timeout.
        /// Note that, because of the asynchronous transport of the requests, if a zero or very low timeout is
        /// set for a message, it is not guaranteed that the previous message can be processed, even if no communication
        /// issues occur. <br/>
        /// Sequence identifiers can also be associated with the messages. In this case, the sequential management is
        /// restricted to all subsets of messages with the same sequence identifier associated. <br/>
        /// Notifications of the operation outcome can be received by supplying a suitable listener. The supplied
        /// listener is guaranteed to be eventually invoked; listeners associated with a sequence are guaranteed
        /// to be invoked sequentially. <br/>
        /// The "UNORDERED_MESSAGES" sequence name has a special meaning. For such a sequence, immediate processing
        /// is guaranteed, while strict ordering and even sequentialization of the processing is not enforced.
        /// Likewise, strict ordering of the notifications is not enforced. However, messages that, for any reason,
        /// should fail to reach the Server whereas subsequent messages had succeeded, might still be discarded after
        /// a server-side timeout. <br/>
        /// Moreover, if "UNORDERED_MESSAGES" is used and no listener is supplied, a "fire and forget" scenario
        /// is assumed. In this case, no checks on missing, duplicated or overtaken messages are performed at all,
        /// so as to optimize the processing and allow the highest possible throughput.
        ///
        /// <b>Lifecycle:</b>  Since a message is handled by the Metadata Adapter associated to the current connection, a
        /// message can be sent only if a connection is currently active. If the special enqueueWhileDisconnected
        /// flag is specified it is possible to call the method at any time and the client will take care of sending
        /// the message as soon as a connection is available, otherwise, if the current status is "DISCONNECTED*",
        /// the message will be abandoned and the <seealso cref="ClientMessageListener.onAbort"/> event will be fired. <br/>
        /// Note that, in any case, as soon as the status switches again to "DISCONNECTED*", any message still pending
        /// is aborted, including messages that were queued with the enqueueWhileDisconnected flag set to true. <br/>
        /// Also note that forwarding of the message to the server is made appending the request to
        /// the internal scheduler queue; hence, if a message
        /// is sent while the connection is active, it could be aborted because of a subsequent disconnection.
        /// In the same way a message sent while the connection is not active might be sent because of a subsequent
        /// connection.
        /// </summary>
        /// <param name="message"> a text message, whose interpretation is entirely demanded to the Metadata Adapter
        /// associated to the current connection. </param>
        /// <param name="sequence"> an alphanumeric identifier, used to identify a subset of messages to be managed in sequence;
        /// underscore characters are also allowed. If the "UNORDERED_MESSAGES" identifier is supplied, the message will
        /// be processed in the special way described above. The parameter is optional; if set to null, "UNORDERED_MESSAGES"
        /// is used as the sequence name. </param>
        /// <param name="delayTimeout"> a timeout, expressed in milliseconds. If higher than the Server default timeout, the
        /// latter will be used instead. <br/>
        /// The parameter is optional; if a negative value is supplied, the Server default timeout will be applied. <br/>
        /// This timeout is ignored for the special "UNORDERED_MESSAGES" sequence, for which a custom server-side
        /// timeout applies. </param>
        /// <param name="listener"> an object suitable for receiving notifications about the processing outcome. The parameter is
        /// optional; if not supplied, no notification will be available. </param>
        /// <param name="enqueueWhileDisconnected"> if this flag is set to true, and the client is in a disconnected status when
        /// the provided message is handled, then the message is not aborted right away but is queued waiting for a new
        /// session. Note that the message can still be aborted later when a new session is established. </param>
        public virtual void sendMessage(string message, string sequence, int delayTimeout, ClientMessageListener listener, bool enqueueWhileDisconnected)
        {
            lock (this)
            {
                if (string.ReferenceEquals(sequence, null))
                {
                    sequence = Constants.UNORDERED_MESSAGES;
                }
                else if (!ext_alpha_numeric.Match(sequence).Success)
                {
                    throw new System.ArgumentException("The given sequence name is not valid, use only alphanumeric characters plus underscore, or null");
                }

                string seq = sequence;
                eventsThread.queue(() =>
                {
                    messages.send(message, seq, delayTimeout, listener, enqueueWhileDisconnected);
                });
            }
        }