// Receive expected messages and return the elapsed time from first // message to last message. private TimeSpan ReceiveMessages() { Stopwatch sw = new Stopwatch(); AutoResetEvent ev = new AutoResetEvent(false); EventHandler <StanMsgHandlerArgs> msgHandler = (sender, args) => { if (received == 0) { sw.Start(); } received++; if (verbose) { Console.WriteLine("Received seq # {0}", args.Message.Sequence); } if (received >= count) { sw.Stop(); ev.Set(); } }; using (s = CreateSubscriber(c, msgHandler)) { ev.WaitOne(); } return(sw.Elapsed); }
public IStanSubscription SubscribeQueue(string subject, EventHandler <StanMsgHandlerArgs> handler) { if (_options.StanSubscriptionOptions.DurableName != _options.QueueGroup) { throw new QuantQueueGroupNotEqualsException($"DurableName {_options.StanSubscriptionOptions.DurableName} and QueueGroup {_options.QueueGroup} not equals"); } return(_stanSubscription = _stanClient.Subscribe(subject, _options.QueueGroup, handler)); }
private StanObservableSubscription(IStanConnection cn, string subject) { if (cn == null) { throw new ArgumentNullException(nameof(cn)); } subscription = cn.Subscribe(subject, OnIncomingMessage); }
public Program(string[] args) { var clientId = ""; var topic = "sample"; if (args.Length > 1) { topic = args[1]; } if (args.Length > 2) { clientId = args[2]; } var cf = new StanConnectionFactory(); var options = StanOptions.GetDefaultOptions(); options.ConnectTimeout = 1000; options.NatsURL = "nats://*****:*****@localhost:4222"; IStanConnection connection = cf.CreateConnection("test-cluster", clientId, options); if (args.Length > 0 && args[0] == "send") { while (true) { connection.Publish(topic, Encoding.UTF8.GetBytes("Hello NATS " + Guid.NewGuid().ToString())); Console.WriteLine("Message sent to topic: " + topic); Thread.Sleep(500); } } else { var subName = "subscription-1"; if (args.Length > 0) { subName = args[0]; } EventHandler <StanMsgHandlerArgs> eh = (sender, argsMsg) => { var body = Encoding.UTF8.GetString(argsMsg.Message.Data); // TODO: Handle headers in right way Console.WriteLine(body); Thread.Sleep(1000); argsMsg.Message.Ack(); }; var opts = StanSubscriptionOptions.GetDefaultOptions(); opts.DurableName = subName; opts.ManualAcks = true; opts.AckWait = 60000; opts.MaxInflight = 1; IStanSubscription subscription = subscription = connection.Subscribe(topic, subName, opts, eh); } }
private Exception reconnect() { if (_conn != null) { return(null); } // reconnect Exception error = null; lock (_token) { if (_conn != null) { return(null); } // create a new clientID _clientID = string.Format("{0}-{1}", _serviceID, Guid.NewGuid()); // fields var fields = getConnLogFields(); // now create a new connect var opts = StanOptions.GetDefaultOptions(); opts.NatsURL = _serverURL; try { // reset event _publishAbort.Reset(); // reconnect var conn = nats.DefaultFactory.CreateConnection(_clusterID, _clientID, opts); if (conn == null) { throw new ApplicationException(string.Format("nats connection failed, conn==null")); } // save conn _conn = conn; // log info logInfo(fields, "nats connection completed"); // resubscribe all foreach (var item in _subs.Values) { IStanSubscription sub = null; internalSubscribe(item.subject, item.queue, item.options, item.cb, out sub); item.sub = sub; } } catch (Exception ex) { error = ex; } } // return return(error); }
public void Start() { _connection = _connectionProvider.GetConnection(); _cancellationTokenSource = new CancellationTokenSource(); Task.Run(() => { var opts = StanSubscriptionOptions.GetDefaultOptions(); opts.DurableName = $"{_config.Value.NatsConnection.ClientId}.Durable"; _subscription = _connection.Subscribe("PostTechnology.EventBus", opts, MessageReceived); }, _cancellationTokenSource.Token); }
public bool Unsubscribe(string subject) { subject = $"{productID}_{subject}"; IStanSubscription stanSubscription = null; if (dicSubscription.TryRemove(subject, out stanSubscription)) { stanSubscription.Unsubscribe(); return(true); } else { return(false); } }
public Task StartAsync(CancellationToken cancellationToken) { if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation($"Starting hosted service \"{nameof(StanMessageReceiverService)}\"."); } var task = Task.Run(() => { List <Task> tasks = new List <Task>(); Task t; _cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); foreach (var subscription in _messagingEvent.subscriptions) { t = Task.Run(() => { var topic = subscription.Key; var theInstance = (IMessagingEvent)Activator.CreateInstance(_messagingEvent.subscriptions[topic], _serviceProvider); EventHandler <StanMsgHandlerArgs> msgHandler = (sender, args) => { theInstance.Process(args.Message.Data); }; //while (!cancellationToken.IsCancellationRequested) //{ IStanSubscription stanSubscription = _connection.Subscribe(topic, qGroup, sOpts, msgHandler); //} }, cancellationToken); tasks.Add(t); } _tasks = tasks.ToArray(); if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation($"Started hosted service \"{nameof(StanMessageReceiverService)}\"."); } }); return(task.IsCompleted ? Task.CompletedTask : task); }
/// <summary> /// Creates a new subscription /// </summary> /// <param name="subscriptionOptions">The object used to configure the subscription to create</param> /// <param name="persist">A boolean indicating whether or not to persist the subscription to the <see cref="SubscriptionRegistry"/></param> /// <param name="cancellationToken">A <see cref="CancellationToken"/></param> /// <returns>A new awaitable <see cref="Task"/></returns> protected virtual async Task SubscribeAsync(SubscriptionOptionsDto subscriptionOptions, bool persist, CancellationToken cancellationToken = default) { string subject = this.GetStanSubjectFor(subscriptionOptions.Subject); this.Logger.LogInformation("NATSS subject: {subject}", subject); IStanSubscription subscription = this.StanConnection.Subscribe(subject, subscriptionOptions.ToStanSubscriptionOptions(), this.CreateEventHandlerFor(subscriptionOptions.Id)); this.Subscriptions.TryAdd(subscriptionOptions.Id, subscription); if (persist) { lock (this._Lock) { this.SubscriptionRegistry.InsertKey(subscriptionOptions.Id, JsonConvert.SerializeObject(subscriptionOptions), false); } } await Task.CompletedTask; }
public string QueueSubscribe(string subject, string queue, StanSubscriptionOptions options, EventHandler <StanMsgHandlerArgs> cb) { IStanSubscription sub = null; string guid = Guid.NewGuid().ToString(); var error = internalSubscribe(subject, queue, options, cb, out sub); // keep a copy of subscription info _subs[guid] = new SubRecord { subject = subject, queue = queue, options = options, cb = cb, sub = sub, }; if (error != null) { internalClose(); reconnect(); } // return return(guid); }
/// <summary> /// Constructor for generating a StanMsg object. Used only for application unit testing. /// </summary> /// <remarks> /// Objects of this type are normally generated internally by the NATS streaming client. /// This constructor has been provided to facilitate application unit testing. /// </remarks> /// <param name="data">The message payload.</param> /// <param name="redelivered">True if the message may have been redelivered.</param> /// <param name="subject">Subject of the message</param> /// <param name="timestamp">Message timestamp, nanoseconds since epoch (1/1/1970)</param> /// <param name="sequence">Sequence number of the message.</param> /// <param name="subscription">Subscription of the message. Must be a valid streaming subscription or null.</param> public StanMsg(byte[] data, bool redelivered, string subject, long timestamp, ulong sequence, IStanSubscription subscription) { proto = new MsgProto(); proto.Data = Google.Protobuf.ByteString.CopyFrom(data); proto.Redelivered = redelivered; proto.Subject = subject; proto.Sequence = sequence; proto.Timestamp = timestamp; sub = (AsyncSubscription)subscription; }
/// <summary> /// Constructor for generating a StanMsgHandlerArgs object. Used for application unit testing. /// </summary> /// <remarks> /// Objects of this type are normally generated internally by the NATS streaming client. /// This constructor has been provided to facilitate application unit testing. /// </remarks> /// <param name="data">The message payload.</param> /// <param name="redelivered">True if the message may have been redelivered.</param> /// <param name="subject">Subject of the message.</param> /// <param name="timestamp">Message timestamp, nanoseconds since epoch.(1/1/1970)</param> /// <param name="sequence">Sequence number of the message.</param> /// <param name="subscription">Subscription of the message. Must be a valid streaming subscription or null.</param> public StanMsgHandlerArgs(byte[] data, bool redelivered, string subject, long timestamp, ulong sequence, IStanSubscription subscription) { msg = new StanMsg(data, redelivered, subject, timestamp, sequence, subscription); }
private Exception internalSubscribe(string subject, string queue, StanSubscriptionOptions options, EventHandler <StanMsgHandlerArgs> cb, out IStanSubscription sub) { sub = null; var fields = getSubLogFields(subject, queue, options); // check connection first var error = reconnect(); if (error != null) { fields["error"] = error; logWarn(fields, "nats subscription failed at reconnect"); return(error); } // now subscribe try { if (string.IsNullOrEmpty(queue)) { sub = _conn.Subscribe(subject, options, cb); } else { sub = _conn.Subscribe(subject, queue, options, cb); } } catch (Exception ex) { error = ex; } if (error != null) { fields["error"] = error; logWarn(fields, "nats subscription failed"); } else { logInfo(fields, "nats subscription completed"); } // return return(error); }
public IStanSubscription Subscribe(string subject, StanSubscriptionOptions options, EventHandler <StanMsgHandlerArgs> handler) { return(_stanSubscription = _stanClient.Subscribe(subject, options, handler)); }