Пример #1
0
        /*
         * Check for messages and also deal with new connections and disconnects etc
         */
        private bool ReceiveAndProcessEvents(out int connectionId, out TransportEvent transportEvent, out byte[] data, int chan)
        {
            data = null;

            //first check if we have received any new connections and return them as an event
            if (steamNewConnections.Count > 0)
            {
                if (LogFilter.Debug || debug)
                {
                    Debug.Log("Handling a new connection from queue");
                }

                connectionId = steamNewConnections.Dequeue();

                try
                {
                    SteamClient steamClient = steamConnectionMap.fromConnectionID[connectionId];

                    steamClient.timeIdle = 0;

                    if (steamClient.state == SteamClient.ConnectionState.CONNECTING)
                    {
                        if (LogFilter.Debug || debug)
                        {
                            Debug.Log("Set connection state to connected");
                        }
                        steamClient.state = SteamClient.ConnectionState.CONNECTED;
                    }
                }
                catch (KeyNotFoundException)
                {
                    //shouldnt happen - ignore
                }

                transportEvent = TransportEvent.Connected;
                return(true);
            }

            //first check if we have received any new disconnects and return them as an event
            if (steamDisconnectedConnections.Count > 0)
            {
                if (LogFilter.Debug || debug)
                {
                    Debug.Log("Handling a disconnect from queue");
                }

                SteamClient steamClient = steamDisconnectedConnections.Dequeue();
                connectionId   = steamClient.connectionID;
                transportEvent = TransportEvent.Disconnected;

                //at this point we have completly disconnected from the client so stop accepting further messages from this client
                SteamNetworking.CloseP2PSessionWithUser(steamClient.steamID);

                return(true);
            }

            //this is a buffer that may have been received at the same time as a new connection
            if (serverReceiveBufferPending != null)
            {
                if (LogFilter.Debug || debug)
                {
                    Debug.Log("Handling a postponed message");
                }

                //we have a packet received and already in the buffer waiting to be returned
                connectionId   = serverReceiveBufferPendingConnectionID;
                transportEvent = TransportEvent.Data;
                data           = serverReceiveBufferPending;

                //clear our buffered variables
                serverReceiveBufferPendingConnectionID = -1;
                serverReceiveBufferPending             = null;
                return(true);
            }

            //finally look for new packets

            return(Receive(out connectionId, out transportEvent, out data, chan));
        }
Пример #2
0
        /**
         * Check for internal networked messages like disconnect request
         */
        private void handleInternalMessages()
        {
            if (lastInternalMessageFrame == Time.frameCount)
            {
                return; //already processed this frame
            }
            lastInternalMessageFrame = Time.frameCount;

            int connectionId;

            Byte[] data;

            while (ReceiveInternal(out connectionId, out data))
            {
                if (LogFilter.Debug || debug)
                {
                    Debug.Log("handleInternalMessages Got a message");
                }
                try
                {
                    SteamClient steamClient = steamConnectionMap.fromConnectionID[connectionId];

                    if (steamClient.state == SteamClient.ConnectionState.CONNECTED || steamClient.state == SteamClient.ConnectionState.CONNECTING)
                    {
                        NetworkReader reader  = new NetworkReader(data);
                        byte          message = reader.ReadByte();
                        switch (message)
                        {
                        case (byte)InternalMessages.CONNECT:
                            if (LogFilter.Debug || debug)
                            {
                                Debug.LogWarning("Received a request to Connect from " + steamClient.steamID);
                            }

                            //if we are a server and have spaces then accept the request to connect, else reject
                            if (mode == Mode.SERVER && getNumberOfActiveConnection() < maxConnections)
                            {
                                //we have to queue this connection up so we can let the ReceiveFromHost method return the new connection
                                steamNewConnections.Enqueue(connectionId);
                                //send a message back to the client to confirm they have connected successfully
                                SteamNetworking.SendP2PPacket(steamClient.steamID, acceptConnectMsgBuffer, (uint)acceptConnectMsgBuffer.Length, sendMethods[Channels.DefaultReliable], (int)SteamChannels.SEND_INTERNAL);
                            }
                            else
                            {
                                if (LogFilter.Debug || debug)
                                {
                                    Debug.LogWarning("Rejected connect from " + steamClient.steamID + ". Active Connections: " + getNumberOfActiveConnection() + ", maxConnections: " + maxConnections);
                                }
                                SteamNetworking.CloseP2PSessionWithUser(steamClient.steamID);
                            }

                            steamClient.timeIdle = 0;

                            break;

                        case (byte)InternalMessages.ACCEPT_CONNECT:
                            if (LogFilter.Debug || debug)
                            {
                                Debug.LogWarning("Received an accept to connect to " + steamClient.steamID);
                            }

                            //if we are a client and received this message from the server we are trying to connect to then connect, else reject
                            if (mode == Mode.CLIENT && steamClient.steamID == steamClientServer.steamID)
                            {
                                //we have to queue this connection up so we can let the ReceiveFromHost method return the new connection
                                steamNewConnections.Enqueue(connectionId);
                            }
                            else
                            {
                                Debug.LogError("Received an ACCEPT_CONNECT from wrong person");
                                SteamNetworking.CloseP2PSessionWithUser(steamClient.steamID);
                            }

                            steamClient.timeIdle = 0;

                            break;

                        case (byte)InternalMessages.DISCONNECT:
                            if (LogFilter.Debug || debug)
                            {
                                Debug.LogWarning("Received an instruction to Disconnect from " + steamClient.steamID);
                            }

                            //requested to disconnect
                            if (mode == Mode.CLIENT || mode == Mode.SERVER)
                            {
                                //disconnect this client
                                closeSteamConnection(steamClient);
                            }
                            break;
                        }
                    }
                    else
                    {
                        Debug.LogWarning("Received message for non connected client ?");
                    }
                }
                catch (KeyNotFoundException)
                {
                    //shouldnt happen - ignore
                    Debug.LogError("Received internal message from unknown.. connect?");
                }
            }

            //check all connections to check they are healthy
            foreach (var connection in steamConnectionMap)
            {
                SteamClient steamClient = connection.Value;

                if (steamClient.state == SteamClient.ConnectionState.CONNECTED)
                {
                    if (steamClient.timeIdle > (NetworkTime.PingFrequency + connectedTimeoutBuffer))
                    {
                        //idle too long - disconnect
                        Debug.LogWarning("Connection " + steamClient.connectionID + " timed out - going to disconnect");
                        internalDisconnect(steamClient);
                        continue;
                    }

                    //If client then this will Not be called if the scene is loading. We dont want to count idle time if loading the scene for this reason
                    //If Server then this will be called so we need to not count idle time for clients who are not "ready" as they are loading the scene and unable to communicate. The connect timeout will catch people that disconnect during scene load
                    if (mode == Mode.CLIENT || (mode == Mode.SERVER && (!NetworkServer.connections.ContainsKey(steamClient.connectionID) || NetworkServer.connections[steamClient.connectionID].isReady)))
                    {
                        steamClient.timeIdle += Time.deltaTime;
                    }
                }
            }
        }
        /**
         * Check for internal networked messages like ping or disconnect request
         */
        private void handleInternalMessages()
        {
            if (lastInternalMessageFrame == Time.frameCount)
            {
                return; //already processed this frame
            }
            lastInternalMessageFrame = Time.frameCount;

            int            connectionId;
            TransportEvent transportEvent;

            Byte[] data;

            while (ReceiveInternal(out connectionId, out data))
            {
                try
                {
                    SteamClient steamClient = steamConnectionMap.fromConnectionID[connectionId];

                    if (steamClient.state == SteamClient.ConnectionState.CONNECTED)
                    {
                        float senderTime;

                        NetworkReader reader = new NetworkReader(data);
                        switch (reader.ReadByte())
                        {
                        case (byte)InternalMessages.PING:
                            //ping .. send a pong
                            senderTime = reader.ReadSingle();
                            sendInternalPong(steamClient, senderTime);
                            break;

                        case (byte)InternalMessages.PONG:
                            //pong .. update when we last received a pong
                            senderTime           = reader.ReadSingle();
                            steamClient.lastPong = Time.time;

                            double rtt = LocalTime() - senderTime;
                            _rtt.Add(rtt);
                            break;

                        case (byte)InternalMessages.DISCONNECT:
                            if (LogFilter.Debug)
                            {
                                Debug.LogWarning("Received an instruction to Disconnect");
                            }
                            //requested to disconnect
                            if (mode == Mode.CLIENT || mode == Mode.SERVER)
                            {
                                //disconnect this client
                                closeSteamConnection(steamClient);
                            }
                            break;
                        }
                    }
                }
                catch (KeyNotFoundException)
                {
                    //shouldnt happen - ignore
                }
            }

            //check all connections to check they are healthy
            foreach (var connection in steamConnectionMap)
            {
                SteamClient steamClient = connection.Value;

                if (steamClient.state == SteamClient.ConnectionState.CONNECTED)
                {
                    if (Time.time - steamClient.lastPong > PONG_TIMEOUT)
                    {
                        //idle too long - disconnect
                        Debug.LogError("Connection " + steamClient.connectionID + " timed out - going to disconnect");
                        internalDisconnect(steamClient);
                        continue;
                    }
                    if (Time.time - steamClient.lastPing > PING_FREQUENCY)
                    {
                        //time to ping
                        sendInternalPing(steamClient);
                    }
                }
            }
        }