public void SendBasicMessage(short opCode, Action <NetWriter> writeAction, int?requestId, int?responseId, ResponseStatus?status, byte defaultFlags = 0) { if (_isDisconnected) { return; } byte[] data; if (!IsVirtual) { lock (_writer) { GcProtocol.PackMessage(_writer, opCode, writeAction, requestId, responseId, status, null, defaultFlags); data = _writer.ToArray(); } _connection.SendRawData(data); } else { lock (_writer) { GcProtocol.PackMessage(_writer, opCode, writeAction, requestId, responseId, status, PeerId, defaultFlags); data = _writer.ToArray(); } _concretePeer.SendRawData(data); } }
private void SendBasicMessage(short opCode, Action <NetWriter> writeAction, int?requestId, int?responseId, ResponseStatus?status, int?peerId, byte defaultFlags = 0) { byte[] data; lock (_writer) { GcProtocol.PackMessage(_writer, opCode, writeAction, requestId, responseId, status, peerId, defaultFlags); data = _writer.ToArray(); } Implementation.SendRawData(data); }
private void OnDataReceived(byte[] data) { // Ignore empty data if (data.Length == 0) { return; } // Ignore intercepted data if (_interceptionHandler != null && _interceptionHandler(data)) { return; } var flags = data[0]; if ((flags & MessageFlags.InternalMessage) > 0) { HandleInternalMessage(data); return; } var msg = GcProtocol.ParseMessage(null, data); // TODO Try catch if (msg.ResponseId >= 0) { // In case it's a response to a message TaskCompletionSource <GcMessage> source; _responseCallbacks.TryRemove(msg.ResponseId, out source); source?.TrySetResult(msg); return; } // TODO Handle a regular message throw new NotImplementedException("Regular message not yet handled"); }
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); } }