/// <summary> /// Attempts to connects to the server. /// </summary> /// <param name="host">The server address.</param> /// <param name="port">The server port.</param> /// <param name="approvalMessage">The initial message to send to the server when making the connection. This can /// be utilized by the server to provide additional information for determining whether or not to accept the connection. /// Or, can be null to send nothing.</param> /// <returns> /// True if the connection attempt was successfully started. Does not mean that the connection was established, but /// just that it can be attempted. Will return false if a connection is already established or being established. /// </returns> public bool Connect(string host, int port, BitStream approvalMessage = null) { if (_local.ConnectionsCount > 0) { return(false); } NetConnection conn; if (approvalMessage != null && approvalMessage.LengthBits > 0) { // Connect with approval message var netOutMsg = SocketHelper.GetNetOutgoingMessage(_local, approvalMessage.LengthBytes); approvalMessage.CopyTo(netOutMsg); conn = _local.Connect(host, port, netOutMsg); } else { // Connect without approval message conn = _local.Connect(host, port); } // Check if connection successful if (conn == null) { Debug.Fail("conn is null. Why?"); return(false); } // Store the remote connection as an IPSocket _remote = IPSocket.Create(conn); return(true); }
/// <summary> /// Handles processing of the underlying connection(s) and promoting data to the upper layer to be handled /// by the application. Should be called once per frame. /// </summary> public void Heartbeat() { const string debugMsgFormat = "Debug message from `{0}` on `{1}`: {2}"; NetIncomingMessage incMsg; while ((incMsg = _local.ReadMessage()) != null) { IIPSocket ipSocket; switch (incMsg.MessageType) { case NetIncomingMessageType.DebugMessage: case NetIncomingMessageType.VerboseDebugMessage: if (log.IsDebugEnabled) { var debugMsg = incMsg.ReadString(); log.DebugFormat(debugMsgFormat, incMsg.SenderConnection, this, debugMsg); } break; case NetIncomingMessageType.WarningMessage: if (log.IsWarnEnabled) { var debugMsg = incMsg.ReadString(); log.WarnFormat(debugMsgFormat, incMsg.SenderConnection, this, debugMsg); } break; case NetIncomingMessageType.ErrorMessage: if (log.IsErrorEnabled) { var debugMsg = incMsg.ReadString(); log.ErrorFormat(debugMsgFormat, incMsg.SenderConnection, this, debugMsg); } break; case NetIncomingMessageType.ConnectionApproval: // Make sure that the IIPSocket has been created ipSocket = IPSocket.Create(incMsg.SenderConnection); Debug.Assert(ipSocket != null); // Copy the received data into a BitStream before passing it up _receiveBitStream.Reset(); _receiveBitStream.Write(incMsg); _receiveBitStream.PositionBits = 0; // Ask the acception handler method if this connection will be accepted var rejectMessage = AcceptConnect(ipSocket.IP, ipSocket.Port, _receiveBitStream); if (log.IsDebugEnabled) { log.DebugFormat("Received connection request from `{0}`. Accepted? {1}.", ipSocket, string.IsNullOrEmpty(rejectMessage)); } // Approve or deny the connection accordingly if (string.IsNullOrEmpty(rejectMessage)) { incMsg.SenderConnection.Approve(); } else { incMsg.SenderConnection.Deny(rejectMessage); } break; case NetIncomingMessageType.StatusChanged: // Make sure that the IIPSocket has been created ipSocket = IPSocket.Create(incMsg.SenderConnection); Debug.Assert(ipSocket != null); // Read the status and reason var status = (NetConnectionStatus)incMsg.ReadByte(); var reason = incMsg.ReadString(); if (log.IsDebugEnabled) { log.DebugFormat("Socket `{0}` status changed to `{1}`. Reason: {2}", ipSocket, status, reason); } // Forward to the handler OnReceiveStatusChanged(ipSocket, status, reason); break; case NetIncomingMessageType.Data: // Get the IIPSocket for the connection (it definitely should be created by this point) ipSocket = (IIPSocket)incMsg.SenderConnection.Tag; Debug.Assert(ipSocket != null); // Copy the received data into a BitStream before passing it up _receiveBitStream.Reset(); _receiveBitStream.Write(incMsg); _receiveBitStream.PositionBits = 0; if (log.IsDebugEnabled) { log.DebugFormat("Received {0} bits from {1}.", incMsg.LengthBits, ipSocket); } // Forward the data to the data handler OnReceiveData(ipSocket, _receiveBitStream); break; } _local.Recycle(incMsg); } }