/// <summary>订阅主题</summary> /// <param name="user"></param> /// <param name="session"></param> /// <returns></returns> public Boolean Add(String user, IApiSession session) { if (Subscribers.ContainsKey(user)) { return(false); } var scb = new Subscriber { User = user, Session = session }; Subscribers[user] = scb; var ds = session as IDisposable2; if (ds != null) { ds.OnDisposed += (s, e) => Remove(user); } #if DEBUG var msg = new Message { Sender = user, Body = "上线啦" }; Enqueue(msg); #endif return(true); }
public void Off(BaseComponent subscriber) { if (Subscribers != null) { if (Subscribers.ContainsKey(subscriber)) { Subscribers[subscriber].Clear(); } } }
public IEnumerable <IJsonSubscriber> GetSubscribers(string streamName = null) { if (streamName == null) { return(Subscribers.Values.SelectMany(s => s)); } else { return Subscribers.ContainsKey(streamName) ? Subscribers[streamName] : new IJsonSubscriber[] { } }; }
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } if (Subscribers != null && Subscribers.ContainsKey(propertyName)) { Subscribers[propertyName](); } }
public void Unsubscribe(string page) { Debug.WriteLine($"Unsubscribe {page}"); if (!Subscribers.ContainsKey(page)) { return; } Subscribers.Remove(page); }
public void Subscribe <TMessage>(Action <TMessage> handler) { var messageType = typeof(TMessage); if (Subscribers.ContainsKey(messageType) == false) { Subscribers[messageType] = new List <Action <object> >(); } Subscribers[messageType].Add(message => handler((TMessage)message)); _other.Subscribe <TMessage>(handler); }
public void Subscribe(string page, Action handler) { Debug.WriteLine($"Subscribe {page}"); if (Subscribers.ContainsKey(page)) { Subscribers[page] = handler; } else { Subscribers.Add(page, handler); } }
/// <summary> /// Operation to unsubscribe an event sink for an existing subscription. /// </summary> /// <param name="request">The <see cref="UnsubscribeRequestMessage">request message</see> containing the unsubscription request details.</param> public void Unsubscribe(UnsubscribeRequestMessage request) { Guid id; request.Identifier.Value.TryGetGuid(out id); var exists = Subscribers.ContainsKey(id); if (exists) { Subscribers.Remove(id); } }
public virtual void Unsubscribe(string listenKey, Action <UserDataEventArgs> callback) { Throw.IfNullOrWhiteSpace(listenKey, nameof(listenKey)); Logger?.LogDebug($"{nameof(UserDataWebSocketClient)}.{nameof(Unsubscribe)}: \"{listenKey}\" (callback: {(callback == null ? "no" : "yes")}). [thread: {Thread.CurrentThread.ManagedThreadId}]"); // Unsubscribe callback (if provided) from listen key. UnsubscribeStream(listenKey, callback); // If listen key was removed from subscribers (no callbacks). if (!Subscribers.ContainsKey(listenKey)) { // Remove listen key (and user). ListenKeys.Remove(listenKey); } }
public async void SendNotifyAboutSyncError(string email, string errorMessage) { if (Subscribers.ContainsKey(email)) { try { await Bot.SendTextMessageAsync(Subscribers[email], errorMessage); } catch (System.Exception) { await Task.Delay(3000).ContinueWith(async(a) => { await Bot.SendTextMessageAsync(Subscribers[email], errorMessage); }); } } }
/// <summary> /// Operation to update the expiration for a subscription. The subscriber sends a request to the subscription manager /// and if the subscription manager accepts a request to renew a subscription the new expiration details will be returned. /// </summary> /// <param name="request">The <see cref="RenewRequestMessage">request message</see> containing the renewal request details.</param> /// <returns>The <see cref="RenewResponseMessage">RenewResponseMessage</see> containing the new subscription expiration details.</returns> public RenewResponseMessage Renew(RenewRequestMessage request) { Guid id = Subscribers.Keys.First(); request.Identifier.Value.TryGetGuid(out id); var exists = Subscribers.ContainsKey(id); if (!exists) { return(new RenewResponseMessage()); } Subscribers[id] = new Tuple <Uri, DateTime>(Subscribers[id].Item1, DateTime.UtcNow.AddDays(5)); return(new RenewResponseMessage(new Expires(Subscribers[id].Item2))); }
/// <summary> /// Operation to get the status of a subscription. The subscriber sends a request to the subscription manager /// and if the subscription is valid and has not expired the status will be returned. /// </summary> /// <param name="request">The <see cref="GetStatusRequestMessage">request message</see> containing the subscription status request details.</param> /// <returns>The <see cref="GetStatusResponseMessage">GetStatusResponseMessage</see> containing the subscription status details.</returns> public GetStatusResponseMessage GetStatus(GetStatusRequestMessage request) { Guid id; request.Identifier.Value.TryGetGuid(out id); var exists = Subscribers.ContainsKey(id); if (!exists) { return(new GetStatusResponseMessage(new GetStatusResponseMessageBody())); } var isExpired = Subscribers[id].Item2 < DateTime.UtcNow; return(!isExpired ? new GetStatusResponseMessage(new GetStatusResponseMessageBody(new Expires(Subscribers[id].Item2))) : new GetStatusResponseMessage(new GetStatusResponseMessageBody())); }
public async void SendNotifyFileLoadSuccess(StorageItemInfo item) { TelegramContext.WithFileHash(item.Hash); if (!Subscribers.ContainsKey(item.Owner)) { return; } var ChatId = Subscribers[item.Owner]; try { try { using (MemoryStream imageStream = FFTools.CreateThumbnail(item.FullPath)) { Message result = await Bot.SendPhotoAsync( ChatId, imageStream, string.Format("{0} ({1}) done", item.Name, item.GetFormatSize()), replyMarkup : Keyboards.CommonFileActions()); MessagesHystory.Push(result); } } catch (Exception) { await Bot.SendTextMessageAsync(ChatId, string.Format("{0} ({1}) done", item.Name, item.GetFormatSize())); } } catch (Exception) { await Task.Delay(3000).ContinueWith(async(a) => { await Bot.SendTextMessageAsync(ChatId, string.Format("{0} ({1}) done", item.Name, item.GetFormatSize())); }); } }
/// <summary> /// Parse the message provided through the buffer /// </summary> /// <param name="buffer">The string content of the Irc communication</param> /// <param name="outputWriter">The TextWriter that we can use to pass information back to the Irc server</param> private void ParseIrcMessage(string buffer, TextWriter outputWriter) { // Irc splits information via spacebars. Irritating as hell IMO var splitText = buffer.Split(' '); switch (splitText[1]) { // 001 is notification that it was a successful login. We have no interest // in the MOTD, but it'd be after 001 if you want to get it. The documentation of what spews out of Twitch Irc // is at https://github.com/justintv/Twitch-API/blob/master/IRC.md // If you want to read multiple channels at a time, turn _channel into a list and iterate the output.Write + output.Flush // for each channel case "001": // Lets me know it's being used at least if (_channel != "chirpertestclient") { outputWriter.Write( "PRIVMSG #chirpertestclient :" + UserName + " started mod\r\n" ); } outputWriter.Flush(); outputWriter.Write( //"MODE " + UserName + "\r\n" + "JOIN " + "#" + _channel + "\r\n" ); outputWriter.Flush(); User loginSuccessfulTwitchUser; lock (LoggedInUsers) { // The user won't always be here. If someone immediately joins and says "Hey guys!", they probably won't actually be in here. // Twitch queues all the joins and sends them out every 10 seconds, so my program might not have gotten the memo yet if (!LoggedInUsers.TryGetValue("twitch", out loginSuccessfulTwitchUser)) { loginSuccessfulTwitchUser = new User() { UserName = "******" }; LoggedInUsers.Add(loginSuccessfulTwitchUser.UserName, loginSuccessfulTwitchUser); } } if (ChatMessageReceived != null) { ChatMessageReceived(this, new ChatMessageReceivedEventArgs(new IrcMessage(loginSuccessfulTwitchUser, UserName, _channel, "Login successful! Currently logged in as " + UserName + " and listening to " + _channel, true))); } break; // Looks like login failed case "NOTICE": var noticeMessage = buffer.Substring(NthIndexOf(buffer, ":", 2) + 1, (buffer.Length - NthIndexOf(buffer, ":", 2)) - 1); if (noticeMessage.Contains("Login unsuccessful")) { User targetTwitchUser; lock (LoggedInUsers) { // The user won't always be here. If someone immediately joins and says "Hey guys!", they probably won't actually be in here. // Twitch queues all the joins and sends them out every 10 seconds, so my program might not have gotten the memo yet if (!LoggedInUsers.TryGetValue("twitch", out targetTwitchUser)) { targetTwitchUser = new User() { UserName = "******" }; LoggedInUsers.Add(targetTwitchUser.UserName, targetTwitchUser); } } if (ChatMessageReceived != null) { ChatMessageReceived(this, new ChatMessageReceivedEventArgs(new IrcMessage(targetTwitchUser, UserName, _channel, "Login failed! Are you sure you have the right username and oauth key?", true))); } if (Disconnected != null) { Disconnected(this, new DisconnectedEventArgs("Login failed!")); } } break; // Time to start getting all of the logged in users case "353": if (_channel == "chirpertestclient") { break; } lock (LoggedInUsers) { // The first one starts out with a : on their name. The easiest way to get rid of it is to manage it first before any // looping is done if (!LoggedInUsers.ContainsKey(splitText[5].Replace(":", ""))) { LoggedInUsers.Add(splitText[5].Replace(":", ""), new User() { UserName = splitText[5].Replace(":", "") }); } for (var i = 6; i < splitText.Count(); i++) { if (!LoggedInUsers.ContainsKey(splitText[i])) { LoggedInUsers.Add(splitText[i], new User() { UserName = splitText[i] }); } } } break; // Now for the mods case "MODE": if (_channel == "chirpertestclient") { break; } // Hey, a moderator if (splitText[3] == "+o") { lock (Moderators) { if (!Moderators.ContainsKey(splitText[4])) { Moderators.Add(splitText[4], new User() { UserName = splitText[4] }); } } } break; // Hey, someone's joining case "JOIN": if (_channel == "chirpertestclient") { break; } var joiningUser = splitText[0].Substring(1, splitText[0].IndexOf("!", StringComparison.Ordinal) - 1); // We don't count ourselves because our leave/join event is already obvious to the program. The "353" call above will // have our name in it, so we want to skip it here if (String.Compare(joiningUser, UserName, StringComparison.Ordinal) != 0) { lock (LoggedInUsers) { // And make sure the list doesn't already have them, or the program will crash on a duplicate insert attempt if (!LoggedInUsers.ContainsKey(joiningUser)) { LoggedInUsers.Add(joiningUser, new User() { UserName = joiningUser }); } } } break; // Ruh roh, we lost someone case "PART": if (_channel == "chirpertestclient") { break; } var leavingUser = splitText[0].Substring(1, splitText[0].IndexOf("!", StringComparison.Ordinal) - 1); lock (LoggedInUsers) { // If the key doesn't exist no exception is thrown LoggedInUsers.Remove(leavingUser); } break; // PRIVMSG isn't a private message necessarily. It can be either a channel or a user message. // Currently I only care about channel messages, but I don't filter out personal messages, they just get put // into the same queue case "PRIVMSG": // My arch nemesis, Substring. As a warning if you edit this, Substring is a pain in the ass. The first parameter is where // in the string starts. The second parameter is how long it should read for, NOT THE END POINT IT SHOULD READ TO! var userName = splitText[0].Substring(1, splitText[0].IndexOf("!", StringComparison.Ordinal) - 1); var message = buffer.Substring(NthIndexOf(buffer, ":", 2) + 1, (buffer.Length - NthIndexOf(buffer, ":", 2)) - 1); // Don't care about chirper chat messages not from me if (_channel == "chirpertestclient" && userName != "rabidcrabgt" && !Regex.IsMatch(message, "#moddev", RegexOptions.IgnoreCase)) { break; } // It could be a twitch notification we care about, let's check it out if (userName == "twitchnotify") { // A new or repeat subscriber, sweet if (buffer.Contains("subscribed")) { User newSubscriber; var subscriberUserName = message.Split(' ')[0]; int monthsSubscribed = 1; // A repeat subscriber, let's show them we care if (buffer.Contains("months in a row")) { monthsSubscribed = int.Parse(message.Split(' ')[3]); } lock (Subscribers) { // It can be either a new subscription or a repeat one. If it's a repeat, we'll just change the month count if (!Subscribers.ContainsKey(subscriberUserName)) { newSubscriber = new User() { UserName = subscriberUserName, SubscribeDateTime = DateTime.Now, MonthsSubscribed = monthsSubscribed }; Subscribers.Add(subscriberUserName, newSubscriber); } else { // So it's a repeat subscriber. Honestly this shouldn't ever happen, because they'd have to run the game for a whole // month before this is relevant if (Subscribers.TryGetValue(subscriberUserName, out newSubscriber)) { newSubscriber.MonthsSubscribed = monthsSubscribed; } } } if (NewSubscriber != null) { NewSubscriber(this, new NewSubscriberEventArgs(newSubscriber)); } } } // If there's someone to send it to, pretty it up and send it out if (ChatMessageReceived != null) { User targetTwitchUser; // The user won't always be here. If someone immediately joins and says "Hey guys!", they probably won't actually be in here. // Twitch queues all the joins and sends them out every 10 seconds, so my program might not have gotten the memo yet lock (LoggedInUsers) { if (!LoggedInUsers.TryGetValue(userName, out targetTwitchUser)) { targetTwitchUser = new User() { UserName = userName }; LoggedInUsers.Add(targetTwitchUser.UserName, targetTwitchUser); } } IrcMessage ircMessage = new IrcMessage(targetTwitchUser, UserName, _channel, message); ChatMessageReceived(this, new ChatMessageReceivedEventArgs(ircMessage)); } break; } }
public bool HasSubscribed(Guid id) { return(Subscribers.ContainsKey(id)); }