Пример #1
0
        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");
        }
Пример #4
0
        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);
            }
        }