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"); } } }
/// <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."); } } }