/// <summary> /// Request processor dequeues wait request and notify respected thread after waiting for requested time /// </summary> private void WaitRequestProcessor() { Thread.Sleep(2000); while (true) { if (waitRequestQueue.Count > 0) { WaitRequest currentRequest; waitRequestQueue.TryDequeue(out currentRequest); if (this.label1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { "Server is waiting for " + currentRequest.WaitSecond + " of client " + currentRequest.ClientName + "." }); } Thread.Sleep(currentRequest.WaitSecond * 1000); servedRequest = currentRequest; //Notify thread currentRequest.WaitRequestHandle.Set(); } } }
/// <summary> /// Register client, parse http message and wait for requested time peroid /// </summary> public void ServeRequest(TcpClient currentClient) { TcpClient tcpClientSocket = currentClient; string clientName = string.Empty; while (true) { try { if (tcpClientSocket.Connected) { //Get message from socket NetworkStream networkStream = tcpClientSocket.GetStream(); byte[] message = new byte[tcpClientSocket.ReceiveBufferSize]; networkStream.Read(message, 0, message.Length); string clientData = System.Text.Encoding.ASCII.GetString(message); string[] message1 = clientData.Split('\n'); //TcpClient sends empty message while disconnects if (message[0] == 0) { if (this.label1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); string responseMessage = "Client " + clientName + " has disconnected successfully."; this.Invoke(d, new object[] { responseMessage }); tcpClientSocket.Close(); } break; } else { JObject json = JObject.Parse(message1.Last()); clientName = json["ClientName"].ToString(); if (json["WaitRequest"] == null) { if (this.label1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); string responseMessage = "Client " + json["ClientName"] + " has registered successfully."; this.Invoke(d, new object[] { responseMessage }); SendMessage(responseMessage, networkStream); } } else { int waitSeconds = Convert.ToInt32(json["WaitRequest"]); SetTextCallback d = new SetTextCallback(SetText); if (this.label1.InvokeRequired) { this.Invoke(d, new object[] { "Client " + json["ClientName"] + " has sent request wait of " + json["WaitRequest"] + "." }); } //Enque wait request. EventWaitHandle waitRequestHandle = new AutoResetEvent(false); WaitRequest waitRequest = new WaitRequest { ClientName = json["ClientName"].ToString(), WaitSecond = waitSeconds, WaitRequestHandle = waitRequestHandle }; waitRequestQueue.Enqueue(waitRequest); //Once request processor serves request from queue it will notify respected thread by triggering event. //URL:http://www.yoda.arachsys.com/csharp/threads/waithandles.shtml if (waitRequestHandle.WaitOne()) { string waitSuccess = "Server waited for client " + clientName + " for " + servedRequest.WaitSecond + " successfully."; if (this.label1.InvokeRequired) { this.Invoke(d, new object[] { waitSuccess }); } SendMessage(waitSuccess, networkStream); } } } } else { currentClient.Close(); if (this.label1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); string responseMessage = "Client " + clientName + " has disconnected successfully."; this.Invoke(d, new object[] { responseMessage }); } break; } } catch (Exception ex) { if (this.label1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { ex.Message }); } } } }