private void SendSpecificPacket <T>(ChatPacketModel packet, EventHandler <T> eventHandler) { if (packet.data != null) { eventHandler?.Invoke(this, packet.data.ToObject <T>()); } }
/// <summary> /// Processes a received text packet. /// </summary> /// <param name="packet">The text packet received</param> /// <returns>An awaitable Task</returns> protected override Task ProcessReceivedPacket(string packet) { Logger.Log(LogLevel.Debug, "Trovo Chat Packet: " + packet); ChatPacketModel response = JSONSerializerHelper.DeserializeFromString <ChatPacketModel>(packet); if (response != null && !string.IsNullOrEmpty(response.type)) { switch (response.type) { case "RESPONSE": if (this.replyIDListeners.ContainsKey(response.nonce)) { this.replyIDListeners[response.nonce] = response; } break; case "CHAT": this.SendSpecificPacket(response, this.OnChatMessageReceived); break; } } return(Task.FromResult(0)); }
private async Task BackgroundPing(CancellationToken token) { while (!token.IsCancellationRequested) { int delay = 30; try { ChatPacketModel reply = await this.Ping(); if (reply != null && reply.data != null && reply.data.ContainsKey("gap")) { int.TryParse(reply.data["gap"].ToString(), out delay); } await Task.Delay(delay * 1000); } catch (ThreadAbortException) { return; } catch (OperationCanceledException) { return; } catch (Exception ex) { Logger.Log(ex); } } }
/// <summary> /// Sends a packet to the server and listens for a reply. /// </summary> /// <param name="packet">The packet to send</param> /// <returns>The reply packet</returns> protected async Task <ChatPacketModel> SendAndListen(ChatPacketModel packet) { ChatPacketModel replyPacket = null; this.replyIDListeners[packet.nonce] = null; await this.Send(packet); await this.WaitForSuccess(() => { if (this.replyIDListeners.ContainsKey(packet.nonce) && this.replyIDListeners[packet.nonce] != null) { replyPacket = this.replyIDListeners[packet.nonce]; return(true); } return(false); }, secondsToWait : 5); this.replyIDListeners.Remove(packet.nonce); return(replyPacket); }
/// <summary> /// Connects the client to the specified channel. /// </summary> /// <param name="token">The connection token to the channel</param> /// <returns>Whether the connection was successful</returns> public new async Task <bool> Connect(string token) { Validator.ValidateString(token, "token"); if (await base.Connect(TrovoChatConnectionURL)) { ChatPacketModel authReply = await this.SendAndListen(new ChatPacketModel("AUTH", new JObject() { { "token", token } })); if (authReply != null && string.IsNullOrEmpty(authReply.error)) { this.backgroundPingCancellationTokenSource = new CancellationTokenSource(); #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed Task.Run(() => this.BackgroundPing(this.backgroundPingCancellationTokenSource.Token), this.backgroundPingCancellationTokenSource.Token); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed return(true); } } return(false); }
private void OnMessage(object sender, MessageEventArgs e) { PacketModel packet = PacketModel.ReadData(e.Data); if (string.IsNullOrEmpty(packet.Message)) { return; } if (packet.Type == "Chat") { ChatPacketModel chat = packet as ChatPacketModel; _outputFunction($"[CHAT] | {chat.Username} [{chat.UserID}]: {chat.ChatMessage}"); return; } if (packet.Type == "Generic") { _outputFunction(packet.Message); return; } _outputFunction($"Error! Uncaught packet type: {packet.Type}"); }
/// <summary> /// Sends the specified packet. /// </summary> /// <param name="packet">The packet to send</param> /// <returns>An awaitable Task</returns> protected async Task Send(ChatPacketModel packet) { await this.Send(JSONSerializerHelper.SerializeToString(packet)); }