/// <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(); } } }
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; }
/// <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); }
/// <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) ); } }
/// <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); } }
/// <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); }
/// <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); }
/// <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); } } }
/// <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; }
public Worker(ITemzitReader temzitReader, IMqttSender mqttSender) { _temzitReader = temzitReader; _mqttSender = mqttSender; }
/// <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)); }