private void _server_MessageReceived(object sender, TcpRawMessageReceivedEventArgs args)
        {
            if (!IsRunning)
            {
                return;
            }
            long proxyClientID = args.Message.ClientID;

            if (!_clientDict.ContainsKey(proxyClientID))
            {
                //If remote connection is not ready, we have to wait until connection completed
                _waitConnDict.TryRemove(proxyClientID, out ManualResetEvent temp);
                ManualResetEvent waitEvent = new ManualResetEvent(false);
                _waitConnDict.TryAdd(proxyClientID, waitEvent);
                for (int i = 0; i < 300; i++)
                {
                    if (!IsRunning)
                    {
                        return;
                    }
                    if (_clientDict.ContainsKey(proxyClientID))
                    {
                        _waitConnDict.TryRemove(proxyClientID, out ManualResetEvent temp2);
                        break;
                    }
                    else
                    {
                        if (waitEvent.WaitOne(10))
                        {
                            break;
                        }
                    }
                }
            }

            if (_clientDict.ContainsKey(proxyClientID))
            {
                if (DataFilter != null)
                {
                    DataFilter.BeforeClientToServer(args.Message);
                }
                try
                {
                    //the method may throw exception when stopping, so try catch is used but do nothing.
                    _clientDict[proxyClientID].SendMessage(args.Message.MessageRawData.ToArray());
                }
                catch { }
            }
        }