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); }
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(); } }
internal void InvokeBytesReceived(byte[] bytes) { OnBytesReceived?.Invoke(this, bytes); }
/// <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; }