public void ToArray_with_xml_body() { const string someXml = "<message>hello world</message>"; byte[] payload = Encoding.UTF8.GetBytes(someXml); MemoryStream body = new MemoryStream(payload); var frame = new StompFrame { Command = "SEND", Headers = new StompHeaderCollection { {"content-type", "application/xml; encoding=UTF8"}, }, Body = body, }; var bytes = frame.ToArray(); var text = new StreamReader(new MemoryStream(bytes), Encoding.UTF8).ReadToEnd(); string expectedText = "SEND\r\n" + "content-type:application/xml; encoding=UTF8\r\n" + "content-length:" + payload.Length + "\r\n\r\n" + someXml + "\0"; Assert.AreEqual(expectedText, text); }
public void ToArray_with_empty_body() { var frame = new StompFrame { Command = "CONNECT", Headers = new StompHeaderCollection { {"login", "scott"}, {"passcode", "tiger"}, }, Body = null, }; var bytes = frame.ToArray(); var text = new StreamReader(new MemoryStream(bytes), Encoding.UTF8).ReadToEnd(); const string expectedText = "CONNECT\r\nlogin:scott\r\npasscode:tiger\r\ncontent-length:0\r\n\r\n\0"; Assert.AreEqual(expectedText, text); }
public void Subscribe() { using (_lock.Lock()) { if (State == StompSubscriptionState.Unsubscribed) { var message = new StompFrame(StompCommand.Subscribe) { Headers = { {StompHeader.Id, _subscriptionIdText}, {StompHeader.Destination, Destination}, {StompHeader.Ack, Ack}, } }; _lock.AfterUnlock(RaiseStateChanged); State = StompSubscriptionState.Subscribing; Client.SendRawMessage(message, true); } } }
public void Receive_small_frame_in_one_receive() { const string payloadText = "<message>This is a message</message>"; byte[] payloadBytes = Encoding.UTF8.GetBytes(payloadText); MemoryStream memoryStream = new MemoryStream(payloadBytes); var originalFrame = new StompFrame { Command = "SEND", Headers = { {"destination", "/queue/a"}, {"transaction", "tx-112"}, }, Body = memoryStream, }; byte[] data = originalFrame.ToArray(); var builder = new StompFrameBuilder(); builder.ReceiveBytes(data, 0, data.Length); Assert.IsTrue(builder.IsFrameReady, "Unexpected result"); var receivedFrame = builder.GetNextFrame(); Assert.IsNotNull(receivedFrame); Assert.IsNull(builder.GetNextFrame()); Assert.AreEqual(originalFrame.Command, receivedFrame.Command); Assert.AreEqual(originalFrame.Headers["destination"], receivedFrame.Headers["destination"]); Assert.AreEqual(originalFrame.Headers["transaction"], receivedFrame.Headers["transaction"]); Assert.AreEqual(originalFrame.Headers["content-length"], receivedFrame.Headers["content-length"]); Assert.AreEqual(originalFrame.Headers.Count, receivedFrame.Headers.Count); Assert.AreEqual(payloadBytes.Length, receivedFrame.Body.Length); string receivedText = Encoding.UTF8.GetString(receivedFrame.Body.ToArray()); Assert.AreEqual(payloadText, receivedText); }
public StompMessageEventArgs(StompFrame message) { Message = Verify.ArgumentNotNull(message, "message"); }
public void Dispose() { using (_lock.Lock()) { var oldState = State; if (!IsDisposed()) { State = StompSubscriptionState.Disposed; _lock.AfterUnlock(RaiseStateChanged); if (oldState == StompSubscriptionState.Subscribing || oldState == StompSubscriptionState.Subscribed) { var message = new StompFrame(StompCommand.Unsubscribe) { Headers = { {StompHeader.Id, _subscriptionIdText} } }; Client.SendRawMessage(message, false); } } } MessageArrived = null; StateChanged = null; }
private void CheckConnected() { using (Lock.Lock()) { if (!_isDisposed) { if (_connected) { if (_transport == null || !_transport.Connected) { _connected = false; Log.Debug("Client is now disconnected from server"); Lock.AfterUnlock(() => OnConnectedChanged(EventArgs.Empty)); } StopOutgoingHeartBeatTimer(); StopIncomingHeartBeatTimer(); StopConnectTimer(); } else { if (_transport != null && _transport.Connected && !_waitingForConnectedFrame) { var login = Login ?? string.Empty; var passcode = Passcode ?? string.Empty; // the client id provides some help with diagnostics by identifying the client process var processName = Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().MainModule.FileName); var clientId = Environment.MachineName + "/" + processName + "/" + Process.GetCurrentProcess().Id; _sentHeartBeatValues = new HeartBeatValues(OutgoingHeartBeat, IncomingHeartBeat); // time to send a CONNECT message var frame = new StompFrame { Command = StompCommand.Connect, Headers = { {StompHeader.Login, login}, {StompHeader.Passcode, passcode}, {StompHeader.HeartBeat, _sentHeartBeatValues.ToString()}, {StompHeader.NonStandard.ClientId, clientId} } }; // a little enhancement, if we are re-connecting a previous session, // include the session id so that we can resume if (_sessionId != null) { frame.Headers[StompHeader.Session] = _sessionId; } _waitingForConnectedFrame = true; StartConnectTimer(); _transport.SendFrame(frame); Log.Debug("Sent " + frame.Command + " command to server"); } } } } }
public void Missing_header_results_in_null_value() { var message = new StompFrame(); Assert.IsNull(message.Headers["missing-header"]); }
public void ToString_with_xml_body() { var frame = new StompFrame { Command = "MESSAGE", Headers = new StompHeaderCollection { {"subscription", "1"}, {"content-length", "123"}, {"content-type", "application/xml"}, {"clr-type", "Test.Type,Test"}, {"message-id", "6"}, }, Body = new MemoryStream(), }; var writer = new StreamWriter(frame.Body); writer.WriteLine("<?xml version='1.0'>"); writer.WriteLine("<Test>"); writer.WriteLine(" <Name>This is the name</Name>"); writer.WriteLine("</Test>"); writer.Flush(); frame.Headers["content-length"] = frame.Body.Length.ToString(CultureInfo.InvariantCulture); var actual = frame.ToString(); const string expected = "MESSAGE message-id:6 subscription:1 content-length:74 clr-type:Test.Type,Test " + "<?xml version='1.0'> <Test> <Name>This is the name</Name> </Test>"; Assert.AreEqual(expected, actual); }
public void Expires_header() { var frame = new StompFrame(); var dateTime = new DateTimeOffset(2099, 11, 10, 19, 18, 17, 16, TimeSpan.FromHours(10)); frame.SetExpires(dateTime); Assert.AreEqual("20991110T091817Z", frame.Headers[StompHeader.NonStandard.Expires]); // truncated milliseconds means not expired Assert.IsFalse(frame.IsExpiredAt(dateTime - TimeSpan.FromSeconds(1))); Assert.IsTrue(frame.IsExpiredAt(dateTime + TimeSpan.FromSeconds(1))); }
public void Cannot_deserialize_without_content_type() { var s1 = new SerializeTestClass { Number = 123, Text = "This is some text" }; var frame = new StompFrame(); frame.Serialize(s1); frame.Headers[StompHeader.ContentType] = "text/plain"; try { frame.Deserialize(); Assert.Fail("Expected exception"); } catch (InvalidOperationException ex) { Assert.AreEqual("Cannot deserialize: content-type:text/plain", ex.Message); } }
public void Header_value_contains_colon() { var originalFrame = new StompFrame { Command = "SEND", Headers = { {"destination", "queue://this-contains:three:colons"}, }, }; byte[] data = originalFrame.ToArray(); var builder = new StompFrameBuilder(); builder.ReceiveBytes(data, 0, data.Length); var receivedFrame = builder.GetNextFrame(); Assert.IsNotNull(receivedFrame); Assert.AreEqual(originalFrame.Headers["destination"], receivedFrame.Headers["destination"]); Assert.AreEqual("queue://this-contains:three:colons", receivedFrame.Headers["destination"]); }
private void AssignSessionAndResubscribe(StompFrame frame) { var oldSessionId = _sessionId; _sessionId = frame.Headers[StompHeader.Session]; if (oldSessionId != _sessionId && _subscriptions.Count > 0) { // This is where we had an old session, but lost it. The most probable // cause is that the server was stopped and restarted. What we do here // is re-send our subscription information. foreach (var subscription in _subscriptions.Values) { Log.DebugFormat("Resubscribing subscription {0}: {1}", subscription.SubscriptionId, subscription.Destination); subscription.Subscribe(); } } }
private void HandleReceipt(StompFrame message) { var receiptIdText = message.Headers[StompHeader.ReceiptId]; if (Log.IsDebugEnabled) { Log.DebugFormat("{0} received, {1}={2}", message.Command, StompHeader.ReceiptId, receiptIdText); } if (receiptIdText == null) { // TODO: what do we do here, disconnect? Log.ErrorFormat("Missing {0} header in {1} command", StompHeader.ReceiptId, message.Command); _transport.Shutdown(); return; } long receiptId; if (!long.TryParse(receiptIdText, out receiptId)) { // TODO: what to we do here, disconnect? Log.ErrorFormat("Invalid value for {0} header: {1}", StompHeader.ReceiptId, receiptIdText); _transport.Shutdown(); return; } if (_pendingSendMessages.Count == 0) { Log.ErrorFormat("Received RECEIPT {0} but nothing asked for it", receiptId); _transport.Shutdown(); return; } var sentMessage = _pendingSendMessages.Peek(); var idText = sentMessage.Headers[StompHeader.Receipt]; if (idText == null) { Log.ErrorFormat("Received RECEIPT {0} but nothing asked for it (and there is a message queued)", receiptId); _transport.Shutdown(); return; } // the current implementation never sends more than one message requiring receipt without receiving a receipt var id = long.Parse(sentMessage.Headers[StompHeader.Receipt]); if (id != receiptId) { Log.ErrorFormat("Received RECEIPT {0} but expected RECEIPT {1}", id, receiptId); _transport.Shutdown(); } _pendingSendMessages.Dequeue(); _sendInProgress = false; if (sentMessage.Command == StompCommand.Subscribe) { int subscriptionId = int.Parse(sentMessage.Headers[StompHeader.Id]); StompSubscription subscription; if (_subscriptions.TryGetValue(subscriptionId, out subscription)) { subscription.Confirm(); } } SendNextMessage(); }
private void HandleError(StompFrame message) { var messageText = message.Headers[StompHeader.Message]; if (messageText.StartsWith(ErrorMessages.SessionDoesNotExistPrefix) && !_connected) { // We have tried to reconnect to our old session, but it no longer exists, so remove it. Log.Info("Server says our session no longer exists. Will ask for a new one"); _sessionId = null; foreach (var subscription in _subscriptions.Values) { subscription.SubscriptionLost(); } } }
private StompSubscription HandleMessage(StompFrame message) { var subscriptionIdText = message.Headers[StompHeader.Subscription]; if (subscriptionIdText == null) { Log.WarnFormat("Received {0} message without a {1} header", message.Command, StompHeader.Subscription); return null; } int subscriptionId; if (!int.TryParse(subscriptionIdText, out subscriptionId)) { Log.WarnFormat("Received {0} message with invalid {1}: {2}", message.Command, StompHeader.Subscription, subscriptionIdText); return null; } StompSubscription subscription; if (!_subscriptions.TryGetValue(subscriptionId, out subscription)) { Log.WarnFormat("Receive {0} message with unknown {1}: {2}", message.Command, StompHeader.Subscription, subscriptionId); return null; } return subscription; }
private void HandleConnected(StompFrame frame) { AssignSessionAndResubscribe(frame); StopConnectTimer(); _connected = true; _waitingForConnectedFrame = false; Log.DebugFormat("Received {0} response, {1}={2}", frame.Command, StompHeader.Session, _sessionId); var serverHeartBeatValues = new HeartBeatValues(frame.Headers[StompHeader.HeartBeat]); _negotiatedHeartBeatValues = _sentHeartBeatValues.CombineWith(serverHeartBeatValues); StartIncomingHeartBeatTimer(); StartOutgoingHeartBeatTimer(); SendNextMessage(); }
public void BodyText_tests() { var frame = new StompFrame { Command = "COMMAND", BodyText = "1", }; Assert.AreEqual("1", frame.BodyText); }
public void Serialize() { var s1 = new SerializeTestClass { Number = 123, Text = "This is some text" }; var frame = new StompFrame(); frame.Serialize(s1); var s2 = (SerializeTestClass)frame.Deserialize(); Assert.IsNotNull(s2); Assert.AreEqual(s1.Number, s2.Number); Assert.AreEqual(s1.Text, s2.Text); }
public void Receive_two_frames_in_one_receive() { const string payloadText = "<message>This is a message</message>"; byte[] payloadBytes = Encoding.UTF8.GetBytes(payloadText); MemoryStream memoryStream = new MemoryStream(payloadBytes); var originalFrame = new StompFrame { Command = "SEND", Headers = { {"destination", "/queue/a"}, {"transaction", "tx-112"}, }, Body = memoryStream, }; byte[] data1 = originalFrame.ToArray(); originalFrame.Headers["destination"] = "/queue/b"; originalFrame.Headers["transaction"] = "tx-113"; byte[] data2 = originalFrame.ToArray(); byte[] combinedData = new byte[data1.Length + data2.Length]; Array.Copy(data1, combinedData, data1.Length); Array.Copy(data2, 0, combinedData, data1.Length, data2.Length); var builder = new StompFrameBuilder(); builder.ReceiveBytes(combinedData, 0, combinedData.Length); Assert.IsTrue(builder.IsFrameReady); var receivedFrame1 = builder.GetNextFrame(); Assert.IsNotNull(receivedFrame1); var receivedFrame2 = builder.GetNextFrame(); Assert.IsNotNull(receivedFrame2); Assert.IsNull(builder.GetNextFrame()); Assert.AreEqual(originalFrame.Command, receivedFrame1.Command); Assert.AreEqual("/queue/a", receivedFrame1.Headers["destination"]); Assert.AreEqual("tx-112", receivedFrame1.Headers["transaction"]); Assert.AreEqual(originalFrame.Headers.Count, receivedFrame1.Headers.Count); Assert.AreEqual(payloadBytes.Length, receivedFrame1.Body.Length); Assert.AreEqual(payloadText, Encoding.UTF8.GetString(receivedFrame1.Body.ToArray())); Assert.AreEqual(originalFrame.Command, receivedFrame2.Command); Assert.AreEqual("/queue/b", receivedFrame2.Headers["destination"]); Assert.AreEqual("tx-113", receivedFrame2.Headers["transaction"]); Assert.AreEqual(originalFrame.Headers.Count, receivedFrame2.Headers.Count); Assert.AreEqual(payloadBytes.Length, receivedFrame2.Body.Length); Assert.AreEqual(payloadText, Encoding.UTF8.GetString(receivedFrame2.Body.ToArray())); }
public void Cannot_deserialize_without_clr_type() { var s1 = new SerializeTestClass { Number = 123, Text = "This is some text" }; var frame = new StompFrame(); frame.Serialize(s1); frame.Headers[StompHeader.NonStandard.ClrType] = null; try { frame.Deserialize(); Assert.Fail("Expected exception"); } catch (InvalidOperationException ex) { Assert.AreEqual("Cannot deserialize: no clr-type specified", ex.Message); } }
internal void ReceiveMessage(StompFrame message) { using (_lock.Lock()) { if (IsDisposed()) { // Silently discard messages received after being disposed. // By not acknowledging them, they will not be discarded by the server return; } var messageId = message.Headers[StompHeader.MessageId]; if (messageId == null) { Log.Warn("Received message from server without a " + StompHeader.MessageId + " header"); } else { if (Ack != StompAck.Auto) { var ackMessage = new StompFrame(StompCommand.Ack) { Headers = { {StompHeader.Subscription, _subscriptionIdText}, {StompHeader.MessageId, messageId}, } }; Client.SendRawMessage(ackMessage, false); } } } RaiseMessageArrived(message); }
public void KeepAlive_frame() { var frame = new StompFrame(string.Empty); Assert.IsTrue(frame.IsHeartBeat); frame.Command = null; Assert.IsTrue(frame.IsHeartBeat); frame.Command = "XXX"; Assert.IsFalse(frame.IsHeartBeat); }
public void SendMessage(StompFrame message) { Verify.ArgumentNotNull(message, "message"); CheckDisposed(); if (message.Command == null) { message.Command = StompCommand.Send; } else if (message.Command != StompCommand.Send) { throw new InvalidOperationException("Only " + StompCommand.Send + " commmands permitted"); } if (message.Headers[StompHeader.Destination] == null) { throw new InvalidOperationException(("Header mising: " + StompHeader.Destination)); } SendRawMessage(message, false); }
public void ToString_with_large_text_body() { var frame = new StompFrame { Command = "MESSAGE", Headers = new StompHeaderCollection { {"subscription", "1"}, {"content-length", "123"}, {"content-type", "text/plain"}, {"message-id", "6"}, }, Body = new MemoryStream(), }; var writer = new StreamWriter(frame.Body); writer.WriteLine("12345678901234567890123456789012345678901234567890"); writer.WriteLine("12345678901234567890123456789012345678901234567890"); writer.WriteLine("12345678901234567890123456789012345678901234567890"); writer.WriteLine("12345678901234567890123456789012345678901234567890"); writer.WriteLine("12345678901234567890123456789012345678901234567890"); writer.WriteLine("12345678901234567890123456789012345678901234567890"); writer.WriteLine("12345678901234567890123456789012345678901234567890"); writer.WriteLine("12345678901234567890123456789012345678901234567890"); writer.WriteLine("12345678901234567890123456789012345678901234567890"); writer.WriteLine("12345678901234567890123456789012345678901234567890"); writer.Flush(); frame.Headers["content-length"] = frame.Body.Length.ToString(CultureInfo.InvariantCulture); var actual = frame.ToString(); const string expected = "MESSAGE message-id:6 subscription:1 content-length:520 " + "12345678901234567890123456789012345678901234567890 " + "12345678901234567890123456789012345678901234567890 " + "12345678901234567890123456789012345678901234567890 " + "12345678901234567890123456789012345678901234567890 " + "12345678901234567890123456789012345678901234567890 " + "12345678901234567890123456789012345678901234567890 " + "12345678901234567890123456789012345678901234..."; Assert.AreEqual(expected, actual); }
internal void SendRawMessage(StompFrame message, bool receiptRequired) { using (Lock.Lock()) { if (!_isDisposed) { if (receiptRequired) { _receiptId += 1; message.Headers[StompHeader.Receipt] = _receiptId.ToString(); } _pendingSendMessages.Enqueue(message); SendNextMessage(); } } }
private void RaiseMessageArrived(StompFrame frame) { if (MessageArrived != null) { var args = new StompMessageEventArgs(frame); var synchronizationContext = SynchronizationContext; if (synchronizationContext == null) { MessageArrived(this, args); } else { SendOrPostCallback callback = (obj => MessageArrived(this, args)); synchronizationContext.Send(callback, null); } } }
public void SendTextMessage(string destination, string text) { Verify.ArgumentNotNull(destination, "destination"); Verify.ArgumentNotNull(text, "text"); CheckDisposed(); var frame = new StompFrame(StompCommand.Send) { Headers = { {StompHeader.Destination, destination}, {StompHeader.ContentType, "text/plain"} }, BodyText = text }; SendRawMessage(frame, false); }
public void Null_command_results_in_heartbeat() { var data = new StompFrame { Command = null }.ToArray(); Assert.AreEqual(1, data.Length); Assert.AreEqual(10, data[0]); }
void ClientConnectedChanged(object sender, EventArgs e) { if (_clientTransport.Connected) { Log.Debug("Client: connected to server"); const string text = "1"; var frame = new StompFrame { Command = StompCommand.Message, BodyText = text, }; _clientTransport.SendFrame(frame); Log.Debug("Client: sent message: " + text); } else { Log.Debug("Client: disconnected from server"); } }