private void OnConnectionReceived(PeerConnection connection) { var peerId = Interlocked.Increment(ref _peerIdGenerator); var peer = new GcPeer(peerId, connection); _peersByConnectionId.TryAdd(connection.ConnectionId, peer); _peers.TryAdd(peerId, peer); PeerJoined?.Invoke(peer); }
private async Task HandleEstablishPeer(GcMessage message) { var peerId = message.Reader.ReadInt32(); var isDirectMessage = peerId < 0; GcPeer peer = null; if (isDirectMessage) { // This is a direct message from client // who can't know his peer id peerId = message.Peer.PeerId; peer = message.Peer; } else { // This is a message that was already relayed at least once // We need to create a virtual peer which will be used in this server var vPeer = new GcPeer(Interlocked.Increment(ref _peerIdGenerator), message.Peer); _peers.TryAdd(vPeer.PeerId, vPeer); PeerJoined?.Invoke(vPeer); // Add the newly created peer id peerId = vPeer.PeerId; peer = vPeer; } // Send messages to all of the relayed servers to establish a peer in them var connections = _relayConnections.Values.Distinct().Where(c => c.IsConnected); var allSuccessful = true; // Do it "linearly" (one by one) because it's a lot easier to handle foreach (var connection in connections) { var response = await connection.SendRequest((short)InternalOpCodes.EstablishPeer, w => w.Write(peerId)); if (response.Status != ResponseStatus.Success) { _logger.LogWarning("Failed to establish a peer in connection: " + connection); allSuccessful = false; continue; } var assignedPeerId = response.Reader.ReadInt32(); // For forwarding messages peer.SetPeerIdInRelayedServer(assignedPeerId, connection); // For "backwarding" messages connection.SaveRelayedPeer(assignedPeerId, peer); } if (isDirectMessage) { message.Respond(allSuccessful ? ResponseStatus.Success : ResponseStatus.Failed); } else { message.Respond(ResponseStatus.Success, w => w.Write(peerId)); } }