protected void StartTopicMonitoring()
        {
            lock (_lock)
            {
                if (!this._isActivated)
                {
                    var taskFactory = new TaskFactory(_cancellationTokenSource.Token);
                    this._isActivated = true;
                    var cancellationToken = _cancellationTokenSource.Token;

                    _task = taskFactory.StartNew(async(_) =>
                    {
                        _sharedSymKeyId             = await _whisperRpc.RegisterSymKeyAsync(_sharedKey);
                        string messageFilter        = await _whisperRpc.CreateMessageFilterAsync(topicHex: _sessionTopic, symKeyId: _sharedSymKeyId);
                        var messageHandlerResolver  = _messageHandlerResolverBuilder.Build();
                        this._producerConsumerQueue = new ProducerConsumerQueue(messageHandlerResolver, cancellationToken);

                        do
                        {
                            var messages = await _transportClient.GetSessionMessagesAsync(messageFilter);

                            if (messages != null &&
                                messages.Count != 0)
                            {
                                foreach (var message in messages)
                                {
                                    if (!_signService.VerifySign(message.Payload, message.Signature,
                                                                 _counterPartyPubSigningKey))
                                    {
                                        continue;
                                    }

                                    _producerConsumerQueue.Enqueue(message.Message);
                                }

                                continue;
                            }

                            //Poll whisper each 5 sec for new messages
                            await Task.Delay(5000, cancellationToken);
                        } while (!cancellationToken.IsCancellationRequested);
                    }, cancellationToken, TaskCreationOptions.LongRunning);
                }
                else
                {
                    throw new Exception("Session was already started");
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Run listener which would process incoming messages.
        /// </summary>
        /// <param name="messageHandler">Handler which authorizes originator's Vasp and processes Transfer Request and Transfer Dispatch Messages</param>
        public void RunListener(IVaspMessageHandler messageHandler)
        {
            lock (_lock)
            {
                if (!_hasStartedListening)
                {
                    _hasStartedListening = true;
                    var token       = _cancellationTokenSource.Token;
                    var taskFactory = new TaskFactory(_cancellationTokenSource.Token);

                    this._listener = taskFactory.StartNew(async(_) =>
                    {
                        var privateKeyId     = await _whisperRpc.RegisterKeyPairAsync(this._handshakeKey.PrivateKey);
                        string messageFilter =
                            await _whisperRpc.CreateMessageFilterAsync(topicHex: _vaspContractInfo.VaspCode.Code,
                                                                       privateKeyId);

                        do
                        {
                            var sessionRequestMessages = await _transportClient.GetSessionMessagesAsync(messageFilter);

                            if (sessionRequestMessages != null &&
                                sessionRequestMessages.Count != 0)
                            {
                                foreach (var message in sessionRequestMessages)
                                {
                                    var sessionRequestMessage = message.Message as SessionRequestMessage;

                                    if (sessionRequestMessage == null)
                                    {
                                        continue;
                                    }

                                    var isAuthorized =
                                        await messageHandler.AuthorizeSessionRequestAsync(sessionRequestMessage.VASP);

                                    if (!isAuthorized)
                                    {
                                        continue;
                                    }

                                    var originatorVaspContractInfo =
                                        await _ethereumRpc.GetVaspContractInfoAync(sessionRequestMessage.VASP
                                                                                   .VaspIdentity);

                                    if (!_signService.VerifySign(message.Payload, message.Signature,
                                                                 originatorVaspContractInfo.SigningKey))
                                    {
                                        continue;
                                    }

                                    var sharedSecret =
                                        this._handshakeKey.GenerateSharedSecretHex(sessionRequestMessage.HandShake
                                                                                   .EcdhPubKey);

                                    var session = new BeneficiarySession(
                                        originatorVaspContractInfo,
                                        this.VaspInfo,
                                        sessionRequestMessage.Message.SessionId,
                                        sessionRequestMessage.HandShake.TopicA,
                                        originatorVaspContractInfo.SigningKey,
                                        sharedSecret,
                                        this._signatureKey,
                                        this._whisperRpc,
                                        messageHandler,
                                        _transportClient,
                                        _signService);

                                    this.NotifySessionCreated(session);
                                    session.OnSessionTermination += this.ProcessSessionTermination;
                                    if (_beneficiarySessionsDict.TryAdd(session.SessionId, session))
                                    {
                                        await session.StartAsync();
                                    }
                                    else
                                    {
                                        await session.TerminateAsync(TerminationMessage.TerminationMessageCode
                                                                     .SessionClosedTransferDeclinedByBeneficiaryVasp);
                                    }
                                }

                                continue;
                            }

                            await Task.Delay(5000, token);
                        } while (!token.IsCancellationRequested);
                    }, token, TaskCreationOptions.LongRunning);
                }
                else
                {
                    throw new Exception("You can start observation only once.");
                }
            }
        }