Пример #1
0
        // This routine with be run synchronously with UDPWii.Server
        public void SendDataPacket(UDPWii.DataDSU packet)
        {
            // If the server is not running, just drop the packet
            if (tokenSource == null)
            {
                return;
            }

            lock (clients)
            {
                // If there's no client, skip the packet processing step and drop the packet
                if (clients.Count == 0)
                {
                    return;
                }

                List <IPEndPoint> toRemove = new List <IPEndPoint>();

                DSU.DataRsp dsuPacket     = packet.ToDSU(id);
                byte[]      dsuPacketData = dsuPacket.Finish();
                //Console.WriteLine("[DSU.Sender] ({0}, {1})", dsuPacket.touch1.x, dsuPacket.touch1.y);

                foreach (var keyValuePair in clients)
                {
                    Client client = keyValuePair.Value;
                    if (!Util.IsTimeout(client.lastSeenAll) || !Util.IsTimeout(client.lastSeenSlot[packet.client.slot]))
                    {
                        udpSend.Send(dsuPacketData, dsuPacketData.Length, keyValuePair.Key);
                    }
                    else
                    {
                        // Is this client completely dead? If so, mark it for removal
                        // Reference: https://github.com/Davidobot/BetterJoy/blob/master/BetterJoyForCemu/UpdServer.cs

                        // We're here so lastSeenAll must have timed out
                        if (client.lastSeenSlot.All(Util.IsTimeout))
                        {
                            toRemove.Add(keyValuePair.Key);
                        }
                    }
                    //Console.WriteLine("[DSU.Sender] Packet sent to " + keyValuePair.Key.ToString());
                }

                // Clear all dead clients now to prevent concurrent modification
                foreach (IPEndPoint key in toRemove)
                {
                    Console.WriteLine("[DSU.Server] Removing dead client {0}", key.ToString());
                    clients.Remove(key);
                }
            }
        }
Пример #2
0
        private void TaskMain(CancellationToken token)
        {
            broadcaster.Start();

            try
            {
                Task <UdpReceiveResult> taskRecv;
                while (true)
                {
                    token.ThrowIfCancellationRequested();

                    //Util.TimingStart();
                    taskRecv = udp.ReceiveAsync();
                    taskRecv.Wait(token);
                    //Console.WriteLine(Util.TimingEnd());

                    // Mark this server's client as "alive"
                    client.lastSeen = DateTime.Now;

                    // Box data for DSU.Sender
                    UDPWii.DataDSU packet = new UDPWii.DataDSU(taskRecv.Result.Buffer, client);
                    if (packet.flags == UDPWii.Data.Flags.None)
                    {
                        Console.WriteLine("[UDPWii.Server@{0}] Dropping invalid packet from {1}", client.slot, taskRecv.Result.RemoteEndPoint.ToString());
                    }
                    else
                    {
                        //Util.TimingStart();
                        DSU.Server.theInstance.SendDataPacket(packet);
                        //Console.Error.WriteLine(Util.TimingEnd());
                    }
                }
            }
            catch (OperationCanceledException)
            {
                ;
            }

            broadcaster.Stop();
        }