/// <summary> /// Handles a connection. /// </summary> /// <param name="objConnection">The Connection.</param> private void HandleClient(object objConnection) { var localConnection = (LocalConnection)objConnection; NetworkStream networkStream = localConnection.Client.GetStream(); while (localConnection.Connected) { if (localConnection.Client.Available > 0) { //Reset idle _idleTimeout = 0; _currentIdle = 0; IBasePackage package = PackageSerializer.Deserialize(networkStream); var binaryPackage = package as BinaryPackage; if (binaryPackage != null) { //notify package listeners foreach (IPackageListener subscriber in GetPackageSubscriber(binaryPackage.OriginType)) { subscriber.OnPackageReceived(binaryPackage); } //The package is not a system package, send it to it's destination if (binaryPackage.Receiver == null) { //Send to all Clients Send(binaryPackage); } else { //Special destination Send(binaryPackage, binaryPackage.Receiver); } return; } //system package with type of pingpackage var pingPackage = package as PingPackage; if (pingPackage != null) { SetLatency(pingPackage); return; } } else { Idle(); } } //Client exited. SendNotificationPackage(NotificationMode.ClientExited, new IConnection[] { SerializableConnection.FromIConnection(localConnection) }); _connections.Remove(localConnection); IConnection[] connectionList = SerializableConnection.FromIConnection(_connections.ToArray()); SendNotificationPackage(NotificationMode.ClientList, connectionList); }
/// <summary> /// Called if a PingRequest timed out. /// </summary> private void _connectionManager_PingTimedOut(object sender, IPAddress ipAddress) { for (int i = 0; i <= _connections.Count - 1; i++) { if (Equals(_connections[i].IPAddress, ipAddress)) { //remove the connection _connections.RemoveAt(i); //notify clients SendNotificationPackage(NotificationMode.TimeOut, new IConnection[] { SerializableConnection.FromIConnection(_connections[i]) }); break; } } }
/// <summary> /// Sets the latency of a connection. /// </summary> /// <param name="pingPackage">The PingPackage.</param> private void SetLatency(PingPackage pingPackage) { DateTime timeNow = DateTime.Now; TimeSpan dif = timeNow - pingPackage.TimeStamp; LocalConnection connection = GetConnection(pingPackage.Receiver); connection.Latency = (float)dif.TotalMilliseconds; //Kick the client if the latency is to high if (!(connection.Latency > TimeOutLatency)) { return; } SendNotificationPackage(NotificationMode.TimeOut, new IConnection[] { SerializableConnection.FromIConnection(connection) }); connection.Client.Close(); _connections.Remove(connection); }
/// <summary> /// Sending a ping request every 30 seconds to all clients. /// </summary> private void PingRequestLoop() { while (IsActive) { IConnection[] connectionList = SerializableConnection.FromIConnection(_connections.ToArray()); //Send a ping request to all clients for (int i = 0; i <= _connections.Count - 1; i++) { var pingPackage = new PingPackage { Receiver = _connections[i].IPAddress }; Send(pingPackage, _connections[i].IPAddress); //add the ping request to the connection manager. _connectionManager.AddPingRequest(new UdpPingRequest(_connections[i].IPAddress, pingPackage.TimeStamp)); //Also update the client list. SendNotificationPackage(NotificationMode.ClientList, connectionList); } //Idle for 15 seconds Thread.Sleep(15000); } }
/// <summary> /// Accepts clients if available. /// </summary> private void BeginAcceptConnections() { while (IsActive) { TcpClient tcpClient = _localListener.AcceptTcpClient(); //Reset idle _idleTimeout = 0; _currentIdle = 0; var localConnection = new LocalConnection(tcpClient); _connections.Add(localConnection); //Handle connection. var pts = new ParameterizedThreadStart(HandleClient); var handleClient = new Thread(pts) { IsBackground = true }; SendNotificationPackage(NotificationMode.ClientJoined, new IConnection[] { SerializableConnection.FromIConnection(localConnection) }); IConnection[] connectionList = SerializableConnection.FromIConnection(_connections.ToArray()); SendNotificationPackage(NotificationMode.ClientList, connectionList); handleClient.Start(localConnection); } }
/// <summary> /// Sending a ping request every 30 seconds to all clients. /// </summary> private void PingRequestLoop() { while (IsActive) { IConnection[] connectionList = SerializableConnection.FromIConnection(_connections.ToArray()); //Send a ping request to all clients for (int i = 0; i <= _connections.Count - 1; i++) { var pingPackage = new PingPackage { Receiver = _connections[i].IPAddress }; NetworkStream networkStream = _connections[i].Client.GetStream(); PackageSerializer.Serialize(pingPackage, networkStream); //May not be neccessary networkStream.Flush(); //Also update the client list. SendNotificationPackage(NotificationMode.ClientList, connectionList); } //Idle for 15 seconds Thread.Sleep(15000); } }