Esempio n. 1
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// Receive message processing.
        /// </summary>
        /// <param name="msg"></param>
        //----------------------------------------------------------------------------------
        public void ReceivePacket(IAsyncResult msg)
        {
            NetworkDataPacket packet   = null;
            IPEndPoint        endPoint = new IPEndPoint(0, 0);

            byte[] data = m_udpClient.EndReceive(msg, ref endPoint);

            packet = Deserialize(data);

            packet.IPAddress = endPoint.Address;
            packet.NetworkID = m_UdpClients[endPoint.Address].NetworkID;

            //if packet is sent InOrder then an ACK needs to be sent.
            if (packet.SendMethod == NetworkSendMethod.InOrder)
            {
                SendAck(endPoint.Address);
            }

            //we divert it at this point based on if its a system for the EntityController ie. Delete or Create or an entity message
            if (packet.MessageType == MessageType.SystemMessage)
            {
                ProcessSystemMessage(packet);
            }
            else
            {
                if (ReceiveCallback != null)
                {
                    ReceiveCallback(packet);
                }
            }

            m_udpClient.BeginReceive(ReceivePacket, null);
        }
Esempio n. 2
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// Process system message for the EntityController.
        /// </summary>
        /// <param name="packet">received packet data.</param>
        /// <returns></returns>
        //----------------------------------------------------------------------------------
        private bool ProcessSystemMessage(NetworkDataPacket packet)
        {
            bool bResult    = false;
            Type systemType = typeof(HybridClient);

            //using reflection.
            MethodInfo method = systemType.GetMethod(
                packet.MethodInvoke,
                BindingFlags.Instance |
                BindingFlags.NonPublic |
                BindingFlags.Public);

            //if we find the message call...then we handle it. it not we pass it on to the local device for further handling.
            if (method != null)
            {
                method.Invoke(this, new object[] { packet });
                bResult = true;
            }
            else
            {
                if (SystemMessageReceivedCallback != null)
                {
                    SystemMessageReceivedCallback(packet);
                }
            }

            return(bResult);
        }
Esempio n. 3
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// Update ACK mask when an ACK is received.
        /// </summary>
        /// <param name="packet"></param>
        //----------------------------------------------------------------------------------
        private void ReceiveAck(NetworkDataPacket packet)
        {
            int nMaskIndex = m_UdpClients[packet.IPAddress].NetworkID;

            //OR the flags together.
            m_AckClientsMask |= nMaskIndex;
        }
Esempio n. 4
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// For the receiving client to send an ACK when a packet is sent in order.
        /// </summary>
        /// <param name="address">Address to send the ACK back to.</param>
        //----------------------------------------------------------------------------------
        private void SendAck(IPAddress address)
        {
            NetworkDataPacket packet = new NetworkDataPacket();

            packet.MessageType  = MessageType.SystemMessage;
            packet.MethodInvoke = "ReceiveAck";
            packet.SendMethod   = NetworkSendMethod.FireForget;

            SendPacket(packet, address);
        }
Esempio n. 5
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// Serialize packet in binary format.
        /// </summary>
        /// <param name="packet">packet to be serialized</param>
        /// <returns></returns>
        //----------------------------------------------------------------------------------
        private byte[] SerializePacket(NetworkDataPacket packet)
        {
            //We reset the buffer back to the start.
            try
            {
                m_SendMemoryBuffer.Position = 0;
                m_formatter.Serialize(m_SendMemoryBuffer, packet);
                m_SendMemoryBuffer.Flush();
            }
            catch (System.Exception ex) { Debug.Assert(false, "a network packet failed to serialize"); }

            return(Compress(m_SendMemoryBuffer.ToArray()));
        }
Esempio n. 6
0
 //----------------------------------------------------------------------------------
 /// <summary>
 /// Put received queue ready for processing.
 /// </summary>
 /// <param name="packet">received packet</param>
 //----------------------------------------------------------------------------------
 public void QueueMessage(NetworkDataPacket packet)
 {
     if (m_bQueueReceivedMessages)
     {
         lock (m_ReceiveListLock)
             m_ReceivedPackets.Add(packet);
     }
     else
     {
         if (MessageReceived != null)
         {
             MessageReceived(packet);
         }
     }
 }
Esempio n. 7
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// Broadcast to any available clients looking to connect.
        /// </summary>
        /// <param name="packet">packet data.</param>
        //----------------------------------------------------------------------------------
        private void LookingForPeers(NetworkDataPacket packet)
        {
            //check if connections are allowed
            if (m_bAllowConnections)
            {
                byte[] data;
                //find first available connection index.
                int nMaskIndex = FindAvailableIndex();

                //ensure the index return is a valid index entry.
                if (nMaskIndex != InvalidIndex)
                {
                    NetworkDataPacket replyPacket = new NetworkDataPacket();
                    UdpClient         newClient   = new UdpClient();
                    newClient.Connect(new IPEndPoint(packet.IPAddress, m_nUdpPort));

                    m_UdpClients.Add(packet.IPAddress,
                                     new ClientConnectedInfo(nMaskIndex,
                                                             newClient,
                                                             packet.IPAddress)
                                     );

                    //we lock here to avoid race conditions with the packet proc.
                    lock (m_connectionLock)
                        m_ConnectedClientsMask |= nMaskIndex;

                    if (ClientConnectedCallback != null)
                    {
                        ClientConnectedCallback(nMaskIndex);
                    }

                    //set up the reply packet
                    replyPacket.MessageType  = MessageType.SystemMessage;
                    replyPacket.SendMethod   = NetworkSendMethod.FireForget;
                    replyPacket.MethodInvoke = "PeerConnectionReply";

                    data = SerializePacket(replyPacket);

                    newClient.BeginSend(data, data.Length, SendCompleteCallback, newClient);
                }
            }
        }
Esempio n. 8
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// Process messages that are meant for the EntityController.
        /// </summary>
        /// <param name="packet"></param>
        //----------------------------------------------------------------------------------
        public void ProcessSystemMessage(NetworkDataPacket packet)
        {
            Type type = typeof(NetworkEngine);

            //use reflection to find method.
            MethodInfo method = type.GetMethod(
                packet.MethodInvoke,
                BindingFlags.Instance |
                BindingFlags.NonPublic |
                BindingFlags.Public);

            if (method != null)
            {
                method.Invoke(this, new object[] { packet });
            }
            else
            {
                Debug.Assert(false, "Failed to find a system message for " + packet.MethodInvoke);
            }
        }
Esempio n. 9
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// sends network data packet message across the network.
        /// </summary>
        /// <param name="packet">the packet to be sent.</param>
        /// <param name="address">the address of the client that the packet is to be sent to.</param>
        //----------------------------------------------------------------------------------
        public void SendPacket(NetworkDataPacket packet, IPAddress address = null)
        {
            IPEndPoint          endPoint = null;
            ClientConnectedInfo clientInfo;

            byte[] data;

            if (address != null)
            {
                endPoint = new IPEndPoint(address, m_nUdpPort);
            }

            data = SerializePacket(packet);

            clientInfo = m_UdpClients[endPoint.Address];
            clientInfo.Client.BeginSend(data,
                                        data.Length,
                                        SendCompleteCallback,
                                        null);
        }
Esempio n. 10
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// locate and return broadcasting peers for the network.
        /// </summary>
        //----------------------------------------------------------------------------------
        public void FindPeers()
        {
            byte[]            data;
            NetworkDataPacket packet = new NetworkDataPacket();

            packet.NetworkID    = 0;
            packet.MessageType  = MessageType.SystemMessage;
            packet.SendMethod   = NetworkSendMethod.FireForget;
            packet.MethodInvoke = "LookingForPeers";

            m_udpClient.EnableBroadcast = true;

            data = SerializePacket(packet);
            m_bAllowConnections = true;
            m_udpClient.BeginSend(data,
                                  data.Length,
                                  new IPEndPoint(IPAddress.Loopback, m_nUdpPort),
                                  SendCompleteCallback,
                                  m_udpClient);
        }
Esempio n. 11
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// This is the reply to a client looking for peers.
        /// </summary>
        /// <param name="packet">Received packet</param>
        //----------------------------------------------------------------------------------
        private void PeerConnectionReply(NetworkDataPacket packet)
        {
            //get connection mask index
            int nMaskIndex = FindAvailableIndex();

            //ensure its a valid index.
            if (nMaskIndex != InvalidIndex)
            {
                UdpClient newClient = new UdpClient(new IPEndPoint(packet.IPAddress, m_nUdpPort));
                m_UdpClients.Add(packet.IPAddress, new ClientConnectedInfo(nMaskIndex, newClient, packet.IPAddress));

                //lock wil updating mask to avoid race conditions.
                lock (m_connectionLock)
                    m_ConnectedClientsMask |= nMaskIndex;

                if (ClientConnectedCallback != null)
                {
                    ClientConnectedCallback(nMaskIndex);
                }
            }
        }
Esempio n. 12
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// Deserilize a reveived packet.
        /// </summary>
        /// <param name="data">data to be deserialized.</param>
        /// <returns>NetworkDataPacket</returns>
        //----------------------------------------------------------------------------------
        private NetworkDataPacket Deserialize(byte[] data)
        {
            NetworkDataPacket packet = null;

            m_ReceiveMemoryBuffer.Position = 0;

            try
            {
                byte[] decompressData = Decompress(data);
                m_ReceiveMemoryBuffer.Write(decompressData, 0, decompressData.Length);
                m_ReceiveMemoryBuffer.Flush();
                m_ReceiveMemoryBuffer.Seek(0, SeekOrigin.Begin);
                m_ReceiveMemoryBuffer.Position = 0;

                packet = (NetworkDataPacket)m_formatter.Deserialize(m_ReceiveMemoryBuffer);
            }
            catch (System.Exception ex)
            {
                Debug.Assert(false);
            }

            return(packet);
        }
Esempio n. 13
0
 //----------------------------------------------------------------------------------
 /// <summary>
 /// Send network message. Wraps hybrid client send packet.
 /// </summary>
 /// <param name="packet"></param>
 /// <param name="address"></param>
 //----------------------------------------------------------------------------------
 public void SendMessage(NetworkDataPacket packet, IPAddress address = null)
 {
     m_hybridclient.SendPacket(packet, address);
 }
Esempio n. 14
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// Processes the send queue and send all queued packets for the network. NOTE: This is done on a seperate thread.
        /// </summary>
        /// <param name="queue"></param>
        //----------------------------------------------------------------------------------
        private void ProcessSendQueue(object queue)
        {
            lock (m_SendQueueLock)
            {
                if (m_OrderedSendQueue.Count > 0)
                {
                    while (m_OrderedSendQueue.Count > 0)
                    {
                        NetworkSendItem   item     = m_OrderedSendQueue.Dequeue();
                        NetworkDataPacket packet   = item.Packet;
                        IPEndPoint        endpoint = null;

                        //serialise the packet to be sent.
                        byte[] data = SerializePacket(packet);
                        int    nConnectionMask;
                        int    nCounter = 50;
                        int    nSpins   = 0;
                        m_AckClientsMask = 0;

                        if (item.IPAdress != null)
                        {
                            endpoint = new IPEndPoint(item.IPAdress, m_nUdpPort);
                        }

                        if (endpoint == null)
                        {
                            //send the packet to all connected clients.
                            foreach (ClientConnectedInfo clientInfo in m_UdpClients.Values)
                            {
                                clientInfo.Client.BeginSend(data,
                                                            data.Length,
                                                            SendCompleteCallback,
                                                            clientInfo.Client);
                            }

                            //We don't obtain a double nested lock on the AckMask as
                            //we want the thread to overwrite as necessary
                            lock (m_connectionLock)
                                nConnectionMask = m_ConnectedClientsMask;

                            //We hold execution here until all acks have come back.
                            while (0 != (m_AckClientsMask ^ nConnectionMask))
                            {
                                ++nSpins;

                                if (nSpins > nCounter)
                                {
                                    //if a certain amount of time passes and not all replies have come back.
                                    // disconnect that client.
                                    int nDisconnectionMask = m_ConnectedClientsMask ^ m_AckClientsMask;

                                    for (int i = 0; i < 32; ++i)
                                    {
                                        if (0 != (m_ConnectedClientsMask & i))
                                        {
                                            DisconnectPeer(i);
                                        }
                                    }
                                }

                                //We need to keep updating this every cycle to check if anything has changed.
                                lock (m_connectionLock)
                                    nConnectionMask = m_ConnectedClientsMask;
                            }
                        }
                        else
                        {
                            //This is if we are only sending an inorder packet to a single client.
                            ClientConnectedInfo clientInfo = m_UdpClients[endpoint.Address];

                            clientInfo.Client.BeginSend(data,
                                                        data.Length,
                                                        SendCompleteCallback,
                                                        clientInfo.Client);

                            //We hold execution here till we get a response..
                            //if we dont we assume the client has disconnected.
                            while (0 != (m_AckClientsMask & clientInfo.NetworkID))
                            {
                                ++nSpins;

                                if (nSpins > nCounter)
                                {
                                    DisconnectPeer(clientInfo.Address);
                                }
                            }
                        }
                    }
                }
            }
        }