private void OnConnectionLost(PeerConnection connection) { _peersByConnectionId.TryRemove(connection.ConnectionId, out var peer); if (peer == null) { return; } _peers.TryRemove(peer.PeerId, out var removedPeer); peer.OnDisconnected(); PeerLeft?.Invoke(peer); }
private void OnRawDataReceived(PeerConnection sender, byte[] data) { // If the message is empty - ignore if (data.Length < 0) { return; } try { var flags = data[0]; if ((flags & MessageFlags.InternalMessage) > 0) { HandleInternalMessage(sender, data); return; } // 1. Get the peer GcPeer peer = null; if ((flags & MessageFlags.PaddedPeerId) > 0) { // There's a peer id within a message, which means that this message // was relayed from somewhere, and we need to use an "indirect" peer var peerId = EndianBitConverter.Little.ToInt32(data, 3); if (peerId <= 0) { // This was just an empty padding, ignore it, use a direct peer _peersByConnectionId.TryGetValue(sender.ConnectionId, out peer); } else { // Get a peer with provided peer id _peers.TryGetValue(peerId, out peer); } } else { _peersByConnectionId.TryGetValue(sender.ConnectionId, out peer); } // Received a message from connection which has no direct peer object if (peer == null) { _logger.LogWarning("Received a message from a source which doesn't have a peer"); return; } // 2. Handle relaying of messages if (_relayConnections.Count != 0) { var opCode = EndianBitConverter.Little.ToInt16(data, 1); GcConnection connectionToRelay; _relayConnections.TryGetValue(opCode, out connectionToRelay); // If connection to relay for this opcode exists, it means a message // needs to be relayed if (connectionToRelay != null) { // Write relayed peer id into the messages peerId padding var relayedId = peer.GetPeerIdInRelayedServer(connectionToRelay); // Ignore if peer doesn't have an established peer id if (relayedId < 0) { return; } // TODO Do this only if there's a peerId padding, otherwise - reconstruct the whole thing // Add a peer id EndianBitConverter.Little.CopyBytes(relayedId, data, 3); // Pass the data connectionToRelay.Implementation.SendRawData(data); return; } } // 3. Generate the message object var message = GcProtocol.ParseMessage(peer, data); HandleMessage(message); } catch (Exception e) { _logger.LogError("Exception while handling received data", e); } }
/// <summary> /// Override if you want a fine-control of how to handle the messages /// </summary> /// <param name="sender"></param> /// <param name="data"></param> protected virtual void HandleInternalMessage(PeerConnection sender, byte[] data) { }