private IStanConnection Connect(string clusterId, string clientId, StanOptions opts = null) { try { if (String.IsNullOrEmpty(clusterId) || String.IsNullOrEmpty(clientId)) { return(null); } if (stanConnection == null || stanConnection.NATSConnection == null) { if (opts == null) { stanConnection = new StanConnectionFactory().CreateConnection(clusterId, clientId); } else { stanConnection = new StanConnectionFactory().CreateConnection(clusterId, clientId, opts); } } } catch (STAN.Client.StanConnectionException ex) { InternalLogger.Error(ex, $"NATS connection exception."); } catch (STAN.Client.StanConnectRequestTimeoutException ex) { InternalLogger.Error(ex, $"NATS connection request timeout exception."); } return(stanConnection); }
public StanMessageReceiverService( IConfiguration configuration, ILogger <StanMessageReceiverService> logger, MessagingEvent messagingEvent, IServiceProvider serviceProvider) { _configuration = configuration; _logger = logger; _serviceProvider = serviceProvider; _messagingEvent = messagingEvent; var opts = StanOptions.GetDefaultOptions(); opts.NatsURL = _configuration.GetValue <string>("Messaging:Stan:Servers"); string clusterID = _configuration.GetValue <string>("Messaging:Stan:ClusterId"); qGroup = _configuration.GetValue <string>("Messaging:Group"); try { _connection = new StanConnectionFactory().CreateConnection(clusterID, qGroup, opts); } catch (Exception ex) { _logger.LogError(ex, "Error messaging connection"); //throw ex; } }
public void Start() { // connect to STAN var cf = new StanConnectionFactory(); var natsOptions = StanOptions.GetDefaultOptions(); natsOptions.NatsURL = "nats://localhost:4223"; _stanConnection = cf.CreateConnection("test-cluster", "ShippingService", natsOptions); // create events subscription StanSubscriptionOptions stanOptions = StanSubscriptionOptions.GetDefaultOptions(); stanOptions.DurableName = "ShippingService"; // determine where to start reading in the event-stream ulong?lastSeqNr = GetLastSequenceNumber(); if (lastSeqNr != null) { lastSeqNr++; stanOptions.StartAt(lastSeqNr.Value); Console.WriteLine($"Replaying from seq# {lastSeqNr}"); } else { stanOptions.DeliverAllAvailable(); Console.WriteLine("Replaying all messages."); } _stanConnection.Subscribe("store.events", stanOptions, EventReceived); }
private TimeSpan ReceiveAsyncSubscriber(IStanConnection c) { var sw = new Stopwatch(); var ev = new AutoResetEvent(false); EventHandler <StanMsgHandlerArgs> msgHandler = (sender, args) => { if (_received == 0) { sw.Start(); } _received++; if (Verbose) { Console.WriteLine("Received seq # {0}: {1}", args.Message.Sequence, System.Text.Encoding.UTF8.GetString(args.Message.Data)); } if (_received >= Count) { sw.Stop(); ev.Set(); } }; using (var s = c.Subscribe(Subject, _sOpts, msgHandler)) { ev.WaitOne(); } return(sw.Elapsed); }
//--------------------------------------------------------------------- // IStanConnection extensions /// <summary> /// Publish publishes the data argument to the given subject. The data /// argument is left untouched and needs to be correctly interpreted on /// the receiver. This API is synchronous and waits for the acknowledgement /// or error from the NATS streaming server. /// </summary> /// <typeparam name="TMessage">The message type.</typeparam> /// <param name="connection">The conmnection.</param> /// <param name="subject">Subject to publish the message to.</param> /// <param name="data">Message payload.</param> /// <exception cref="StanException">When an error occurs locally or on the NATS streaming server.</exception> public static void Publish <TMessage>(this IStanConnection connection, string subject, TMessage data) where TMessage : class, IRoundtripData, new() { Covenant.Requires <ArgumentNullException>(data != null); connection.Publish(subject, data.ToBytes()); }
/// <summary> /// Publish publishes the data argument to the given subject. The data /// argument is left untouched and needs to be correctly interpreted on /// the receiver. This API is asynchronous and handles the acknowledgement /// or error from the NATS streaming server in the provided handler. An exception is thrown when /// an error occurs during the send, the handler will process acknowledgments and errors. /// </summary> /// <typeparam name="TMessage">The message type.</typeparam> /// <param name="connection">The conmnection.</param> /// <param name="subject">Subject to publish the message to.</param> /// <param name="data"></param> /// <returns>The task object representing the asynchronous operation, containing the guid.</returns> public static async Task <string> PublishAsync <TMessage>(this IStanConnection connection, string subject, TMessage data) where TMessage : class, IRoundtripData, new() { Covenant.Requires <ArgumentNullException>(data != null); return(await connection.PublishAsync(subject, data.ToBytes())); }
public async Task StartAsync(string consumerId) { StanOptions options = StanOptions.GetDefaultOptions(); options.NatsURL = _natsOptions.Url; var stanSubOptions = StanSubscriptionOptions.GetDefaultOptions(); stanSubOptions.DurableName = _natsOptions.DurableName; _stanConnection = new StanConnectionFactory() .CreateConnection(_natsOptions.ClusterId, consumerId, options); try { _stanConnection .Subscribe(_natsOptions.Subject, stanSubOptions, (obj, args) => { string messageData = Encoding.UTF8.GetString(args.Message.Data); Console.WriteLine($"[#{args.Message.Sequence}] {messageData}"); var message = JsonSerializer.Deserialize <Message>(messageData); message.Number = args.Message.Sequence; _messageRepository.AddAsync(message).GetAwaiter().GetResult(); }); } catch (Exception e) { _logger.LogError($"Ошибка подписки на сообщения: {e.ToString()}"); CloseConnection(); } await Task.CompletedTask; }
/// <summary> /// Publish publishes the data argument to the given subject. The data /// argument is left untouched and needs to be correctly interpreted on /// the receiver. This API is asynchronous and handles the acknowledgement /// or error from the NATS streaming server in the provided handler. An exception is thrown when /// an error occurs during the send, the handler will process acknowledgments and errors. /// </summary> /// <typeparam name="TMessage">The message type.</typeparam> /// <param name="connection">The conmnection.</param> /// <param name="subject">Subject to publish the message to.</param> /// <param name="data">Message payload.</param> /// <param name="handler">Event handler to process message acknowledgements.</param> /// <returns>The GUID of the published message.</returns> /// <exception cref="StanException">Thrown when an error occurs publishing the message.</exception> public static string Publish <TMessage>(this IStanConnection connection, string subject, TMessage data, EventHandler <StanAckHandlerArgs> handler) where TMessage : class, IRoundtripData, new() { Covenant.Requires <ArgumentNullException>(data != null); return(connection.Publish(subject, data.ToBytes(), handler)); }
internal void ProcessMsgs(string url, string clusterID) { IStanConnection sc = null; try { sc = CreateConnection(url, clusterID, "synadia-rel-sub"); var opts = StanSubscriptionOptions.GetDefaultOptions(); opts.AckWait = 60000; opts.ManualAcks = true; opts.MaxInflight = 32; opts.DurableName = "synadia-restest"; sc.Subscribe("synadia.restest", "qg", opts, ProcessMsg); FeV.WaitOne(); } catch (Exception e) { Log("Create Subscriber failed: " + e); } finally { sc?.Close(); } Log("Subscriber is finished."); }
static void TestSTAN(IStanConnection conn) { Task.Run(async() => { var i = 0; while (true) { try { string guid = conn.Publish("stest", UTF8Encoding.UTF8.GetBytes(i.ToString()), null); await Task.Delay(1000); i++; } catch (Exception err) { Console.WriteLine(err); } } }); var sOpts = StanSubscriptionOptions.GetDefaultOptions(); sOpts.AckWait = 60000; var s = conn.Subscribe("stest", sOpts, (obj, msgArs) => { Console.WriteLine(UTF8Encoding.UTF8.GetString(msgArs.Message.Data)); }); }
internal void SendMessages(string url, string clusterID) { IStanConnection sc = null; sc = CreateConnection(url, clusterID, "synadia-rel-publisher"); for (int i = 0; !IsFinished(); i++) { try { sc.Publish("synadia.restest", payload, (obj, args) => { /* NOOP */ }); // sync publish for long running stability // sc.Publish("synadia.restest", payload); ; } catch (Exception e) { Log("Publish Exception: " + e.Message); Thread.Sleep(250); } if (i % 500 == 0) { Log("Publisher Sent {0} messages to the streaming server.", i); PrintResourceStats(); } } sc?.Close(); Log("Publisher is finished."); }
// Convenience method to create a queue or standard subscriber private IStanSubscription CreateSubscriber(IStanConnection c, EventHandler <StanMsgHandlerArgs> msgHandler) { if (qGroup != null) { return(c.Subscribe(subject, qGroup, sOpts, msgHandler)); } return(c.Subscribe(subject, sOpts, msgHandler)); }
private StanObservableSubscription(IStanConnection cn, string subject) { if (cn == null) { throw new ArgumentNullException(nameof(cn)); } subscription = cn.Subscribe(subject, OnIncomingMessage); }
/// <summary> /// Subscribe will create an Asynchronous Subscriber with /// interest in a given subject, assign the handler, and immediately /// start receiving messages. /// </summary> /// <typeparam name="TMessage">The message type.</typeparam> /// <param name="connection">The conmnection.</param> /// <param name="subject">Subject of interest.</param> /// <param name="qgroup">Name of the queue group.</param> /// <param name="options">SubscriptionOptions used to create the subscriber.</param> /// <param name="handler">A message handler to process messages.</param> /// <returns>A new subscription.</returns> public static IStanSubscription Subscribe <TMessage>(this IStanConnection connection, string subject, string qgroup, StanSubscriptionOptions options, EventHandler <StanMsgHandlerArgs <TMessage> > handler) where TMessage : class, IRoundtripData, new() { return(connection.Subscribe(subject, qgroup, options, (sender, args) => { handler?.Invoke(sender, args.Message.ToHandler <TMessage>()); })); }
void InitStanClient() { var stanConnectionFactory = new StanConnectionFactory(); _stanClient = stanConnectionFactory.CreateConnection(_options.ClusterId, _options.ClientId, _stanOptions); _stanSubscriptionOptions = StanSubscriptionOptions.GetDefaultOptions(); _stanSubscriptionOptions.DurableName = _options.StanSubscriptionOptions.DurableName; }
public Test_NatsStreamingFixture(NatsStreamingFixture fixture) { if (fixture.Start() == TestFixtureStatus.AlreadyRunning) { fixture.Restart(); } this.fixture = fixture; this.connection = fixture.Connection; }
/// <summary> /// This method completely resets the fixture by removing and recreating /// the NATS-STREAMING container. /// </summary> public override void Reset() { if (Connection != null) { Connection.Dispose(); Connection = null; } base.Reset(); }
/// <summary> /// Establishes the server connection. /// </summary> private void Connect() { var factory = new StanConnectionFactory(); var retry = new LinearRetryPolicy(exception => true, 20, TimeSpan.FromSeconds(0.5)); retry.Invoke( () => { Connection = factory.CreateConnection("test-cluster", nameof(NatsStreamingFixture)); }); }
public Test_NatsStreamingFixture(NatsStreamingFixture fixture) { TestHelper.ResetDocker(this.GetType()); if (fixture.Start() == TestFixtureStatus.AlreadyRunning) { fixture.Restart(); } this.fixture = fixture; this.connection = fixture.Connection; }
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); } }
/// <summary> /// Initializes a new <see cref="EventChannel"/> /// </summary> /// <param name="logger">The service used to perform logging</param> /// <param name="stanConnection">The underlying NATS Streaming connection</param> /// <param name="httpClientFactory">The service used to create new <see cref="System.Net.Http.HttpClient"/> instances</param> public EventChannel(ILogger <EventChannel> logger, IStanConnection stanConnection, IHttpClientFactory httpClientFactory) { this.Logger = logger; this.StanConnection = stanConnection; this.EventFormatter = new JsonEventFormatter(); this.HttpClient = httpClientFactory.CreateClient(typeof(EventChannel).Name); this.SubscriptionRegistry = new HashFile(); this.SubscriptionRegistry.Initialize(Path.Combine(AppContext.BaseDirectory, "sub"), 128, (ushort)JsonConvert.SerializeObject(new SubscriptionOptionsDto() { Id = StringExtensions.GenerateRandomString(128), Subject = StringExtensions.GenerateRandomString(128), DurableName = StringExtensions.GenerateRandomString(128), StreamPosition = 999999 }).Length); this.Subscriptions = new ConcurrentDictionary <string, IStanSubscription>(); }
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); }
IStanConnection getConnection() { IStanConnection conn = null; try { conn = StanConnectionFactory.CreateConnection(clusterID, clientID, cOpts); } catch (Exception ex) { NLog.LogManager.GetCurrentClassLogger().Warn(ex, "Creat nats connection fail!"); } return(conn); }
/// <summary> /// Restarts the NATS container to clear any previous state and returns the /// new client connection. /// </summary> /// <returns>The new connection.</returns> public new IStanConnection Restart() { base.Restart(); if (Connection != null) { Connection.Dispose(); Connection = null; } Connect(); return(Connection); }
public void Setup(string appname) { var cf = new StanConnectionFactory(); _connection = cf.CreateConnection("test-cluster", appname); _connection.NATSConnection.Opts.DisconnectedEventHandler += (sender, args) => { OnDisconnected?.Invoke(this, new OnDisconnectedHandlerArgs(args.Conn.State)); }; _connection.NATSConnection.Opts.ClosedEventHandler += (sender, args) => { OnClosed?.Invoke(this, new OnClosedHandlerArgs(args.Conn.State)); }; }
public NATSOrderRepository() { try { var cf = new StanConnectionFactory(); var options = StanOptions.GetDefaultOptions(); options.NatsURL = "nats://localhost:4223"; _stanConnection = cf.CreateConnection("test-cluster", CLIENTID, options); var subOptions = StanSubscriptionOptions.GetDefaultOptions(); subOptions.DeliverAllAvailable(); _stanConnection.Subscribe(EVENTSTREAM_SUBJECT, subOptions, (obj, args) => { try { string message = Encoding.UTF8.GetString(args.Message.Data); string[] messageParts = message.Split('#'); string eventTypeDescriptor = $"Store.OrderProcessingService.Domain.Events.{messageParts[0]}"; Type eventType = Type.GetType(eventTypeDescriptor); string eventData = message.Substring(message.IndexOf('#') + 1); dynamic e = JsonSerializer.Deserialize(eventData, eventType); if (_eventStreams.ContainsKey(e.OrderNumber)) { _eventStreams[e.OrderNumber].Add(e); } else { _eventStreams.Add(e.OrderNumber, new List <BusinessEvent>() { e }); Console.WriteLine($"Order #{e.OrderNumber} found during replay."); } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } }); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } }
public NatsTarget(string natsUrl, string natsClusterId, string natsClientId, int natsConnectionTimeout = 10000, int natsPubAckWait = 5000) { cache = new ConcurrentDictionary <string, IpObj>(); this.NatsUrl = natsUrl; this.NatsClusterId = natsClusterId; this.NatsClientId = natsClientId; this.NatsConnectionTimeout = natsConnectionTimeout; this.NatsPubAckWait = natsPubAckWait; opts.NatsURL = this.NatsUrl; opts.ConnectionLostEventHandler = (obj, args) => { InternalLogger.Error($"NATS connection lost. {args.ConnectionException}"); }; stanConnection = Connect(this.NatsClusterId, this.NatsClientId, opts); }
public StanMessageSenderService( IConfiguration configuration, ILogger <StanMessageSenderService> logger) { _configuration = configuration; _logger = logger; cOpts.NatsURL = _configuration.GetValue <string>("Messaging:Stan:Servers"); string clusterID = _configuration.GetValue <string>("Messaging:Stan:ClusterId"); //if testing for local loop send error, 'coz clientID already used when listen string clientID = _configuration.GetValue <string>("Messaging:Group"); // string clientID = "TEST"; _connection = new StanConnectionFactory().CreateConnection(clusterID, clientID, cOpts); }
private static IStanConnection Connect(string clusterId, string clientId, StanOptions opts = null) { int connectionRetryCounter = 0; int connectionRetryMax = 3; while (connectionRetryMax > 0 && stanConnection == null) { try { if (stanConnection == null || stanConnection.NATSConnection == null) { if (opts == null) { stanConnection = new StanConnectionFactory().CreateConnection(clusterId, clientId); } else { stanConnection = new StanConnectionFactory().CreateConnection(clusterId, clientId, opts); } } } catch (STAN.Client.StanConnectionException ex) { connectionRetryMax--; Console.WriteLine($"NATS connection exception. {ex}"); Thread.Sleep(1000 * connectionRetryCounter); } catch (STAN.Client.StanConnectRequestTimeoutException ex) { connectionRetryMax--; Console.WriteLine($"NATS connection request timeout exception. {ex}"); Thread.Sleep(1000 * connectionRetryCounter); } catch (STAN.Client.StanConnectRequestException ex) { connectionRetryMax--; Console.WriteLine($"NATS connection request exception. {ex}"); Thread.Sleep(1000 * connectionRetryCounter); } connectionRetryCounter++; } return(stanConnection); }
public void Start() { _repo = new SQLServerOrderRepository(); // connect to NATS var natsConnectionFactory = new ConnectionFactory(); _natsConnection = natsConnectionFactory.CreateConnection("nats://localhost:4222"); // connect to STAN var cf = new StanConnectionFactory(); var options = StanOptions.GetDefaultOptions(); options.NatsURL = "nats://localhost:4223"; _stanConnection = cf.CreateConnection("test-cluster", "OrderProcessingService", options); // create commands subscription _commandsSubscription = _natsConnection.SubscribeAsync("store.commands.*", CommandReceived); }