예제 #1
0
        /// <summary>
        /// Receives bytes from endpoint.
        /// </summary>
        /// <returns>The amount of bytes received. 0 or elss if failed.</returns>
        /// <param name="buffer">The buffer to receive to.</param>
        /// <param name="offset">The offer of the buffer to receive at.</param>
        /// <param name="length">The max length to receive.</param>
        /// <param name="timeoutMs">The operation timeout in milliseconds.</param>
        /// <param name="endpoint">The endpoint the packet came from.</param>
        public int ReceiveFrom(byte[] buffer, int offset, int length, int timeoutMs, out IPEndPoint endpoint)
        {
            if (socket != null)
            {
                // Wait for message. This is to prevent a tight loop
                socket.SyncronizationEvent.WaitOne(timeoutMs);

                NetworkEvent @event;
                while ((@event = socket.Poll()).Type != NetworkEventType.Nothing)
                {
                    if (@event.Type == NetworkEventType.UnconnectedData)
                    {
                        if (@event.Data.Count == length)
                        {
                            endpoint = (IPEndPoint)@event.EndPoint;

                            Array.Copy(@event.Data.Array, 0, buffer, offset, length);

                            return(@event.Data.Count);
                        }
                    }

                    // Recycle the event
                    @event.Recycle();
                }
            }
            endpoint = null;
            return(-1);
        }
예제 #2
0
        public static void Server()
        {
            RuffleSocket socket = new RuffleSocket(new Configuration.SocketConfig()
            {
                AllowBroadcasts          = true,
                AllowUnconnectedMessages = true,
                DualListenPort           = 5555
            });

            socket.Start();

            while (true)
            {
                // Wait for message. This is to prevent a tight loop
                socket.SyncronizationEvent.WaitOne(1000);

                NetworkEvent @event;
                while ((@event = socket.Poll()).Type != NetworkEventType.Nothing)
                {
                    if (@event.Type == NetworkEventType.BroadcastData)
                    {
                        // We got a broadcast. Reply to them with the same token they used
                        socket.SendUnconnected(@event.Data, (IPEndPoint)@event.EndPoint);
                    }

                    // Recycle the event
                    @event.Recycle();
                }
            }
        }
예제 #3
0
        protected override void PreUpdate(double deltaTime)
        {
            base.PreUpdate(deltaTime);

            //InfoViewer.Values["Server FPS"] = Math.Round(1f / deltaTime, 2).ToString();

            NetworkEvent networkEvent = _server.Poll();

            while (networkEvent.Type != NetworkEventType.Nothing)
            {
                switch (networkEvent.Type)
                {
                case NetworkEventType.Connect:
                    _newConnections.Add(networkEvent.Connection);
                    break;

                case NetworkEventType.Data:
                    MessageRecieved(networkEvent.Data);
                    break;
                }
                networkEvent.Recycle();
                networkEvent = _server.Poll();
            }
        }
예제 #4
0
        public override NetEventType PollEvent(out ulong clientId, out string channelName, out ArraySegment <byte> payload)
        {
            socket.RunInternalLoop();
            NetworkEvent @event = socket.Poll();

            if (@event.Type != NetworkEventType.Nothing)
            {
                clientId = GetMLAPIClientId(@event.Connection.Id, false);
            }
            else
            {
                clientId = 0;
            }

            byte[] dataBuffer = messageBuffer;

            if (@event.Type == NetworkEventType.Data)
            {
                if (@event.Data.Count > messageBuffer.Length)
                {
                    if (temporaryBufferReference != null && temporaryBufferReference.IsAlive && ((byte[])temporaryBufferReference.Target).Length >= @event.Data.Count)
                    {
                        dataBuffer = (byte[])temporaryBufferReference.Target;
                    }
                    else
                    {
                        dataBuffer = new byte[@event.Data.Count];
                        temporaryBufferReference = new WeakReference(dataBuffer);
                    }
                }

                Buffer.BlockCopy(@event.Data.Array, @event.Data.Offset, dataBuffer, 0, @event.Data.Count);
                payload = new ArraySegment <byte>(dataBuffer, 0, @event.Data.Count);
            }
            else
            {
                payload = new ArraySegment <byte>();
            }

            channelName = channelIdToName[@event.ChannelId];

            // Translate NetworkEventType to NetEventType
            switch (@event.Type)
            {
            case NetworkEventType.Data:
                return(NetEventType.Data);

            case NetworkEventType.Connect:
            {
                connections.Add(@event.Connection.Id, @event.Connection);

                // Set the server connectionId
                if (isConnector)
                {
                    serverConnection = @event.Connection;
                }

                return(NetEventType.Connect);
            }

            case NetworkEventType.Timeout:
            case NetworkEventType.Disconnect:
            {
                if (@event.Connection == serverConnection)
                {
                    serverConnection = null;
                }

                connections.Remove(@event.Connection.Id);

                @event.Connection.Recycle();

                return(NetEventType.Disconnect);
            }

            case NetworkEventType.Nothing:
                return(NetEventType.Nothing);
            }

            return(NetEventType.Nothing);
        }
예제 #5
0
        public override NetworkEvent PollEvent(out ulong clientId, out ArraySegment <byte> payload, out float receiveTime)
        {
            RufflesNetworkEvent @event = socket.Poll();

            receiveTime = Time.realtimeSinceStartup - (float)(NetTime.Now - @event.SocketReceiveTime).TotalSeconds;

            byte[] dataBuffer = messageBuffer;

            if (@event.Type == NetworkEventType.Data)
            {
                if (@event.Data.Count > messageBuffer.Length)
                {
                    if (temporaryBufferReference != null && temporaryBufferReference.IsAlive && ((byte[])temporaryBufferReference.Target).Length >= @event.Data.Count)
                    {
                        dataBuffer = (byte[])temporaryBufferReference.Target;
                    }
                    else
                    {
                        dataBuffer = new byte[@event.Data.Count];
                        temporaryBufferReference = new WeakReference(dataBuffer);
                    }
                }

                Buffer.BlockCopy(@event.Data.Array, @event.Data.Offset, dataBuffer, 0, @event.Data.Count);
                payload = new ArraySegment <byte>(dataBuffer, 0, @event.Data.Count);
            }
            else
            {
                payload = new ArraySegment <byte>();
            }

            if (@event.Connection != null)
            {
                clientId = GetMLAPIClientId(@event.Connection.Id, false);
            }
            else
            {
                clientId = 0;
            }

            // Translate NetworkEventType to NetEventType
            switch (@event.Type)
            {
            case NetworkEventType.Data:
                @event.Recycle();
                return(NetworkEvent.Data);

            case NetworkEventType.Connect:
            {
                if (isConnector && @event.Connection == serverConnection)
                {
                    // Connection successful
                }

                // Add the connection
                connections.Add(@event.Connection.Id, @event.Connection);

                @event.Recycle();
                return(NetworkEvent.Connect);
            }

            case NetworkEventType.Timeout:
            case NetworkEventType.Disconnect:
            {
                if (isConnector && @event.Connection == serverConnection)
                {
                    // Connection failed
                }

                connections.Remove(@event.Connection.Id);

                @event.Recycle();
                return(NetworkEvent.Disconnect);
            }

            default:
                @event.Recycle();
                return(NetworkEvent.Nothing);
            }
        }
예제 #6
0
        public static void Main(string[] args)
        {
            RuffleSocket server = new RuffleSocket(ServerConfig);

            RuffleSocket client = new RuffleSocket(ClientConfig);

            client.Start();
            server.Start();

            if (IPv6)
            {
                // IPv6 Connect
                client.Connect(new IPEndPoint(IPAddress.Parse("0:0:0:0:0:0:0:1"), 5674));
            }
            else
            {
                // IPv4 Connect
                client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5674));
            }

            // The server stores the clients id here
            Connection clientConnection = null;
            // The client stores the servers id here
            Connection serverConnection = null;

            // The time when the connection started
            DateTime started = DateTime.Now;

            // The time when the last message was sent
            DateTime lastSent = DateTime.MinValue;

            // The time the last status was printed
            DateTime lastStatusPrint = DateTime.MinValue;

            // The amount of message that has been received
            int messagesReceived = 0;

            // The amount of messages that has been sent
            int messageCounter = 0;

            while (true)
            {
                // Polls server for events
                NetworkEvent serverEvent = server.Poll();
                // Polls client for events
                NetworkEvent clientEvent = client.Poll();

                if (serverEvent.Type != NetworkEventType.Nothing)
                {
                    Console.WriteLine("ServerEvent: " + serverEvent.Type);

                    if (serverEvent.Type == NetworkEventType.Connect)
                    {
                        clientConnection = serverEvent.Connection;
                    }

                    if (serverEvent.Type == NetworkEventType.AckNotification)
                    {
                        Console.WriteLine("The remote acked message id: " + serverEvent.NotificationKey);
                    }
                }

                serverEvent.Recycle();

                if (clientEvent.Type != NetworkEventType.Nothing)
                {
                    Console.WriteLine("ClientEvent: " + clientEvent.Type);

                    if (clientEvent.Type == NetworkEventType.Connect)
                    {
                        serverConnection = clientEvent.Connection;
                    }

                    if (clientEvent.Type == NetworkEventType.Data)
                    {
                        messagesReceived++;
                        Console.WriteLine("Got message: \"" + Encoding.ASCII.GetString(clientEvent.Data.Array, clientEvent.Data.Offset, clientEvent.Data.Count) + "\"");
                    }
                }

                clientEvent.Recycle();

                if (serverConnection != null && clientConnection != null && serverConnection.State == ConnectionState.Connected && clientConnection.State == ConnectionState.Connected && (DateTime.Now - lastSent).TotalSeconds >= (1f / 1))
                {
                    byte[] helloReliable = Encoding.ASCII.GetBytes("This message was sent over a reliable channel" + messageCounter);
                    clientConnection.Send(new ArraySegment <byte>(helloReliable, 0, helloReliable.Length), 1, false, (ulong)messageCounter);
                    Console.WriteLine("Sending packet: " + messageCounter);

                    messageCounter++;
                    lastSent = DateTime.Now;
                }

                if (serverConnection != null && clientConnection != null && serverConnection.State == ConnectionState.Connected && clientConnection.State == ConnectionState.Connected && (DateTime.Now - lastStatusPrint).TotalSeconds >= 5)
                {
                    Console.WriteLine("Ping: " + serverConnection.SmoothRoundtrip + "ms, " + clientConnection.SmoothRoundtrip + "ms");
                    lastStatusPrint = DateTime.Now;
                }
            }
        }
예제 #7
0
        public override void Update()
        {
            var deltaSeconds = Stopwatch.Elapsed.TotalSeconds;
            InfoViewer.Log("Client FPS", Math.Round(1f / deltaSeconds, 2).ToString());

            InfoViewer.Log("Roundtrip", _server?.Roundtrip.ToString());
            InfoViewer.Log("Roundtrip Varience", _server?.RoundtripVarience.ToString());

            Stopwatch.Restart();

            NetworkEvent networkEvent = _client.Poll();
            while (networkEvent.Type != NetworkEventType.Nothing)
            {
                switch (networkEvent.Type)
                {
                    case NetworkEventType.Connect:
                        _server = networkEvent.Connection;
                        break;
                    case NetworkEventType.Data:
                        var diff = _messageTimer.Elapsed.TotalMilliseconds;
                        //InfoViewer.Values["Message Time"] = Math.Round(diff, 4).ToString();
                        _messageTimer.Restart();
                        MessageRecieved(networkEvent.Data);
                        break;
                }
                networkEvent.Recycle();
                networkEvent = _client.Poll();
            }

            _imGuiRenderer.Update((float)deltaSeconds, _window.InputSnapshot);
            var imGuiWantsMouse = ImGuiNET.ImGui.GetIO().WantCaptureMouse;

            var cameraEntities = _camerasSet.GetEntities();
            var cameraTransform = cameraEntities.Length > 0 ? cameraEntities[0].Get<Transform>() : new Transform();

            var inputTrackerTransform = Matrix3x2.CreateTranslation(-_window.Width / 2f, -_window.Height / 2f) *
                Matrix3x2.CreateScale(1 / Settings.GRAPHICS_SCALE, -1 / Settings.GRAPHICS_SCALE) *
                Matrix3x2.CreateScale(1 / _zoom) *
                cameraTransform.Matrix;

            _cameraSpaceInputTracker.SetTransform(inputTrackerTransform);
            _cameraSpaceGameInputTracker.SetActive(!imGuiWantsMouse);

            _zoom += _window.InputSnapshot.WheelDelta * 0.1f;

            PreUpdate(deltaSeconds);
            Scene.Update(new LogicUpdate((float)deltaSeconds, _cameraSpaceGameInputTracker));
            PostUpdate(deltaSeconds);

            var serverMessages = new List<object>();

            _editorMenu.Run(new EditorUpdate()
            {
                CameraSpaceInput = _cameraSpaceInputTracker,
                CameraSpaceGameInput = _cameraSpaceGameInputTracker,
                Scene = Scene,
                ServerMessages = serverMessages
            });

            var clientUpdate = new ClientSystemUpdate()
            {
                Messages = serverMessages,
                Input = _cameraSpaceGameInputTracker
            };

            foreach (var system in _clientSystems)
            {
                system.Update(clientUpdate);
            }

            if(_server != null)
            {
                var messages = SerializeMessages(serverMessages);
                _server.Send(messages, 5, true, _messagesSent++);
            }

            cameraEntities = _camerasSet.GetEntities();
            cameraTransform = cameraEntities.Length > 0 ? cameraEntities[0].Get<Transform>() : new Transform();

            var cameraMatrix = cameraTransform.GetCameraMatrix(Settings.GRAPHICS_SCALE) * Matrix4x4.CreateScale(_zoom);

            var vp = _viewport.Viewport;
            _drawDevice.Begin(cameraMatrix * _viewport.GetScalingTransform(), vp);

            Scene.Render(_drawDevice);

            float gridSize = 20;
            var gridCenter = new Vector2((int)Math.Round(cameraTransform.WorldPosition.X / gridSize) * gridSize, (int)Math.Round(cameraTransform.WorldPosition.Y / gridSize) * gridSize);
            for (int x = -2; x <= 2; x++)
            {
                for (int y = -2; y <= 2; y++)
                {
                    SpriteBatchExtensions.DrawCircle(_drawDevice, (gridCenter + new Vector2(x, y) * gridSize) * Settings.GRAPHICS_SCALE, 0.2f * Settings.GRAPHICS_SCALE, 8, RgbaFloat.Red);
                }
            }

            _drawDevice.Draw();

            _imGuiRenderer.Render(_drawDevice.GraphicsDevice, _drawDevice.CommandList);

            _drawDevice.End();

            _window.GraphicsDevice.SwapBuffers(_window.MainSwapchain);
            _window.GraphicsDevice.WaitForIdle();
        }
예제 #8
0
        public static void Client()
        {
            RuffleSocket socket = new RuffleSocket(new Configuration.SocketConfig()
            {
                AllowBroadcasts          = true,
                AllowUnconnectedMessages = true,
                DualListenPort           = 0
            });

            socket.Start();

            // Wait for message. This is to prevent a tight loop
            socket.SyncronizationEvent.WaitOne(1000);

            // Create RNG
            System.Random rnd = new System.Random();
            // Alloc token
            byte[] token = new byte[32];
            // Fill buffer with random data
            rnd.NextBytes(token);

            // Save last send time
            DateTime lastBroadcastSendTime = DateTime.MinValue;

            while (true)
            {
                // If we havent sent broadcast for 5 seconds
                if ((DateTime.Now - lastBroadcastSendTime).TotalSeconds > 5)
                {
                    lastBroadcastSendTime = DateTime.Now;

                    // Send broadcast
                    socket.SendBroadcast(new ArraySegment <byte>(token), 5555);
                }

                // Wait for message. This is to prevent a tight loop
                socket.SyncronizationEvent.WaitOne(1000);

                NetworkEvent @event;
                while ((@event = socket.Poll()).Type != NetworkEventType.Nothing)
                {
                    if (@event.Type == NetworkEventType.UnconnectedData)
                    {
                        // We got a reply. Ensure the token is correct
                        if (@event.Data.Count == token.Length)
                        {
                            bool missMatch = false;

                            // The token had the same length. Check all elements
                            for (int i = 0; i < @event.Data.Count; i++)
                            {
                                if (@event.Data.Array[@event.Data.Offset + i] != token[i])
                                {
                                    // This element did not match. Exit
                                    missMatch = true;
                                    break;
                                }
                            }

                            if (missMatch)
                            {
                                // Continue the receive loop the loop
                                continue;
                            }
                            else
                            {
                                // All matched.
                                Console.WriteLine("Found server at endpoint: " + ((IPEndPoint)@event.EndPoint));
                            }
                        }
                    }

                    // Recycle the event
                    @event.Recycle();
                }
            }
        }
예제 #9
0
        private static void NoRufflesManager()
        {
            RuffleSocket server = new RuffleSocket(ServerConfig);

            RuffleSocket client = new RuffleSocket(ClientConfig);

            // IPv4 Connect
            //client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5674));

            // IPv6 Connect
            client.Connect(new IPEndPoint(IPAddress.Parse("0:0:0:0:0:0:0:1"), 5674));

            // The server stores the clients id here
            ulong clientId = 0;
            // The client stores the servers id here
            ulong serverId = 0;

            // The time when the connection started
            DateTime started = DateTime.Now;

            // The time when the last message was sent
            DateTime lastSent = DateTime.MinValue;

            // The amount of message that has been received
            int messagesReceived = 0;

            // The amount of messages that has been sent
            int messageCounter = 0;

            while (true)
            {
                // Runs all the internals
                client.RunInternalLoop();
                // Runs all the internals
                server.RunInternalLoop();

                // Polls server for events
                NetworkEvent serverEvent = server.Poll();
                // Polls client for events
                NetworkEvent clientEvent = client.Poll();


                if (serverEvent.Type != NetworkEventType.Nothing)
                {
                    if (serverEvent.Type != NetworkEventType.Data)
                    {
                        Console.WriteLine("ServerEvent: " + serverEvent.Type);
                    }

                    if (serverEvent.Type == NetworkEventType.Connect)
                    {
                        clientId = serverEvent.Connection.Id;
                    }

                    if (serverEvent.Type == NetworkEventType.Disconnect || serverEvent.Type == NetworkEventType.Timeout)
                    {
                        serverEvent.Connection.Recycle();
                    }
                }

                if (clientEvent.Type != NetworkEventType.Nothing)
                {
                    if (clientEvent.Type != NetworkEventType.Data)
                    {
                        Console.WriteLine("ClientEvent: " + clientEvent.Type);
                    }

                    if (clientEvent.Type == NetworkEventType.Connect)
                    {
                        serverId = clientEvent.Connection.Id;
                    }

                    if (clientEvent.Type == NetworkEventType.Data)
                    {
                        messagesReceived++;
                        Console.WriteLine("Got message: \"" + Encoding.ASCII.GetString(clientEvent.Data.Array, clientEvent.Data.Offset, clientEvent.Data.Count) + "\"");
                        clientEvent.Recycle();
                    }

                    if (clientEvent.Type == NetworkEventType.Disconnect || clientEvent.Type == NetworkEventType.Timeout)
                    {
                        clientEvent.Connection.Recycle();
                    }
                }

                if ((DateTime.Now - started).TotalSeconds > 10 && (DateTime.Now - lastSent).TotalSeconds >= 1)
                {
                    byte[] helloReliable          = Encoding.ASCII.GetBytes("This message was sent over a reliable channel" + messageCounter);
                    byte[] helloReliableSequenced = Encoding.ASCII.GetBytes("This message was sent over a reliable sequenced channel" + messageCounter);

                    server.Send(new ArraySegment <byte>(helloReliableSequenced, 0, helloReliableSequenced.Length), clientId, 0, false);
                    server.Send(new ArraySegment <byte>(helloReliable, 0, helloReliable.Length), clientId, 1, false);

                    messageCounter++;
                    lastSent = DateTime.Now;
                }
            }
        }