public ClientSocket(NetworkConfig networkConfig, UpdateRunner updateRunner)
        {
            if (networkConfig == null)
            {
                throw new ArgumentNullException(nameof(networkConfig));
            }

            if (updateRunner == null)
            {
                throw new ArgumentNullException(nameof(updateRunner));
            }

            updateRunner.Add(this);

            _socket = new UdpSocket(sizeof(ulong), networkConfig);
            _socket.HandleConnect += (socketService, rs) => {
                if (rs == null)
                {
                    Logger.Warn("连接失败!");
                    Enqueue(() => {
                        Connected?.Invoke(null, null);
                    });
                    return;
                }

                var length = rs.ShiftRight <ushort>();
                var data   = rs.ShiftRight(length);
                var bytes  = new byte[data.Count];
                Buffer.BlockCopy(data.Buffer, data.Offset, bytes, 0, bytes.Length);

                var buffer = Ssui.Security.DecryptAesKey(bytes, _keys);
                var aesKey = buffer.toString();
                Logger.Debug(aesKey);

                var peer = new Peer(_socket, aesKey);

                socketService.HandleDisconnect += () => {
                    Enqueue(() => {
                        Disconnected?.Invoke(peer);
                    });
                };

                socketService.HandleRead += (readStream) => {
                    // remote
                    var remoteMessageId = readStream.ShiftRight <ulong>();
                    var newReadStream   = readStream.Clone();
                    Ssui.Security.DecryptAES(newReadStream, aesKey);
                    Enqueue(() => {
                        RpcProxy.Invoke(remoteMessageId, newReadStream, peer);
                        newReadStream.Dispose();
                    });
                };

                socketService.HandleAcknowledge += (state, readStream) => {
                    var newReadStream = readStream.Clone();

                    var localMessageId = readStream.ShiftRight <ulong>();
                    Enqueue(() => {
                        peer.Acknowledge(state, localMessageId);
                        newReadStream.Dispose();
                    });
                };
                socketService.HandleError += error => Enqueue(() => Logger.Error(error));
                socketService.HandleWrite += (isSuccess) => {
                    Enqueue(() => {
                        if (!isSuccess)
                        {
                            Logger.Warn("发送失败!");
                        }
                    });
                };

                var newRs = rs.Clone();
                Enqueue(() => {
                    peer.SetStatus(ConnectionStatus.Connected, socketService);
                    Connected?.Invoke(peer, newRs);
                    newRs.Dispose();
                });
            };
        }