static async Task TryWebSockets() { // Establish a TCP connection with the STOMP service. using (ClientWebSocket webSocket = new ClientWebSocket()) { await webSocket.ConnectAsync(new Uri("ws://52.137.87.113:15674/ws"), CancellationToken.None); //Create a connector. using (IStompConnector stompConnector = new Stomp12Connector( new WebSocketTransport(webSocket), "WebChannel", "", "")) { // Create a connection. IStompConnection connection = await stompConnector.ConnectAsync(); // Send a message. await connection.SendAsync("/queue/example4", "Anybody there!?"); await connection.SubscribeAsync( new ConsoleWriterObserver(), "/queue/example4"); // Wait for messages to be received. await Task.Delay(250); // Disconnect. await connection.DisconnectAsync(); } } }
/// <summary> /// This example will demonstrate the thread-safety of IStompConnector /// </summary> /// <returns></returns> public static async Task ExampleConnectorConcurrent() { using (TcpClient tcpClient = new TcpClient(serverHostname, serverPort)) using (IStompConnector stompConnector = new Stomp12Connector(tcpClient.GetStream(), virtualHost, login, passcode)) { IStompConnection connection = await stompConnector.ConnectAsync(); // Create threads to send messages. ICollection <Thread> threads = new Collection <Thread>(); for (int i = 0; i < 10; i++) { Thread t = new Thread( async() => { for (int j = 0; j < 100; j++) { await connection.SendAsync(aQueueName, messageContent); } }); threads.Add(t); } // Start threads foreach (Thread t in threads) { t.Start(); } // Subscribe IDisposable subscription = await connection.SubscribeAsync( new CounterObserver(), // An observer that count messages and print the count on completed. aQueueName, StompAckValues.AckClientIndividualValue); // Messages must be acked before the broker discards them. Console.WriteLine("Please wait a few seconds..."); Console.WriteLine(); // Wait for the threads to finish. foreach (Thread t in threads) { t.Join(); } // Wait for a little longer for messages to arrive. await Task.Delay(3000); // Unsubscribe. // After this invocation, observers's OnCompleted is going to be called. // For this example, a count of 1000 should be shown unless there was // previous data in the queue. subscription.Dispose(); // Disconnect. await connection.DisconnectAsync(); } }
/// <summary> /// Example used in the README.md file. /// </summary> static async Task ReadmeExample() { // Establish a TCP connection with the STOMP service. using (TcpClient tcpClient = new TcpClient()) { await tcpClient.ConnectAsync("localhost", 61613); //Create a connector. using (IStompConnector stompConnector = new Stomp12Connector( tcpClient.GetStream(), "localhost", // Virtual host name. "admin", "password")) { // Create a connection. IStompConnection connection = await stompConnector.ConnectAsync(); // Send a message. await connection.SendAsync("/queue/example", "Anybody there!?"); // Send two messages using a transaction. IStompTransaction transaction = await connection.BeginTransactionAsync(); await transaction.SendAsync("/queue/example", "Hi!"); await transaction.SendAsync("/queue/example", "My name is StompNet"); await transaction.CommitAsync(); // Receive messages back. // Message handling is made by the ConsoleWriterObserver instance. await transaction.SubscribeAsync( new ConsoleWriterObserver(), "/queue/example"); // Wait for messages to be received. await Task.Delay(250); // Disconnect. await connection.DisconnectAsync(); } } }
static async Task ReadmeExample() { // Establish a TCP connection with the STOMP service. using (TcpClient tcpClient = new TcpClient()) { await tcpClient.ConnectAsync("", 15674); //Create a connector. using (IStompConnector stompConnector = new Stomp12Connector( tcpClient.GetStream(), "WebChannel", "", "")) { // Create a connection. IStompConnection connection = await stompConnector.ConnectAsync(); // Send a message. await connection.SendAsync("/queue/example", "Anybody there!?"); // Send two messages using a transaction. IStompTransaction transaction = await connection.BeginTransactionAsync(); await transaction.SendAsync("/queue/example", "Hi!"); await transaction.SendAsync("/queue/example", "My name is StompNet"); await transaction.CommitAsync(); await transaction.SubscribeAsync( new ConsoleWriterObserver(), "/queue/example"); // Wait for messages to be received. await Task.Delay(250); // Disconnect. await connection.DisconnectAsync(); } } }
/// <summary> /// Example to demonstrate STOMP transactions using the StompNet high level API. /// /// BEWARE: APACHE APOLLO DOES NOT HANDLE VERY MELL TRANSACTION WITH RECEIPT CONFIRMATIONS. /// </summary> public static async Task ExampleConnectorTransaction() { using (TcpClient tcpClient = new TcpClient(serverHostname, serverPort)) using (IStompConnector stompConnector = new Stomp12Connector(tcpClient.GetStream(), virtualHost, login, passcode)) { IStompConnection connection = await stompConnector.ConnectAsync(); // // TRANSACTION 1 // This transaction send two messages to a queue. // Console.WriteLine("TRANSACTION #1"); IStompTransaction tr1 = await connection.BeginTransactionAsync(); await tr1.SendAsync(aQueueName, messageContent + " #1"); await tr1.SendAsync(aQueueName, messageContent + " #2"); await tr1.CommitAsync(); Console.WriteLine("Messages sent to queue: " + aQueueName + "."); Console.WriteLine(); // // TRANSACTION 2 // Transactionally receive messages from a queue and send rhem to another queue. // Console.WriteLine("TRANSACTION #2"); IAsyncDisposable sub2 = await connection.SubscribeAsync( new TransactionalObserver(connection, "#2"), //The transaction is done inside the observer. aQueueName, StompAckValues.AckClientIndividualValue, true); // Wait some time for the messages to be received and processed. await Task.Delay(500); await sub2.DisposeAsync(); Console.WriteLine("Messages processed from " + aQueueName + " and sent to queue " + anotherQueueName + "."); Console.WriteLine(); // // TRANSACTION 3 // Transactionally receive messages from another queue and send them back to the original queue. // At the last moment, ABORT. // Console.WriteLine("TRANSACTION #3"); IStompTransaction tr3 = await connection.BeginTransactionAsync(); // Creating a subscription from a transaction guarantees that acknowledgements will make part // of the transaction. IAsyncDisposable sub3 = await tr3.SubscribeAsync( new ProcessorObserver("#3", tr3), //All processing inside the observer is automatically made part of the transaction. anotherQueueName, StompAckValues.AckClientIndividualValue); // Wait some time for the messages to be received and processed. await Task.Delay(500); // In transaction cases, subscription SHOULD be disposed before finishing the transaction. // Otherwise, messages will keep being received and new (transacted) acknowledgements will // be unknown for the message broker and may cause errors. await sub3.DisposeAsync(); //Abort. await tr3.AbortAsync(); Console.WriteLine("Nothing should have happened because this transaction was aborted."); Console.WriteLine(); // // TRANSACTION 4 // Transactionally receive messages from another queue and send them back to the original queue. // At the last moment, COMMIT. // Console.WriteLine("TRANSACTION #4"); IStompTransaction tr4 = await connection.BeginTransactionAsync(); IAsyncDisposable sub4 = await tr4.SubscribeAsync( new ProcessorObserver("#4", tr4), //All processing inside the observer is automatically made part of the transaction. anotherQueueName, StompAckValues.AckClientIndividualValue); // Wait some time for the messages to be received and processed. await Task.Delay(500); // In transaction cases, subscription SHOULD be disposed before finishing the transaction. // Otherwise, messages will keep being received and new (transacted) acknowledgements will // be unknown for the message broker and may cause errors. await sub4.DisposeAsync(); // Commit. await tr4.CommitAsync(); Console.WriteLine("Messages processed from " + anotherQueueName + " and sent to queue " + aQueueName + "."); Console.WriteLine(); // // QUEUE DUMP // Transactionally receive messages from another queue and send them back to the original queue. // At the last moment, COMMIT. // Console.WriteLine("QUEUE " + aQueueName.ToUpper() + " DUMP"); Console.WriteLine("Show the messages in their final destination."); Console.WriteLine(); IAsyncDisposable sub5 = await connection.SubscribeAsync( new ExampleObserver("QUEUE " + aQueueName + " DUMP"), aQueueName, StompAckValues.AckClientIndividualValue); await Task.Delay(500); await sub4.DisposeAsync(); // Disconnect. await connection.DisconnectAsync(); } }
public TransactionalObserver(IStompConnection connection, string name) { _connection = connection; _name = name; }
/// <summary> /// This example shows the basic usage of the high level API of the library. /// /// Four messages are going to be sent to a queue and they will be read from the same queue. /// /// High level API features. /// - High level interfaces to ease the flow of the application: IStompConnector, /// IStompConnection, IStompMessage, IStompTransaction and IObserver<IStompMessage>. /// - Built upon an observer pattern. It can be used for reactive application approaches. /// - Message receipt confirmations and sequence number generation for frames are /// automatically handled by the library. /// - Thread-safety. /// - You would rarely have to interact with STOMP frames directly. /// /// </summary> public static async Task ExampleConnector() { //A connection to the TCP server socket is created. using (TcpClient tcpClient = new TcpClient(serverHostname, serverPort)) // IStompConnector is an IDisposable. A Stomp12Connector parametrized using the constructor. // Stomp12Connector receives as parameters: a stream, the name of the virtual host, // a username (optional) and a password (optional). // Stomp12Connector may also receive a parameter 'retryTimeout' (TimeSpan, by default: 30 seconds) // which is the time before a command is re-send if it does not receive a response. using (IStompConnector stompConnector = new Stomp12Connector(tcpClient.GetStream(), virtualHost, login, passcode)) { //Connect to the STOMP service. IStompConnection connection = await stompConnector.ConnectAsync(heartbeat : new Heartbeat(30000, 30000)); // Send a couple of messages with string content. for (int i = 1; i <= 2; i++) { await connection.SendAsync( aQueueName, // Queue/Topic to send messages to. messageContent + " #" + i, // The message content. String (by default UTF-8 encoding is used). false, // Optional - Does a receipt confirmation is used in SEND command?. Default: false. null, // Optional - Collection of key-value pairs to include as non-standard headers. CancellationToken.None); // Optional - A CancellationToken. } // Subscribe to receive messages. // Calling 'SubscribeAsync' returns an IDisposable which can be called to unsubscribe. // It is not mandatory to dispose the subscription manually. It will be disposed when // the stompConnector is disposed or if an exception in the stream occurs. IDisposable subscription = await connection.SubscribeAsync( new ExampleObserver(), // An observer. A class implementing IObserver<IStompMessage>. aQueueName, // Queue/Topic to observe from. StompAckValues.AckAutoValue, // Optional - Ack mode: "auto", "client", "client-individual". Default: "auto". false, // Optional - Does a receipt confirmation is used in SUBSCRIBE command?. Default: false. null, // Optional - Collection of key-value pairs to include as non-standard headers. CancellationToken.None); // Optional - A CancellationToken. // Messages with byte content can also be send. byte[] aByteMessageContent = new byte [] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // Send two more messages using SendAsync byte version. for (int i = 0; i < 2; i++) { await connection.SendAsync( aQueueName, // Queue/Topic to send messages to. aByteMessageContent, // The message content. MediaTypeNames.Application.Octet, // Message content type. true, // Optional - Does a receipt confirmation is used in SEND command?. Default: false. // In this case, a confirmation receipt will be awaited before the task is completed. null, // Optional - Collection of key-value pairs to include as non-standard headers. CancellationToken.None); // Optional - A CancellationToken. } // Wait some time for the messages to be received. await Task.Delay(500); // Unsubscribe. subscription.Dispose(); // Disconnect. await connection.DisconnectAsync(); } }
/// <summary> /// This is another example of the basic usage of the high level API of the library. /// /// Multiple messages are going to be sent to a topic and a queue. After that, /// multiple observers will receive the messages. /// </summary> /// <returns></returns> public static async Task ExampleConnectorAnother() { using (TcpClient tcpClient = new TcpClient(serverHostname, serverPort)) using (IStompConnector stompConnector = new Stomp12Connector(tcpClient.GetStream(), virtualHost, login, passcode)) { IStompConnection connection = await stompConnector.ConnectAsync(); // // QUEUE CASE // Console.WriteLine("TWO OBSERVERS ON A QUEUE"); Console.WriteLine("------------------------"); Console.WriteLine(); // Subscribe two observers to one queue. await connection.SubscribeAsync(new ExampleObserver("QUEUE OBSERVER 1"), aQueueName, StompAckValues.AckClientIndividualValue, true); await connection.SubscribeAsync(new ExampleObserver("QUEUE OBSERVER 2"), aQueueName, StompAckValues.AckClientIndividualValue, true); // Send three messages. for (int i = 1; i <= 3; i++) { // As you see the receipt flag is true, so SendAsync will wait for a receipt confirmation. await connection.SendAsync(aQueueName, messageContent + " #" + i, true); } // Wait some time for the messages to be received. await Task.Delay(500); // // TOPIC CASE // Console.WriteLine("TWO OBSERVERS ON A TOPIC"); Console.WriteLine("------------------------"); Console.WriteLine(); // Subscribe two observers to one topic. await connection.SubscribeAsync(new ExampleObserver("TOPIC OBSERVER 1"), aTopicName, StompAckValues.AckClientIndividualValue, true); await connection.SubscribeAsync(new ExampleObserver("TOPIC OBSERVER 2"), aTopicName, StompAckValues.AckClientIndividualValue, true); // Send three messages. As you see the receipt flag is true. for (int i = 1; i <= 3; i++) { // As you see the receipt flag is true, so SendAsync will wait for a receipt confirmation. await connection.SendAsync(aTopicName, messageContent + " #" + i, true); } // Wait some time for the messages to be received. await Task.Delay(500); // Disconnect. await connection.DisconnectAsync(); } // This delay is for console output formatting purposes. // It makes sure the OnCompleted methods of the observers are invoked before // showing the main menu again. In other words, when this is removed, completion // messages of the observer may appear after the main menu has been showed. await Task.Delay(500); }