示例#1
0
    protected void _doConnect(string strHostName, int nPort, Action <bool, Exception> callback)
    {
        if (IsConnected())
        {
            Debugger.Log("Connect failed! Can do connecting only when a connection is disconnected!!!");
            return;
        }

        __onConnect = callback;

        try
        {
            _connectionState = ConnectionState.CONNECTING;

            _hostName = strHostName;
            _port     = nPort;

            _tcpClient = new TcpClient();
            _tcpClient.BeginConnect(strHostName, nPort, _onConnectedCallback, _tcpClient);
        }
        catch (Exception e)
        {
            if (__onConnect != null)
            {
                __onConnect(false, e);
            }
        }
    }
示例#2
0
    public bool IsRPCReturn()
    {
        var ret = (msgType == MsgType.RPCReturn2Gate) || (msgType == MsgType.RPCReturn2Client);

        Debugger.ConditionalAssert(ret == true, this.RPC_ID != 0);
        return(ret);
    }
示例#3
0
    private void _onConnectedCallback(IAsyncResult pAsyncResult)
    {
        lock (__lock)
        {
            try
            {
                TcpClient pTCPClient = pAsyncResult.AsyncState as TcpClient;

                Debugger.Assert(System.Object.ReferenceEquals(pTCPClient, _tcpClient));
                pTCPClient.EndConnect(pAsyncResult);

                _tcpClient.NoDelay = true;

                _networkStream = pTCPClient.GetStream();
                Debugger.Assert(_networkStream.CanRead);

                __bIsReceiveHeader = true;
                _networkStream.BeginRead(__receiveBuffer, 0, HEAD_SIZE, _onReadCallback, 0);

                _connectionState = ConnectionState.CONNECTED;

                _InternalMsg sysMsg = new _InternalMsg(_InternalMsgType.Connected);
                __sysMsgQueue.Add(sysMsg);
            }
            catch (Exception e)
            {
                _InternalMsg errMsg = new _InternalMsg(_InternalMsgType.ConnectFailed, e);
                __sysMsgQueue.Add(errMsg);
            }
        }
    }
示例#4
0
    public void Disconnect()
    {
        if (_connectionState == ConnectionState.DISCONNECTED)
        {
            return;
        }

        __onConnect = null;

        lock (__lock)
        {
            if (_networkStream != null)
            {
                _networkStream.Close();
                _networkStream = null;
            }

            Debugger.Assert(_tcpClient != null);
            _tcpClient.Close();
            _tcpClient = null;

            __nBytesReceived   = 0;
            __bIsReceiveHeader = true;

            __sendMsgQueue.Clear();
            __sysMsgQueue.Clear();
            __rawMsgQueue.Clear();

            _rpcCallMap.Clear();

            _connectionState  = ConnectionState.DISCONNECTED;
            __fCurrentSeconds = 0;
        }
    }
示例#5
0
    public bool IsRPCCall()
    {
        var ret = (msgType == MsgType.RPCCall);

        Debugger.ConditionalAssert(ret == true, this.msgID != 0);
        return(ret);
    }
示例#6
0
        public void SendNetMessage(NetMessage message)
        {
            if (!IsConnected())
            {
                Debugger.Log("Connection already down, send message failed!"); return;
            }

            try
            {
                if (SendingFilter != null)
                {
                    if (SendingFilter(message))
                    {
                        ByteBuffer buffer = message.Serialize();
                        _socket.Send(buffer.GetInternalBuffer());
                    }
                    else
                    {
                        if (OnSendingFiltered != null)
                        {
                            OnSendingFiltered(message);
                        }
                    }
                }
                else
                {
                    ByteBuffer buffer = message.Serialize();
                    _socket.Send(buffer.GetInternalBuffer());
                }
            }
            catch (Exception e) { Debugger.LogError(e); }
        }
示例#7
0
    ///------------
    private void _sendMessage(Message pMessage)
    {
        Debugger.Assert(IsConnected(), "_sendMessage failed, connection already down!");

        try
        {
            byte[] rawBuffer;
            int    nLength;

            if (pMessage.IsRPCCall())
            {
                _rpcIndex                  = (ushort)(1 + ((_rpcIndex + 1) % (ushort.MaxValue - 1)));
                pMessage.RPC_ID            = _rpcIndex;
                pMessage._RPCCallStartTime = __fCurrentSeconds;
            }

            pMessage.Serialize(out rawBuffer, out nLength);

            if (OnSendingFilter != null)
            {
                if (!OnSendingFilter(pMessage))
                {
                    if (pMessage._Callback != null)
                    {
                        pMessage._Callback(Message.REJECTED_BY_SENDING_FILTER);
                    }
                }
                else
                {
                    if (pMessage.IsRPCCall())
                    {
                        Debugger.Assert(!_rpcCallMap.ContainsKey(pMessage.RPC_ID));
                        _rpcCallMap.Add(_rpcIndex, pMessage);
                        pMessage._RPCCallStartTime = __fCurrentSeconds;
                    }

                    _networkStream.BeginWrite(rawBuffer, 0, nLength, _onWriteCallback, pMessage);
                }
            }
            else
            {
                if (pMessage.IsRPCCall())
                {
                    Debugger.Assert(!_rpcCallMap.ContainsKey(pMessage.RPC_ID));
                    _rpcCallMap.Add(_rpcIndex, pMessage);
                    pMessage._RPCCallStartTime = __fCurrentSeconds;
                }

                _networkStream.BeginWrite(rawBuffer, 0, nLength, _onWriteCallback, pMessage);
            }
        }
        catch (Exception e)
        {
            _onConnectError(e);
        }
    }
示例#8
0
    public bool IsConnected()
    {
#if UNITY_EDITOR
        if (_connectionState == ConnectionState.CONNECTED || _connectionState == ConnectionState.VALIDATED)
        {
            Debugger.Assert(_tcpClient != null && _tcpClient.Connected);
        }
#endif
        return(_connectionState == ConnectionState.CONNECTED || _connectionState == ConnectionState.VALIDATED);
    }
示例#9
0
    public void RemoveTail(int count)
    {
        Debugger.Assert(count >= 0 && count <= this.Count);

        for (int i = this.Count - count; i < this.Count; ++i)
        {
            _Buffer[i] = default(T);
        }

        this.Count -= count;
    }
示例#10
0
    public void SendNotify(Message pMessage)
    {
        if (!IsConnected())
        {
            Debugger.Log("Connection already down, send message failed!"); return;
        }

        lock (__lock)
        {
            __sendMsgQueue.Enqueue(pMessage);
        }
    }
示例#11
0
 public T this[int i]
 {
     get
     {
         Debugger.Assert(i < Count);
         return(_Buffer[i]);
     }
     set
     {
         Debugger.Assert(i < Count);
         _Buffer[i] = value;
     }
 }
示例#12
0
        ///------------------
        protected void _doConnect(string strHostName, int nPort, Action <bool, Exception> callback)
        {
            if (IsConnected())
            {
                Debugger.Log("Connect failed! Can do connecting only when a connection is disconnected!!!");
                return;
            }

            __onConnect = callback;

            _socket.Connect(strHostName, nPort, (ret, err) =>
            {
                _connectionState = ret ? ConnectionState.CONNECTED : ConnectionState.DISCONNECTED;
                callback(ret, err);
            });
        }
示例#13
0
    public void Reserve(int nCount)
    {
        Debugger.Assert(nCount > Count, "Reserve failed, reserved count must large than current count");

        T[] newList;
        if (_Buffer == null)
        {
            newList = new T[nCount];
        }
        else
        {
            newList = new T[nCount];
            if (Count > 0)
            {
                _Buffer.CopyTo(newList, 0);
            }
        }

        _Buffer = newList;
    }
示例#14
0
        ///------------
        protected void _onData(byte[] data)
        {
            try
            {
                ByteBuffer buffer = new ByteBuffer(data);

                NetMessage netMessage = null;
                /// Read the headerType first to determine which message class to use
                buffer.position = NetMessage.LEN_SIZE;
                short headerType = buffer.FReadByte();
                buffer.position = 0;

                if (HeaderType.RPCCall == headerType)
                {
                    netMessage = new NetRPCCall();
                }
                else if (HeaderType.RPCReturn == headerType)
                {
                    netMessage = new _NetRPCReturn();
                }
                else if (HeaderType.Notify == headerType)
                {
                    netMessage = new NetNotify();
                }
                else
                {
                    throw NetMessage.INVALID_HEADER_TYPE;
                }

                netMessage.Deserialize(buffer);

                bool needFurtherProcess = true;
                if (NetMessageFilter != null)
                {
                    needFurtherProcess = NetMessageFilter(netMessage);
                }

                if (needFurtherProcess)
                {
                    if (HeaderType.RPCCall == headerType)
                    {
                        Debugger.Assert(false, "Has not implement!");
                    }
                    else if (HeaderType.RPCReturn == headerType)
                    {
                        _netRPCComponent._OnRPCReturn(netMessage as _NetRPCReturn);
                    }
                    else if (HeaderType.Notify == headerType)
                    {
                        int handlerCount = _messageDispatcher.DispatchEvent(netMessage);

                        if (0 == handlerCount)
                        {
                            Debugger.LogWarning("No message handler for message type: " + netMessage.type);
                        }
                    }
                    else
                    {
                        Debugger.Assert(false);
                    }
                }
            }
            catch (Exception e)
            {
                _onFatalError(e);
            }
        }
示例#15
0
    public void Serialize(out byte[] rawBytes, out int length)
    {
        Debugger.Assert(type != 0);

        if (body == null)
        {
            if (_body == null)
            {
                body = "{}";
            }
            else
            {
                body = JsonWriter.Serialize(_body);
            }
        }

        bool bHasRPC_ID        = false;
        bool bHasMsgID         = false;
        bool bHasDestOrSrcType = false;
        bool bHasDestOrSrcID   = false;

        length = LEN_SIZE + MSG_TYPE_SIZE;

        if ((msgType & MsgType._HAS_MSG_ID) != 0)
        {
            bHasMsgID = true;
            length   += MSG_ID_SIZE;
        }

        if ((msgType & MsgType._HAS_RPC_ID) != 0)
        {
            bHasRPC_ID = true;
            length    += RPC_ID_SIZE;
        }

        if ((msgType & MsgType._HAS_DEST_OR_SRC_TYPE) != 0)
        {
            bHasDestOrSrcType = true;
            length           += DEST_OR_SRC_TYPE_SIZE;
        }

        if ((msgType & MsgType._HAS_DEST_OR_SRC_ID) != 0)
        {
            bHasDestOrSrcID = true;
            length         += DEST_OR_SRC_ID_SIZE;
        }

        Debugger.Assert(body.Length <= ushort.MaxValue - length);
        length += body.Length;

        ///... Use buffer pool later!!!!
        this.len = (ushort)length;
        ByteBuffer byteBuffer = new ByteBuffer(length);

        byteBuffer.WriteUShort((ushort)length);
        byteBuffer.WriteByte(msgType);

        if (bHasMsgID)
        {
            byteBuffer.WriteUShort(msgID);
        }
        if (bHasRPC_ID)
        {
            byteBuffer.WriteUShort(RPC_ID);
        }
        if (bHasDestOrSrcType)
        {
            byteBuffer.WriteByte(destOrSrcType);
        }
        if (bHasDestOrSrcID)
        {
            byteBuffer.WriteInt(destOrSrcID);
        }

        byteBuffer.WriteString(body);

        rawBytes = byteBuffer.GetInternalBuffer();
    }
示例#16
0
 public string GetString(string key)
 {
     Debugger.Assert(_body.ContainsKey(key));
     return((string)_body[key]);
 }
示例#17
0
 public int GetInt(string key)
 {
     Debugger.Assert(_body.ContainsKey(key));
     return((int)_body[key]);
 }
示例#18
0
 public bool GetBool(string key)
 {
     Debugger.Assert(_body.ContainsKey(key));
     return((bool)_body[key]);
 }
示例#19
0
 public void SetValue(string key, object value)
 {
     Debugger.Assert(_body != null);
     _body[key] = value;
 }
示例#20
0
    private void _onReadCallback(IAsyncResult pAsyncResult)
    {
        lock (__lock)
        {
            if (this.IsDisconnected())
            {
                return;
            }

            try
            {
                int numberOfBytesRead = _networkStream.EndRead(pAsyncResult);
                if (numberOfBytesRead == 0)
                {
                    _onConnectError(new Exception("Disconnected by server!"));
                    return;
                }

                __nBytesReceived += numberOfBytesRead;

                var pendingBytes = __bIsReceiveHeader ? HEAD_SIZE : __nMsgLength - HEAD_SIZE;

                if (__nBytesReceived == pendingBytes)
                {
                    Debugger.Assert(__nBytesReceived <= pendingBytes);

                    if (__bIsReceiveHeader)
                    {
                        __bIsReceiveHeader = false;

                        /// Read body size ( Convert first two bytes to ushort)
                        __nMsgLength = (ushort)((__receiveBuffer[1] & 0xff) | (__receiveBuffer[0] << 8));
                        Debugger.Assert(__nMsgLength <= RECEIVE_BUFFER_SIZE);

                        var offset = __nBytesReceived;
                        __nBytesReceived = 0;
                        /// Ready body data
                        _networkStream.BeginRead(__receiveBuffer, offset, __nMsgLength - HEAD_SIZE, _onReadCallback, 0);
                    }
                    else
                    {
                        byte[] rawMsg = new byte[__nMsgLength];
                        Buffer.BlockCopy(__receiveBuffer, 0, rawMsg, 0, __nMsgLength);

                        __rawMsgQueue.Add(rawMsg);

                        /// Continue reading next message
                        __bIsReceiveHeader = true;
                        __nBytesReceived   = 0;
                        __nMsgLength       = 0;
                        _networkStream.BeginRead(__receiveBuffer, 0, HEAD_SIZE, _onReadCallback, 0);
                    }
                }
                else if (__nBytesReceived < pendingBytes)
                {
                    /// Continue reading remaining bytes
                    _networkStream.BeginRead(__receiveBuffer, __nBytesReceived, pendingBytes - __nBytesReceived, _onReadCallback, 0);
                }
                else
                {
                    Debugger.Assert(false, "Should never run into here!");
                }
            }
            catch (Exception e) { _onConnectError(e); }
        }
    }
示例#21
0
    // Update is called once per frame
    public void Update(float curTimeInSeconds)
    {
        __fCurrentSeconds = curTimeInSeconds;

        lock (__lock)
        {
            /// Processing receiving queue
            foreach (Byte[] rawMsgBytes in __rawMsgQueue)
            {
                bool bNeedDispatch;

                if (OnReceivingFilter != null)
                {
                    bNeedDispatch = OnReceivingFilter(rawMsgBytes, rawMsgBytes.Length);
                }
                else
                {
                    bNeedDispatch = true;
                }

                if (bNeedDispatch)
                {
                    Message message = new Message();
                    message.Deserialize(rawMsgBytes, rawMsgBytes.Length);

                    if (message.IsRPCReturn())
                    {
                        if (_rpcCallMap.ContainsKey(message.RPC_ID))
                        {
                            var rpcCallMsg = _rpcCallMap[message.RPC_ID];
                            _rpcCallMap.Remove(message.RPC_ID);
                            if (rpcCallMsg._Callback != null)
                            {
                                rpcCallMsg._Callback(message);
                            }
                        }
                        else
                        {
                            Debugger.Log("Invalid RPC_ID: " + message.RPC_ID);
                        }
                    }
                    else if (message.IsRPCCall())
                    {
                        Debugger.Assert(false, "Not supported now!");
                    }
                    else
                    {
                        DispatchEvent(message);
                    }

                    if (OnReceived != null)
                    {
                        OnReceived(message);
                    }
                }
            }

            __rawMsgQueue.Clear();

            /// Process error msg queue
            ///... _InternalMsgType.Disconnected has bug: Disconnect() method will clear the __sysMsgQueue, which will
            /// break current iteration.
            foreach (_InternalMsg errMsg in __sysMsgQueue)
            {
                switch (errMsg.type)
                {
                case _InternalMsgType.Connected:
                    if (__onConnect != null)
                    {
                        __onConnect(true, null);
                    }
                    __onConnect = null;
                    break;

                case _InternalMsgType.ConnectFailed:
                    if (__onConnect != null)
                    {
                        __onConnect(false, errMsg.exception);
                    }
                    __onConnect = null;
                    break;

                case _InternalMsgType.Disconnected:
                    Disconnect();
                    if (OnDisconnected != null)
                    {
                        OnDisconnected(errMsg.exception);
                    }
                    break;
                }
            }

            __sysMsgQueue.Clear();

            /// Process sending queue
            if (__sendMsgQueue.Count != 0 &&
                (_connectionState == ConnectionState.CONNECTED || _connectionState == ConnectionState.VALIDATED))
            {
                Message pMessage = __sendMsgQueue.Dequeue();
                _sendMessage(pMessage);
            }

            /// Checking RPC timeout
            foreach (var msg in _rpcCallMap.Values)
            {
                if (__fCurrentSeconds - msg._RPCCallStartTime > 6.0f)
                {
                    if (OnTimeout != null)
                    {
                        OnTimeout(TimeoutType.RPCCall, msg.msgID);
                    }
                    msg._RPCCallStartTime = __fCurrentSeconds;
                }
            }
        }
    }