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); } } }
public bool IsRPCReturn() { var ret = (msgType == MsgType.RPCReturn2Gate) || (msgType == MsgType.RPCReturn2Client); Debugger.ConditionalAssert(ret == true, this.RPC_ID != 0); return(ret); }
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); } } }
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; } }
public bool IsRPCCall() { var ret = (msgType == MsgType.RPCCall); Debugger.ConditionalAssert(ret == true, this.msgID != 0); return(ret); }
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); } }
///------------ 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); } }
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); }
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; }
public void SendNotify(Message pMessage) { if (!IsConnected()) { Debugger.Log("Connection already down, send message failed!"); return; } lock (__lock) { __sendMsgQueue.Enqueue(pMessage); } }
public T this[int i] { get { Debugger.Assert(i < Count); return(_Buffer[i]); } set { Debugger.Assert(i < Count); _Buffer[i] = value; } }
///------------------ 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); }); }
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; }
///------------ 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); } }
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(); }
public string GetString(string key) { Debugger.Assert(_body.ContainsKey(key)); return((string)_body[key]); }
public int GetInt(string key) { Debugger.Assert(_body.ContainsKey(key)); return((int)_body[key]); }
public bool GetBool(string key) { Debugger.Assert(_body.ContainsKey(key)); return((bool)_body[key]); }
public void SetValue(string key, object value) { Debugger.Assert(_body != null); _body[key] = value; }
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); } } }
// 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; } } } }