private void CloseConnection(HttpResponseSender clientContext)
        {
            using (EneterTrace.Entering())
            {
                if (!clientContext.IsDisposed)
                {
                    try
                    {
                        // Send close connection message.
                        object anEncodedMessage = myProtocolFormatter.EncodeCloseConnectionMessage(clientContext.ResponseReceiverId);
                        clientContext.SendResponseMessage(anEncodedMessage);
                    }
                    catch (Exception err)
                    {
                        EneterTrace.Warning("failed to send the close message.", err);
                    }

                    // Note: the client context will be removed by the timer.
                    //       The reason is the client can still poll for messages which are stored in the HttpResponseSender.
                    clientContext.Dispose();
                }
            }
        }
        private void HandleConnection(HttpListenerContext httpRequestContext)
        {
            using (EneterTrace.Entering())
            {
                // If polling. (when client polls to get response messages)
                if (httpRequestContext.Request.HttpMethod.ToUpperInvariant() == "GET")
                {
                    // Get responseReceiverId.
                    string[] aQueryItems = httpRequestContext.Request.Url.Query.Split('&');
                    if (aQueryItems.Length > 0)
                    {
                        string aResponseReceiverId = aQueryItems[0].Substring(4);

                        // Find the client.
                        HttpResponseSender aClientContext;
                        using (ThreadLock.Lock(myConnectedClients))
                        {
                            aClientContext = myConnectedClients.FirstOrDefault(x => x.ResponseReceiverId == aResponseReceiverId);
                        }

                        if (aClientContext != null)
                        {
                            // Response collected messages.
                            byte[] aMessages = aClientContext.DequeueCollectedMessages();
                            if (aMessages != null)
                            {
                                httpRequestContext.SendResponseMessage(aMessages);
                            }
                        }
                        else
                        {
                            // Note: This happens when the polling runs and the connection is not open yet.
                            //       It is a normal situation because the polling thread on the client starts
                            //       slightly before the connection is open.
                        }
                    }
                    else
                    {
                        EneterTrace.Warning("Incorrect query format detected for HTTP GET request.");

                        // The request was not processed.
                        httpRequestContext.Response.StatusCode = 404;
                    }
                }
                else
                // Client sends a request message.
                {
                    byte[] aMessage = httpRequestContext.GetRequestMessage();

                    IPEndPoint anEndPoint = httpRequestContext.Request.RemoteEndPoint;
                    string     aClientIp  = (anEndPoint != null) ? anEndPoint.Address.ToString() : "";

                    ProtocolMessage aProtocolMessage = myProtocolFormatter.DecodeMessage(aMessage);

                    bool anIsProcessingOk = true;
                    if (aProtocolMessage != null && !string.IsNullOrEmpty(aProtocolMessage.ResponseReceiverId))
                    {
                        MessageContext aMessageContext = new MessageContext(aProtocolMessage, aClientIp);

                        if (aProtocolMessage.MessageType == EProtocolMessageType.OpenConnectionRequest)
                        {
                            using (ThreadLock.Lock(myConnectedClients))
                            {
                                HttpResponseSender aClientContext = myConnectedClients.FirstOrDefault(x => x.ResponseReceiverId == aProtocolMessage.ResponseReceiverId);
                                if (aClientContext != null && aClientContext.IsDisposed)
                                {
                                    // The client with the same id exists but was closed and disposed.
                                    // It is just that the timer did not remove it. So delete it now.
                                    myConnectedClients.Remove(aClientContext);

                                    // Indicate the new client context shall be created.
                                    aClientContext = null;
                                }

                                if (aClientContext == null)
                                {
                                    aClientContext = new HttpResponseSender(aProtocolMessage.ResponseReceiverId, aClientIp);
                                    myConnectedClients.Add(aClientContext);

                                    // If this is the only sender then start the timer measuring the inactivity to detect if the client is disconnected.
                                    // If it is not the only sender, then the timer is already running.
                                    if (myConnectedClients.Count == 1)
                                    {
                                        myResponseReceiverInactivityTimer.Change(myResponseReceiverInactivityTimeout, -1);
                                    }
                                }
                                else
                                {
                                    EneterTrace.Warning(TracedObject + "could not open connection for client '" + aProtocolMessage.ResponseReceiverId + "' because the client with same id is already connected.");
                                    anIsProcessingOk = false;
                                }
                            }
                        }
                        else if (aProtocolMessage.MessageType == EProtocolMessageType.CloseConnectionRequest)
                        {
                            using (ThreadLock.Lock(myConnectedClients))
                            {
                                HttpResponseSender aClientContext = myConnectedClients.FirstOrDefault(x => x.ResponseReceiverId == aProtocolMessage.ResponseReceiverId);

                                if (aClientContext != null)
                                {
                                    // Note: the disconnection comes from the client.
                                    //       It means the client closed the connection and will not poll anymore.
                                    //       Therefore the client context can be removed.
                                    myConnectedClients.Remove(aClientContext);
                                    aClientContext.Dispose();
                                }
                            }
                        }

                        if (anIsProcessingOk)
                        {
                            NotifyMessageContext(aMessageContext);
                        }
                    }

                    if (!anIsProcessingOk)
                    {
                        // The request was not processed.
                        httpRequestContext.Response.StatusCode = 404;
                    }
                }
            }
        }