Example #1
0
        /// <summary>
        /// Removes a client from the memebership list.
        /// </summary>
        /// <param name="client">The client to remove.</param>
        /// <returns>The current membership.</returns>
        public void Unsubscribe(IMqttSender client, SubscriptionInterest interest)
        {
            lock (this)
            {
                // Remove from the membership
                if (interest.HasFlag(SubscriptionInterest.Messages) && ArrayUtils.Remove(ref this.MessageSubscribers, client) >= 0)
                {
                    // Remove the client from the presence
                    if (client.Id != ConnectionId.Empty)
                    {
                        Console.WriteLine("Removing from presence: " + client.Id);
                        this.Presence.Remove(client.Id.ToString());
                    }

                    if (this.Listeners == 0)
                    {
                        // Broadcast unsubscribe if there's no more clients left
                        this.BroadcastUnsubscribe(client);
                    }
                }

                if (interest.HasFlag(SubscriptionInterest.Presence))
                {
                    // Unregister the client presence as well
                    ArrayUtils.Remove(ref this.PresenceSubscribers, client);
                }

                // Dispose the subscription if empty
                if (this.Empty)
                {
                    this.Dispose();
                }
            }
        }
Example #2
0
 public Engine(ILoggerFactory loggerFactory, IOptions <TrafikverketSettings> settings, IMqttSender sender)
 {
     logger                  = loggerFactory.CreateLogger <Engine>();
     trainStationClient      = new TrafikverketTrainStationClient(settings.Value.ApiKey);
     trainAnnouncementClient = new TrafikverketTrainAnnouncemenClient(settings.Value.ApiKey);
     this.sender             = sender;
     this.settings           = settings;
 }
Example #3
0
        /// <summary>
        /// Constructs a new subscription.
        /// </summary>
        /// <param name="contract">The contract that subscribes.</param>
        /// <param name="channel">The channel to subscribe to.</param>
        /// <param name="client">The first member.</param>
        /// <param name="interest">The interest of the subsriber</param>
        public Subscription(int contract, string channel, IMqttSender client, SubscriptionInterest interest)
        {
            this.ContractKey = contract;
            this.Channel     = channel;

            // Get the contract and set the presence reference
            this.Presence         = this.Contract.Info.GetOrCreate <SubscriptionPresence>(channel);
            this.Presence.Change += OnPresenceChange;
            this.Subscribe(client, interest);
        }
Example #4
0
 /// <summary>
 /// Sends an unsubscribe event through the mesh.
 /// </summary>
 /// <param name="subscription"></param>
 public static void BroadcastUnsubscribe(this Subscription subscription, IMqttSender client)
 {
     // Broadcast to peers
     foreach (var peer in Service.Mesh.Members)
     {
         // Send it as a command
         peer.Send(
             MeshEmitterEvent.Acquire(MeshEventType.Unsubscribe, subscription.ContractKey, subscription.Channel)
             );
     }
 }
Example #5
0
        /// <summary>
        /// Unregisters a subscription from the current registry.
        /// </summary>
        /// <param name="client">The client to unsubscribe.</param>
        /// <param name="ssid">The subscription to unregister.</param>
        /// <param name="contract">The contract to unsubscribe.</param>
        /// <param name="interest">The interest of the subscription.</param>
        /// <returns>Whether the subscription was removed or not.</returns>
        public static bool Unsubscribe(IMqttSender client, int contract, string channel, SubscriptionInterest interest)
        {
            // First we attempt to unregister the subscription
            Subscription subscription;

            if (Subscription.Unregister(client, contract, channel, interest, out subscription))
            {
                // Successfully unsubscribed
                return(true);
            }
            else
            {
                // We didn't manage to unsubscibe
                return(false);
            }
        }
Example #6
0
        /// <summary>
        /// Creates a new subscription.
        /// </summary>
        /// <param name="client">The client to subscribe.</param>
        /// <param name="contract">The contract that subscribes.</param>
        /// <param name="channel">The channel to subscribe to.</param>
        /// <returns>The subscription data structure.</returns>
        public static unsafe Subscription Register(IMqttSender client, int contract, string channel, SubscriptionInterest interest)
        {
            // Register the subscription
            var subs = Index.AddOrUpdate(contract, channel,
                                         () => new Subscription(contract, channel, client, interest),
                                         (v) =>
            {
                // If we're simply updating an existing one, increment the number of clients we have
                v.Subscribe(client, interest);
                return(v);
            });

            // Every time a client subscribes, broadcast it through the network
            subs.BroadcastSubscribe(client);

            // Return the subscription
            return(subs);
        }
Example #7
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);
        }
Example #8
0
        /// <summary>
        /// Subscribes a client by adding it to an appropriate membership list.
        /// </summary>
        /// <param name="client">The client to subscribe.</param>
        /// <param name="interest">The interests to register for.</param>
        /// <returns></returns>
        public void Subscribe(IMqttSender client, SubscriptionInterest interest)
        {
            lock (this)
            {
                if (interest.HasFlag(SubscriptionInterest.Messages))
                {
                    // Add to the membership list
                    ArrayUtils.AddUnique(ref this.MessageSubscribers, client);

                    // Add to the presence. Since the presence is inside the registry, it will be automatically
                    // synchronized and eventually consistent across the cluster.
                    if (client.Id != ConnectionId.Empty)
                    {
                        this.Presence.Add(client.Id.ToString(), new SubscriptionPresenceInfo(client));
                    }
                }

                if (interest.HasFlag(SubscriptionInterest.Presence))
                {
                    // Subscribe to presence events
                    ArrayUtils.AddUnique(ref this.PresenceSubscribers, client);
                }
            }
        }
Example #9
0
 /// <summary>
 /// Creates a new presence info from the client.
 /// </summary>
 /// <param name="client">The client just subscribed.</param>
 public SubscriptionPresenceInfo(IMqttSender client)
 {
     this.ClientId = client.Context.ClientId;
     this.Username = client.Context.Username;
 }
Example #10
0
 public Worker(ITemzitReader temzitReader, IMqttSender mqttSender)
 {
     _temzitReader = temzitReader;
     _mqttSender   = mqttSender;
 }
Example #11
0
 /// <summary>
 /// Subscribe will express interest in the given subject. The subject
 /// can have wildcards (partial:*, full:>).
 /// </summary>
 /// <param name="sender">The sender to subscribe.</param>
 /// <param name="contract">The contract for this operation.</param>
 /// <param name="channel">The channel to subscribe to.</param>
 /// <param name="interest">The interest of the subscription.</param>
 /// <returns>The subscription id.</returns>
 public static Subscription Subscribe(IMqttSender sender, int contract, string channel, SubscriptionInterest interest)
 {
     // Hook the subscription unregister when the client disconnects, this way
     // we should not leak any memory since the disconnect is reliable.
     return(Subscription.Register(sender, contract, channel, interest));
 }