protected void OnPingMessage(TCPMessage message) { using (IOStream stream = new IOStream(message.Content)) { double rtt = 0; bool error = stream.ReadDouble(out rtt); string dateStr = null; error = stream.ReadString(out dateStr); RTT = rtt; try { if (error) { return; } DateTime sent = DateTime.Parse(dateStr, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); Send(new TCPMessage() { Code = TCPMessageCode.Pong, Content = Encoding.UTF8.GetBytes(sent.ToString("O")) }); } catch (Exception er) { Console.WriteLine("Error"); } } }
/// <summary> /// Listen for incomming messages /// </summary> protected void Listen() { using (Stream = GetStream()) { Writer = new TCPWriter(Stream); Reader = new TCPReader(Stream); if (Logging) { Logger.Write("SUCCESS", "Connected to the server"); } OnConnected?.Invoke(); if (RequireHandshake) { byte[] rand = new byte[10]; RandomGen.Random.NextBytes(rand); TCPMessage init = new TCPMessage() { Code = TCPMessageCode.Init, Content = rand }; if (Logging) { Logger.Write("INFO", "Sending handshake"); } Send(init); } while (Running) { TCPMessage message = Reader.Read(Socket); if (message == null) { Running = false; OnDisconnected?.Invoke(); continue; } if (message.Code == TCPMessageCode.Init) { if (Logging) { Logger.Write("SUCCESS", "Successful handshake"); } OnHandshake?.Invoke(); } else if (message.Code == TCPMessageCode.Message) { OnMessage?.Invoke(message); } } } }
/// <summary> /// Handle pong and rtt /// </summary> /// <param name="message"></param> protected void HandlePong(TCPMessage message) { try { string strDate = Encoding.UTF8.GetString(message.Content); DateTime time = DateTime.Parse(strDate, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); message.Client.RTT = ((DateTime.UtcNow.Ticks - time.Ticks) / 10000); } catch (Exception er) { if (Logging) { Logger.Write("FAILED", "Socket RTT failed", er); } } }
/// <summary> /// Sends message to the client /// </summary> /// <param name="message"></param> public void Send(TCPMessage message) { Writer.Write(message); }
/// <summary> /// Write message to stream /// </summary> /// <param name="message"></param> public void Write(TCPMessage message) { Write(message.Code, message.Content); }
/// <summary> /// Listen for new messages of individual clients /// </summary> /// <param name="client"></param> protected void ListenClient(TCPServerClient client) { if (Logging) { Logger.Write("REGION", "Method [ListenClient]"); } using (Stream ns = GetStream(client)) { client.Stream = ns; client.Writer = new TCPWriter(ns); client.Reader = new TCPReader(ns); if (Logging) { Logger.Write("INFO", "Created stream, writer and reader for client: " + client.UID); } lock (ClientsList) ClientsList.Add(client); lock (ClientsDict) ClientsDict.Add(client.UID, client); OnConnected?.Invoke(client); if (RequireHandshake) { TCPMessage message = client.Reader.Read(client); if (message.Code != TCPMessageCode.Init || message.Content.Length > 10) { RemoveClient(client, TCPDisconnectType.NoHandshake); return; } if (Logging) { Logger.Write("SUCCESS", "Handshake: " + client.UID); } client.DoneHandshake = true; client.Send(new TCPMessage() { Code = TCPMessageCode.Init, Content = new byte[] { 0, 1, 0 } }); } while (Running && ClientsDict.ContainsKey(client.UID)) { TCPMessage message = client.Reader.Read(client); if (message == null) { RemoveClient(client, TCPDisconnectType.Timeout); return; } if (Logging) { Logger.Write("INFO", "New message " + Enum.GetName(typeof(TCPMessageCode), message.Code) + " from user: " + client.UID); } if (message.Code == TCPMessageCode.Message) { OnMessage?.Invoke(client, message); } } } }