コード例 #1
0
ファイル: Dispatcher.cs プロジェクト: toomasz/emitter
        /// <summary>
        /// Publishes a message.
        /// </summary>
        /// <param name="contract">The contract</param>
        /// <param name="message">The message to publish.</param>
        /// <param name="channelHash">The hashed channel id.</param>
        /// <param name="channelName">The full name of the channel.</param>
        /// <param name="ttl">The time-to-live value for the message.</param>
        public static void Publish(EmitterContract contract, uint channelHash, string channelName, ArraySegment <byte> message, int ttl = EmitterConst.Transient)
        {
            try
            {
                // Make sure the TTL is within limits and max is 30 days.
                if (ttl < 0)
                {
                    ttl = EmitterConst.Transient;
                }
                if (ttl > 2592000)
                {
                    ttl = 2592000;
                }

                var contractId = contract.Oid;
                var cid        = ((long)contractId << 32) + channelHash;

                // Increment the counter
                Service.MessageReceived?.Invoke(contract, channelName, message.Count);

                // The SSID
                var ssid = EmitterChannel.Ssid(contractId, channelName);

                // Get the subscriptions
                var subs = Subscription.Match(ssid);
                if (subs != null)
                {
                    // Fast-Path: check local subscribers and send it to them
                    ForwardToClients(contractId, channelName, message, subs);

                    // Publish into the messaging cluster once
                    ForwardToServers(contractId, channelName, message, subs);
                }

                // Only call into the storage service if necessary
                if (ttl > 0 && Services.Storage != null)
                {
                    // If we have a storage service, store the message
                    Services.Storage.AppendAsync(contractId, ssid, ttl, message);
                }
            }
            catch (Exception ex)
            {
                Service.Logger.Log(LogLevel.Warning, "Publish failed. Reason: " + ex.Message);
                //Service.Logger.Log(ex);
                return;
            }
        }
コード例 #2
0
ファイル: Dispatcher.cs プロジェクト: toomasz/emitter
        /// <summary>
        /// Forwards a message to a set of subscriptions
        /// </summary>
        internal static void ForwardToClients(int contractId, string channel, ArraySegment <byte> message)
        {
            // Separator must be added
            channel += EmitterConst.Separator;

            // Create an SSID
            var ssid = EmitterChannel.Ssid(contractId, channel);

            // Get the matching subscriptions
            var subs = Subscription.Match(ssid);

            if (subs == null)
            {
                return;
            }

            // Forward to the clients
            ForwardToClients(contractId, channel, message, subs);
        }
コード例 #3
0
        /// <summary>
        /// Unregisters a subscription from the current registry.
        /// </summary>
        /// <param name="client">The client to unsubscribe.</param>
        /// <param name="contract">The contract.</param>
        /// <param name="channel"></param>
        /// <returns>Whether the subscription was removed or not.</returns>
        public static bool Unregister(IMqttSender client, int contract, string channel, SubscriptionInterest interest, out Subscription subs)
        {
            // Make the subscription id
            var ssid = EmitterChannel.Ssid(contract, channel);

            // Get the subscription first
            if (!Index.TryGetValue(ssid, 0, out subs))
            {
                return(false);
            }

            // Validate, only the correct contract can unsubscribe
            if (subs.ContractKey != contract)
            {
                return(false);
            }

            // Unregister a client
            subs.Unsubscribe(client, interest);
            return(true);
        }
コード例 #4
0
        /// <summary>
        /// Disposes the subscription.
        /// </summary>
        public void Dispose()
        {
            try
            {
                // Unbind events
                if (this.Presence != null)
                {
                    this.Presence.Change -= this.OnPresenceChange;
                }

                // Get the ssid
                var ssid = EmitterChannel.Ssid(this.ContractKey, this.Channel);

                // Remove the subscription from the registry
                Subscription removed;
                Index.TryRemove(ssid, 0, out removed);
            }
            catch (Exception ex)
            {
                Service.Logger.Log(ex);
            }
        }
コード例 #5
0
        /// <summary>
        /// Unregisters a subscription from the current registry.
        /// </summary>
        /// <param name="server">The server to unsubscribe.</param>
        /// <param name="contract">The contract.</param>
        /// <param name="channel"></param>
        /// <returns>Whether the subscription was removed or not.</returns>
        public static bool Unregister(IServer server, int contract, string channel)
        {
            // Make the subscription id
            var ssid = EmitterChannel.Ssid(contract, channel);

            // Get the subscription first
            Subscription subs;

            if (!Index.TryGetValue(ssid, 0, out subs))
            {
                return(false);
            }

            // Validate, only the correct contract can unsubscribe
            if (subs.ContractKey != contract)
            {
                return(false);
            }

            // Unregister a server
            subs.Unsubscribe(server);
            return(false);
        }
コード例 #6
0
 /// <summary>
 /// Adds or updates the subscription.
 /// </summary>
 /// <param name="channel">The channel for the subscription to find.</param>
 /// <param name="contract">The channel for the subscription to find.</param>
 /// <param name="addFunc">The add function to execute.</param>
 /// <param name="updateFunc">The update function to execute.</param>
 /// <returns></returns>
 public Subscription AddOrUpdate(int contract, string channel, Func <Subscription> addFunc, Func <Subscription, Subscription> updateFunc)
 {
     return(this.AddOrUpdate(EmitterChannel.Ssid(contract, channel), 0, addFunc, updateFunc));
 }
コード例 #7
0
 /// <summary>
 /// Attempts to fetch a subscription from the trie.
 /// </summary>
 /// <param name="sub">The subscription retrieved.</param>
 /// <param name="channel">The channel for the subscription to find.</param>
 /// <param name="contract">The channel for the subscription to find.</param>
 /// <returns>Whether the subscription was found or not.</returns>
 public bool TryGetValue(int contract, string channel, out Subscription sub)
 {
     return(this.TryGetValue(EmitterChannel.Ssid(contract, channel), 0, out sub));
 }
コード例 #8
0
        /// <summary>
        /// Attempts to remove a subscription from the trie.
        /// </summary>
        /// <param name="sub">The subscription to remove.</param>
        /// <returns>Whether the subscription was removed or not.</returns>
        public bool TryRemove(Subscription sub)
        {
            Subscription removed;

            return(this.TryRemove(EmitterChannel.Ssid(sub.ContractKey, sub.Channel), 0, out removed));
        }
コード例 #9
0
 /// <summary>
 /// Attempts to add a subscription to the trie.
 /// </summary>
 /// <param name="sub">The subscription to add.</param>
 /// <returns>Whether the subscription was added or not.</returns>
 public bool TryAdd(Subscription sub)
 {
     return(this.TryAdd(EmitterChannel.Ssid(sub.ContractKey, sub.Channel), sub));
 }