/// <summary> /// Processes the send queue /// </summary> /// <param name="ObjectCache"></param> public void ProcessSendQueue() { sendingThreads++; while (SendQueue.Count > 0) { Hash sendHash; SendQueue.TryDequeue(out sendHash); IPeerTransport transport = GetTransport(); CacheItem sendItem = sendCache.Get(sendHash); if (sendItem == null) { logger.Warn("A peer send item expired, it will not be resent"); } else { if (transport.TryPut(sendItem)) { //successful send, remove cached item sendCache.Remove(sendItem.Key); } sendCache.Expire(DateTime.Now - ConnectTimeOut, true); } } sendingThreads--; }
private void NetworkWorker() { while (true) { if (IsSpawned && nextPlayerUpdate < DateTime.Now) { nextPlayerUpdate = DateTime.Now.AddMilliseconds(500); SendPacket(new PlayerPacket(true)); // TODO: Store OnGround properly } // Send queued packets while (SendQueue.Count != 0) { IPacket packet; if (SendQueue.TryDequeue(out packet)) { try { // Write packet packet.WritePacket(Stream); #if DEBUG LogProvider.Log(packet, true); #endif Stream.Flush(); if (packet is DisconnectPacket) { return; } } catch { /* TODO */ } } } // Read incoming packets var readTimeout = DateTime.Now.AddMilliseconds(20); // Maximum read time given to server per iteration while (NetworkStream.DataAvailable && DateTime.Now < readTimeout) { try { var packet = PacketReader.ReadPacket(Stream); #if DEBUG LogProvider.Log(packet, false); #endif HandlePacket(packet); if (packet is DisconnectPacket) { return; } } catch { /* TODO */ } } Thread.Sleep(1); } }
/// <summary> /// The internal thread procedure, handling recv and send. /// </summary> protected void ThreadProc() { // cleanup old socket if any if (socket != null) { socket.Close(); socket = null; } // reset the packetcontroller messageController.Reset(); // clean pending messages/exceptions from queues GameMessage message; Exception error; while (SendQueue.TryDequeue(out message)) { ; } while (ReceiveQueue.TryDequeue(out message)) { ; } while (ExceptionQueue.TryDequeue(out error)) { ; } // init a new Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // try connect to server try { socket.Connect(serverAddress, serverPort); } catch (Exception Error) { ExceptionQueue.Enqueue(Error); } // don't go on if no connection if (socket.Connected) { // initialize the socket stream tcpStream = new NetworkStream(socket); // mark running isRunning = true; // start thread loop // this can be broken by calling Disconnect() while (isRunning) { try { bool doSend = false; // processing pending messages to send while (SendQueue.TryDequeue(out message)) { Send(message, false); doSend = true; } // call flush ourself here // so we can send multiple messages above if (doSend) { Flush(); } // read if (socket.Available > 0) { messageController.ReadRecv(tcpStream, socket.Available); } // avoid 100% cpu usage Thread.Sleep(SLEEPTIME); } catch (Exception Error) { // log the exception ExceptionQueue.Enqueue(Error); // stop thread isRunning = false; } } } // cleanup if (socket != null) { socket.Close(); } // reset references socket = null; tcpStream = null; workThread = null; }