private void ReceiveCallBack(IAsyncResult Asr)
        {
            if (_udpClient == null)
            {
                return;
            }
            byte[] dat = null;
            try
            {
                dat = _udpClient.EndReceive(Asr, ref _receivedEp);
            }
            catch (SocketException ex)
            {
                return;
            }
            catch (ObjectDisposedException ex)
            {
                return;
            }

            OnBytesReceived?.Invoke(dat);

            if (OnBytesReceived == null)
            {
                // store the data if callback is not set
                _mutex.WaitOne();
                _receivedPackets.AddLast(dat);
                _mutex.ReleaseMutex();
            }


            // 今一度非同期受信を開始
            _udpClient.BeginReceive(ReceiveCallBack, this);
        }
Example #2
0
        private async Task StartHandlingClientRequestAsync()
        {
            while (_disposeToken.IsCancellationRequested == false)
            {
                _log.Info(() => LogEvent.Create("FAKE Server: Accepting clients."));
                _client = await _listener.AcceptTcpClientAsync();

                _log.Info(() => LogEvent.Create("FAKE Server: Connected client"));
                OnClientConnected?.Invoke();
                _semaphoreSlim.Release();

                try {
                    using (_client) {
                        var buffer = new byte[4096];
                        var stream = _client.GetStream();

                        while (!_disposeToken.IsCancellationRequested)
                        {
                            var bytesReceived = await stream.ReadAsync(buffer, 0, buffer.Length, _disposeToken.Token);

                            if (bytesReceived > 0)
                            {
                                OnBytesReceived?.Invoke(buffer.Take(bytesReceived).ToArray());
                            }
                        }
                    }
                } catch (Exception ex) {
                    _log.Error(LogEvent.Create(ex, "FAKE Server: Client exception..."));
                }

                _log.Error(LogEvent.Create("FAKE Server: Client Disconnected."));
                await _semaphoreSlim.WaitAsync(); //remove the one client

                OnClientDisconnected?.Invoke();
            }
        }
Example #3
0
 public void Start( OnConnectionReceived onConnection, OnBytesReceived onBytes )
 {
     Running = true;
     OnConnection = onConnection;
     OnBytes = onBytes;
     Scheduler.Start();
     Listeners = Configuration
         .Endpoints
         .Select( endpoint =>
         {
             var socket = ListenerFactory.CreateListener( Scheduler, endpoint, Configuration );
             socket.ListenTo( OnSocket );
             return socket;
         })
         .ToList();
 }
Example #4
0
 internal void InvokeBytesReceived(byte[] bytes)
 {
     OnBytesReceived?.Invoke(this, bytes);
 }
Example #5
0
 public SocketHandle( ISocket socket, IScheduler scheduler, OnBytesReceived onBytes )
 {
     OnBytes = onBytes;
     Connection = socket;
     Scheduler = scheduler;
 }
Example #6
0
        /// <summary>
        /// Sends a byte array to several recipient peers
        /// </summary>
        /// <param name="recipients">A list of the recipient peer IDs</param>
        /// <param name="bytes">The byte array to send</param>
        /// <param name="reliable">Whether data is sent UDP/TCP style</param>
        public void SendRaw
            (List <short> recipients, byte[] bytes, bool reliable = false)
        {
            if (recipients == null || recipients.Count == 0)
            {
                recipients = new List <short> {
                    1
                }
            }
            ;

            var message = new Message {
                sender     = ID,
                recipients = recipients.ToArray(),
                bytes      = bytes
            };
            var bytesToSend = message.Serialize();

            // If we're a client, we only send to the server.
            // The server will pass on the message to clients in recipient list
            if (CurrentMode == Mode.Client)
            {
                network.SendData(
                    id: serverCID,
                    data: bytesToSend,
                    offset: 0,
                    len: bytesToSend.Length,
                    reliable: reliable
                    );
            }
            // If we're the server, we send to all the recipients
            else if (CurrentMode == Mode.Server)
            {
                foreach (var recipient in recipients)
                {
                    if (recipient != ID)
                    {
                        network.SendData(
                            id: new ConnectionId(recipient),
                            data: bytesToSend,
                            offset: 0,
                            len: bytesToSend.Length,
                            reliable: reliable
                            );
                    }
                }
            }
        }

        // ================================================
        // NETWORK HANDLERS
        // ================================================
        void Network_OnServerStartSuccess(NetworkEvent e)
        {
            ID          = 0; // server ID is 0
            CurrentMode = Mode.Server;
            Address     = tmpAddress;
            OnServerStartSuccess?.Invoke();
            OnReceiveID?.Invoke(ID);
        }

        void Network_OnServerStartFailure(NetworkEvent e)
        {
            Reset();
            OnServerStartFailure?.Invoke(
                new Exception(e.GetDataAsString() + e.Info)
                );
        }

        // This is called only on the server, not on the client side
        void Network_OnServerStopped(NetworkEvent e)
        {
            // Using a reserved packet tag,
            // we let all the clients know that we have closed the server
            if (CurrentMode == Mode.Server)
            {
                SendPacket(
                    Peers,
                    new Packet().WithTag(Packet.ReservedTags.ServerClosed),
                    true
                    );
                Reset();
                OnServerStop?.Invoke();
            }
        }

        void Network_OnNewConnection(NetworkEvent e)
        {
            if (CurrentMode == Mode.Server)
            {
                var theNewID = e.ConnectionId.id;

                // Notify a new client of its ID is using a reserved tag packet
                var tag    = Packet.ReservedTags.ClientSetID;
                var packet = new Packet().With(tag, theNewID.GetBytes());
                SendPacket(theNewID, packet, true);

                // Using reserved tag packets, let the new client know about
                // all the old clients and the old clients about the new client
                foreach (var anOldID in Peers)
                {
                    tag    = Packet.ReservedTags.ClientJoined;
                    packet = new Packet().With(tag, anOldID.GetBytes());
                    SendPacket(theNewID, packet, true);

                    tag    = Packet.ReservedTags.ClientJoined;
                    packet = new Packet().With(tag, theNewID.GetBytes());
                    SendPacket(anOldID, packet, true);
                }

                Peers.Add(theNewID);
                OnClientJoined?.Invoke(theNewID);
            }
            else if (CurrentMode == Mode.Idle)
            {
                serverCID   = e.ConnectionId;
                CurrentMode = Mode.Client;
                // Add the server as a peer. To the client, server ID is 0
                Peers.Add(0);
                Address = tmpAddress;
                OnConnected?.Invoke();
            }
        }

        void Network_OnConnectionFailed(NetworkEvent e)
        {
            Reset();
            var ex = new Exception(e.GetDataAsString() + e.Info);

            OnConnectionFailed?.Invoke(ex);
        }

        void Network_OnDisconnection(NetworkEvent e)
        {
            if (CurrentMode == Mode.Server)
            {
                Peers.Remove(e.ConnectionId.id);

                // Using a reserved tag, we let all the other clients know
                // that a client has left
                var tag    = Packet.ReservedTags.ClientLeft;
                var packet = new Packet().WithTag(tag)
                             .WithPayload(e.ConnectionId.id.GetBytes());
                SendPacket(Peers, packet, true);

                OnClientLeft?.Invoke(e.ConnectionId.id);
            }
            else if (CurrentMode == Mode.Client)
            {
                Reset();
                OnDisconnected?.Invoke();
            }
        }

        void Network_OnMessageReceived(NetworkEvent e, bool reliable)
        {
            var data = e.GetDataAsByteArray();

            var message = Message.Deserialize(data);
            var packet  = Packet.Deserialize(message.bytes);

            // Try to look for reserved keywords
            if (packet != null && packet.Tag.StartsWith("reserved"))
            {
                switch (packet.Tag)
                {
                case Packet.ReservedTags.ClientJoined:
                    if (CurrentMode == Mode.Client)
                    {
                        var cid = packet.Payload.ToShort();
                        Peers.Add(cid);
                        OnClientJoined?.Invoke(cid);
                    }
                    break;

                case Packet.ReservedTags.ClientLeft:
                    if (CurrentMode == Mode.Client)
                    {
                        var cid = packet.Payload.ToShort();
                        Peers.Remove(cid);
                        OnClientLeft?.Invoke(cid);
                    }
                    break;

                case Packet.ReservedTags.ClientSetID:
                    if (CurrentMode == Mode.Client)
                    {
                        ID = packet.Payload.ToShort();
                        OnReceiveID?.Invoke(ID);
                    }
                    break;

                case Packet.ReservedTags.ServerClosed:
                    Reset();
                    OnRemoteServerClosed?.Invoke();
                    break;
                }
                return;
            }

            // If we were an intended recipient
            if (message.recipients.Contains(ID))
            {
                if (packet != null)
                {
                    OnPacketReceived?.Invoke(message.sender, packet);
                }
                else
                {
                    OnBytesReceived?.Invoke(message.sender, message.bytes);
                }
            }

            // If we're a server, forward the message to the intended
            // recipients, except ourselves
            if (CurrentMode == Mode.Server)
            {
                foreach (var recipient in message.recipients)
                {
                    if (recipient != 0)
                    {
                        if (packet == null)
                        {
                            packet = new Packet();
                            packet.WithPayload(message.bytes);
                        }
                        var m = new Message {
                            sender     = message.sender,
                            recipients = new short[] { recipient },
                            bytes      = packet.Serialize()
                        };
                        network.SendData(
                            id: new ConnectionId(recipient),
                            data: m.Serialize(),
                            offset: 0,
                            len: m.Serialize().Length,
                            reliable: reliable
                            );
                    }
                }
            }
        }

        void Reset()
        {
            ID          = -1;
            CurrentMode = Mode.Idle;
            foreach (var peer in Peers)
            {
                OnClientLeft?.Invoke(peer);
            }
            Peers.Clear();
            Address = null;
        }