├── StompNet
├── Helpers
│ ├── MediaTypeNames.cs
│ ├── ISequenceNumberGenerator.cs
│ ├── SequenceNumberGenerator.cs
│ ├── ActionDisposable.cs
│ ├── RandomSequenceNumberGenerator.cs
│ ├── AsyncActionDisposable.cs
│ ├── ObservableExtensions.cs
│ ├── ITaskExecuter.cs
│ ├── ActionObserver.cs
│ ├── EnumerableExtensions.cs
│ └── SerialTaskExecuter.cs
├── StompNet.csproj
├── Exceptions
│ └── ErrorFrameException.cs
├── Models
│ ├── Frames
│ │ ├── ReceiptFrame.cs
│ │ ├── Heartbeat.cs
│ │ ├── ErrorFrame.cs
│ │ ├── ConnectedFrame.cs
│ │ ├── MessageFrame.cs
│ │ └── Frame.cs
│ ├── StompAckValues.cs
│ ├── StompHeaders.cs
│ ├── StompCommands.cs
│ ├── StompInterpreter.cs
│ └── StompOctets.cs
├── IO
│ ├── IStompClient.cs
│ ├── IStompFrameObservable.cs
│ ├── IStompFrameReader.cs
│ ├── IStompFrameWriter.cs
│ ├── StompSerialFrameWriter.cs
│ ├── StompSerialFrameReader.cs
│ ├── Stomp12Client.cs
│ ├── StompFrameObservable.cs
│ ├── StompClient.cs
│ ├── Stomp12FrameWriter.cs
│ ├── StompFrameWriterWithConfirmation.cs
│ ├── AsyncStreamWriter.cs
│ └── AsyncStreamReader.cs
├── IStompConnector.cs
├── IAsyncDisposable.cs
├── StompTransaction.cs
├── StompConnection.cs
├── IStompConnection.cs
├── IStompTransaction.cs
├── StompMessage.cs
├── IStompMessage.cs
├── StompSubscription.cs
├── StompConnectionBase.cs
├── Stomp12Connector.cs
└── IStompConnectionBase.cs
├── StompNet.Tests
├── Helpers
│ ├── MemoryStreamExtensions.cs
│ └── NoEndChunkedMemoryStream.cs
├── Properties
│ └── AssemblyInfo.cs
└── StompNet.Tests.csproj
├── StompNet.Examples
├── Properties
│ └── AssemblyInfo.cs
├── StompNet.Examples.csproj
├── 0.ReadmeExample.cs
├── 3.ExampleConnectorConcurrent.cs
├── Program.cs
├── 5.ExampleClient.cs
├── 2.ExampleConnectorAnother.cs
└── 6.ExampleWriterAndReader.cs
├── StompNet.sln
├── .gitattributes
├── .gitignore
├── README.md
└── LICENSE.txt
/StompNet/Helpers/MediaTypeNames.cs:
--------------------------------------------------------------------------------
1 | namespace StompNet.Helpers
2 | {
3 | internal static class MediaTypeNames
4 | {
5 | public const string ApplicationOctet = "application/octet-stream";
6 | public const string TextPlain = "text/plain";
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/StompNet.Tests/Helpers/MemoryStreamExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Text;
3 |
4 | namespace StompNet.Tests.Helpers
5 | {
6 | internal static class MemoryStreamExtensions
7 | {
8 | public static void Write(this MemoryStream stream, string str)
9 | {
10 | foreach (byte b in Encoding.UTF8.GetBytes(str))
11 | {
12 | stream.WriteByte(b);
13 | }
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/StompNet/StompNet.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net45;netstandard15
5 |
6 |
7 |
8 | 1.0.1.0
9 | Asynchronous STOMP 1.2 client library for .NET.
10 | Carlos Campo
11 | Copyright © Carlos Campo 2020
12 |
13 |
14 | Carlos Campo
15 | stomp;nms;activemq;message broker client
16 | https://github.com/krlito/StompNet
17 | https://github.com/krlito/StompNet
18 | LICENSE.txt
19 | true
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/StompNet/Helpers/ISequenceNumberGenerator.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | namespace StompNet.Helpers
20 | {
21 | ///
22 | /// Interface for sequence number generator.
23 | ///
24 | internal interface ISequenceNumberGenerator
25 | {
26 | ///
27 | /// Returns the next number in the sequence.
28 | ///
29 | /// The next number in the sequence
30 | int Next();
31 | }
32 | }
--------------------------------------------------------------------------------
/StompNet/Helpers/SequenceNumberGenerator.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using System.Threading;
21 |
22 | namespace StompNet.Helpers
23 | {
24 | ///
25 | /// Sequence number generator starting at 1.
26 | ///
27 | /// This class is thread-safe.
28 | ///
29 | internal class SequenceNumberGenerator : ISequenceNumberGenerator
30 | {
31 | private int _count = 0;
32 |
33 | public int Next()
34 | {
35 | return Interlocked.Increment(ref _count);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/StompNet.Tests/Helpers/NoEndChunkedMemoryStream.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 |
6 | namespace StompNet.Tests.Helpers
7 | {
8 | ///
9 | /// MemoryStream that simulates a 'live' stream (e.g. NetworkStream) which does not signal end of stream. When
10 | /// the end of stream has been reached and ReadAsync(byte[], int, int, CancellationToken) is called, it waits for
11 | /// the cancellation token to be canceled.
12 | ///
13 | /// It also supports providing a chunk size (in constructor) to simulate reading in chunks when using
14 | /// ReadAsync(byte[], int, int, CancellationToken).
15 | ///
16 | internal class NoEndChunkedMemoryStream : MemoryStream
17 | {
18 | private readonly int _chunkSize;
19 |
20 | public NoEndChunkedMemoryStream(int chunkSize = 0)
21 | {
22 | _chunkSize = chunkSize;
23 | }
24 |
25 | public override async Task ReadAsync(byte[] buffer, int offset, int count,
26 | CancellationToken cancellationToken)
27 | {
28 | int chunkSize = _chunkSize > 0 ? Math.Min(_chunkSize, count) : count;
29 | int bytesRead = await base.ReadAsync(buffer, offset, chunkSize, cancellationToken);
30 | if (bytesRead == 0)
31 | {
32 | cancellationToken.WaitHandle.WaitOne();
33 | cancellationToken.ThrowIfCancellationRequested();
34 | }
35 | return bytesRead;
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/StompNet.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("StompNet.Tests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("StompNet.Tests")]
13 | [assembly: AssemblyCopyright("Copyright © 2020")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("546ec5fe-779d-4cfa-9679-091162fe0c6f")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/StompNet/Exceptions/ErrorFrameException.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using StompNet.Models.Frames;
21 |
22 | namespace StompNet.Exceptions
23 | {
24 | ///
25 | /// Exception to be used when an STOMP ERROR frame is received.
26 | ///
27 | public class ErrorFrameException : Exception
28 | {
29 | public ErrorFrame ErrorFrame { get; private set; }
30 |
31 | public ErrorFrameException(ErrorFrame errorFrame)
32 | : base(errorFrame != null ? errorFrame.Message : null)
33 | {
34 | if(errorFrame == null)
35 | throw new ArgumentNullException("errorFrame");
36 | ErrorFrame = errorFrame;
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/StompNet.Examples/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("StompNet.Examples")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("StompNet.Examples")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("7e9fb3b1-c612-4bb0-b5d8-db06dad87e0f")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/StompNet/Helpers/ActionDisposable.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 |
21 | namespace StompNet.Helpers
22 | {
23 | ///
24 | /// Disposable class that calls a custom action when it is disposed.
25 | ///
26 | internal class ActionDisposable : IDisposable
27 | {
28 | private readonly Action _action;
29 |
30 | ///
31 | /// Constructor.
32 | ///
33 | /// Action to be invoked when this instance is disposed.
34 | public ActionDisposable(Action action)
35 | {
36 | _action = action;
37 | }
38 |
39 | public void Dispose()
40 | {
41 | _action();
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/StompNet/Models/Frames/ReceiptFrame.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System.Collections.Generic;
20 | using System.Linq;
21 |
22 | namespace StompNet.Models.Frames
23 | {
24 | ///
25 | /// Class representing a STOMP RECEIPT frame.
26 | ///
27 | public class ReceiptFrame : Frame
28 | {
29 | public string ReceiptId { get; private set; }
30 |
31 | internal ReceiptFrame(IEnumerable> headers)
32 | : base (StompCommands.Receipt, headers)
33 | {
34 | ReceiptId = Headers.FirstOrDefault(header => header.Key == StompHeaders.ReceiptId).Value;
35 |
36 | if (string.IsNullOrEmpty(ReceiptId))
37 | ThrowMandatoryHeaderException(StompHeaders.ReceiptId);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/StompNet/IO/IStompClient.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 |
21 | namespace StompNet.IO
22 | {
23 | ///
24 | /// Stomp client interface.
25 | ///
26 | public interface IStompClient : IStompFrameObservable, IStompFrameWriter
27 | {
28 | ///
29 | /// Get next receipt id.
30 | ///
31 | /// The next receipt id.
32 | string GetNextReceiptId();
33 |
34 | ///
35 | /// Get next subscription id.
36 | ///
37 | /// The next subscription id.
38 | string GetNextSubscriptionId();
39 |
40 | ///
41 | /// Get next transaction id.
42 | ///
43 | /// The next transaction id.
44 | string GetNextTransactionId();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/StompNet/IStompConnector.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Threading;
22 | using System.Threading.Tasks;
23 |
24 | namespace StompNet
25 | {
26 | ///
27 | /// Stomp connector interface.
28 | ///
29 | public interface IStompConnector : IDisposable
30 | {
31 |
32 | ///
33 | /// Connect to the STOMP service.
34 | ///
35 | /// Non-standard headers to include in the connect request frame.
36 | /// The token to monitor for cancellation requests.
37 | /// A task representing the connect operation.
38 | Task ConnectAsync(
39 | IEnumerable> extraHeaders = null,
40 | CancellationToken? cancellationToken = null);
41 | }
42 | }
--------------------------------------------------------------------------------
/StompNet/IAsyncDisposable.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using System.Threading;
21 | using System.Threading.Tasks;
22 |
23 | namespace StompNet
24 | {
25 | ///
26 | /// It's like an IDisposable, but with an async dispose method.
27 | ///
28 | public interface IAsyncDisposable : IDisposable
29 | {
30 | Task DisposeAsync(CancellationToken cancellationToken);
31 | }
32 |
33 | ///
34 | /// IAsyncDisposable Extensions.
35 | ///
36 | public static class AsyncDisposableExtensions
37 | {
38 | ///
39 | /// Dispose asynchronously with no cancellation token.
40 | ///
41 | ///
42 | /// A Task representing the dispose operation.
43 | public static Task DisposeAsync(this IAsyncDisposable disposable)
44 | {
45 | return disposable.DisposeAsync(CancellationToken.None);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/StompNet/Helpers/RandomSequenceNumberGenerator.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using System.Threading;
21 |
22 | namespace StompNet.Helpers
23 | {
24 | ///
25 | /// Sequence number generator based on System.Random.
26 | ///
27 | /// This class is thread-safe.
28 | ///
29 | internal class RandomSequenceNumberGenerator : ISequenceNumberGenerator
30 | {
31 | private readonly Random _random;
32 | private SpinLock _spinLock;
33 |
34 | public RandomSequenceNumberGenerator()
35 | {
36 | _random = new Random();
37 | _spinLock = new SpinLock(false);
38 | }
39 |
40 | public int Next()
41 | {
42 | bool lockTaken = false;
43 | try
44 | {
45 | _spinLock.Enter(ref lockTaken);
46 | return _random.Next();
47 | }
48 | finally
49 | {
50 | if(lockTaken) _spinLock.Exit();
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/StompNet/Helpers/AsyncActionDisposable.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using System.Threading;
21 | using System.Threading.Tasks;
22 |
23 | namespace StompNet.Helpers
24 | {
25 | ///
26 | /// IAsyncDisposable implementation that calls a custom action when it is disposed.
27 | ///
28 | internal class AsyncActionDisposable : IAsyncDisposable
29 | {
30 | private readonly Func _action;
31 |
32 | ///
33 | /// Constructor.
34 | ///
35 | /// Action to be invoked when this instance is disposed.
36 | public AsyncActionDisposable(Func action)
37 | {
38 | _action = action;
39 | }
40 |
41 | public void Dispose()
42 | {
43 | DisposeAsync(CancellationToken.None).Wait();
44 | }
45 |
46 | public Task DisposeAsync(CancellationToken cancellationToken)
47 | {
48 | return Task.Run(() => _action(cancellationToken), cancellationToken);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/StompNet/Helpers/ObservableExtensions.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 |
21 | namespace StompNet.Helpers
22 | {
23 | ///
24 | /// Some IObservable extensions.
25 | ///
26 | public static class ObservableExtensions
27 | {
28 | ///
29 | /// Allows to subscribe to an observable using delegates.
30 | ///
31 | /// Observable to be subscribed to.
32 | /// Action to be invoked when the observable calls OnNext.
33 | /// Action to be invoked when the observable calls OnError.
34 | /// Action to be invoked when the observable calls OnCompleted.
35 | /// An IDisposable which ca be used to unsubscribe.
36 | public static IDisposable SubscribeEx(this IObservable observable, Action onNext = null, Action onError = null, Action onCompleted = null)
37 | {
38 | return observable.Subscribe(new ActionObserver(onNext, onError, onCompleted));
39 | }
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/StompNet/Models/StompAckValues.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using System.Collections.Generic;
21 |
22 | namespace StompNet.Models
23 | {
24 | ///
25 | /// Ack values as defined by STOMP protocol specification.
26 | ///
27 | public static class StompAckValues
28 | {
29 | public const string AckAutoValue = "auto";
30 | public const string AckClientValue = "client";
31 | public const string AckClientIndividualValue = "client-individual";
32 |
33 | private static readonly ISet _ackValidValues = new HashSet { AckAutoValue, AckClientIndividualValue, AckClientValue };
34 |
35 | public static bool IsValidAckValue(string ackValue)
36 | {
37 | return _ackValidValues.Contains(ackValue);
38 | }
39 |
40 | public static void ThrowIfInvalidAckValue(string ackValue)
41 | {
42 | if(!_ackValidValues.Contains(ackValue))
43 | throw new ArgumentException(string.Format("{0} header value MUST be: '{1}', '{2}' or '{3}'", StompHeaders.Ack, AckAutoValue, AckClientIndividualValue, AckClientValue));
44 |
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/StompNet/IO/IStompFrameObservable.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using System.Threading;
21 | using StompNet.Models.Frames;
22 |
23 | namespace StompNet.IO
24 | {
25 | ///
26 | /// Interface for a frame reader in an 'observer pattern' fashion.
27 | ///
28 | public interface IStompFrameObservable : IObservable
29 | {
30 | bool IsStarted { get; }
31 | string ProtocolVersion { get; }
32 |
33 | ///
34 | /// Start processing incoming frames.
35 | ///
36 | /// Cancellation token that may be used to stop the processing of incoming frames.
37 | void Start(CancellationToken cancellationToken);
38 | }
39 |
40 | ///
41 | /// IStompFrameObservable extensions.
42 | ///
43 | public static class StompFrameObservableExtensions
44 | {
45 | ///
46 | /// Start processing incoming frames.
47 | ///
48 | public static void Start(this IStompFrameObservable stompFrameObservable)
49 | {
50 | stompFrameObservable.Start(CancellationToken.None);
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/StompNet/IO/IStompFrameReader.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using System.Threading;
21 | using System.Threading.Tasks;
22 | using StompNet.Models.Frames;
23 |
24 | namespace StompNet.IO
25 | {
26 | ///
27 | /// Contract of a Frame Reader.
28 | ///
29 | public interface IStompFrameReader : IDisposable
30 | {
31 | ///
32 | /// Version of the STOMP protocol.
33 | ///
34 | string ProtocolVersion { get; }
35 |
36 | ///
37 | /// Read a frame.
38 | ///
39 | /// The token to monitor for cancellation requests.
40 | /// A task representing the read operation. The result of this task is a frame.
41 | Task ReadFrameAsync(CancellationToken cancellationToken);
42 | }
43 |
44 | ///
45 | /// So, you do not like using CancellationTokens :D. Use this extension!
46 | ///
47 | public static class FrameReaderExtensions
48 | {
49 | public static Task ReadFrameAsync(this IStompFrameReader reader)
50 | {
51 | return reader.ReadFrameAsync(CancellationToken.None);
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/StompNet/IO/IStompFrameWriter.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using System.Threading;
21 | using System.Threading.Tasks;
22 | using StompNet.Models.Frames;
23 |
24 | namespace StompNet.IO
25 | {
26 | ///
27 | /// Contract of a Frame Writer.
28 | ///
29 | public interface IStompFrameWriter : IDisposable
30 | {
31 | ///
32 | /// Version of the STOMP protocol.
33 | ///
34 | string ProtocolVersion { get; }
35 |
36 | ///
37 | /// Write a frame.
38 | ///
39 | /// Frame to be written.
40 | /// The token to monitor for cancellation requests.
41 | /// A task representing the write operation.
42 | Task WriteAsync(Frame frame, CancellationToken cancellationToken);
43 | }
44 |
45 | ///
46 | /// So, you do not like using CancellationTokens :D. Use this extension!
47 | ///
48 | public static class FrameWriterExtensions
49 | {
50 | public static Task WriteAsync(this IStompFrameWriter writer, Frame frame)
51 | {
52 | return writer.WriteAsync(frame, CancellationToken.None);
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/StompNet/Models/StompHeaders.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | namespace StompNet.Models
20 | {
21 | ///
22 | /// Frame headers as defined by STOMP protocol specification.
23 | ///
24 | public static class StompHeaders
25 | {
26 | public const string AcceptVersion = "accept-version";
27 | public const string Ack = "ack";
28 | public const string ContentLength = "content-length";
29 | public const string ContentType = "content-type";
30 | public const string Destination = "destination";
31 | public const string Heartbeat = "heart-beat";
32 | public const string Host = "host";
33 | public const string Id = "id";
34 | public const string Login = "login";
35 | public const string Message = "message";
36 | public const string MessageId = "message-id";
37 | public const string Passcode = "passcode";
38 | public const string Receipt = "receipt";
39 | public const string ReceiptId = "receipt-id";
40 | public const string Server = "server";
41 | public const string Session = "session";
42 | public const string Subscription = "subscription";
43 | public const string Transaction = "transaction";
44 | public const string Version = "version";
45 | }
46 | }
--------------------------------------------------------------------------------
/StompNet/Helpers/ITaskExecuter.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using System.Threading;
21 | using System.Threading.Tasks;
22 |
23 | namespace StompNet.Helpers
24 | {
25 | ///
26 | /// Interface for a task executer/scheduler.
27 | ///
28 | internal interface ITaskExecuter
29 | {
30 | ///
31 | /// Execute a task.
32 | ///
33 | /// A function that returns the task to be executed.
34 | /// The token to monitor for cancellation requests.
35 | /// A task representing the scheduled task operation.
36 | Task Execute(Func task, CancellationToken cancellationToken);
37 | }
38 |
39 | ///
40 | /// Interface for a task executer/scheduler.
41 | ///
42 | internal interface ITaskExecuter : ITaskExecuter
43 | {
44 | ///
45 | /// Execute a task.
46 | ///
47 | /// A function that returns the task to be executed.
48 | /// The token to monitor for cancellation requests.
49 | /// A task representing the scheduled task operation. The returned task result is the same as the original task's result.
50 | Task Execute(Func> task, CancellationToken cancellationToken);
51 | }
52 | }
--------------------------------------------------------------------------------
/StompNet.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5E1F295D-C527-42EA-A486-DDBD2A1F9CB7}"
7 | ProjectSection(SolutionItems) = preProject
8 | LICENSE.txt = LICENSE.txt
9 | README.md = README.md
10 | EndProjectSection
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StompNet", "StompNet\StompNet.csproj", "{2BE5619B-B63B-4583-B434-371C925FE18C}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StompNet.Examples", "StompNet.Examples\StompNet.Examples.csproj", "{84A7D6AB-D0C5-4A83-A205-35FE232F8547}"
15 | EndProject
16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StompNet.Tests", "StompNet.Tests\StompNet.Tests.csproj", "{546EC5FE-779D-4CFA-9679-091162FE0C6F}"
17 | EndProject
18 | Global
19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
20 | Debug|Any CPU = Debug|Any CPU
21 | Release|Any CPU = Release|Any CPU
22 | EndGlobalSection
23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
24 | {2BE5619B-B63B-4583-B434-371C925FE18C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {2BE5619B-B63B-4583-B434-371C925FE18C}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {2BE5619B-B63B-4583-B434-371C925FE18C}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {2BE5619B-B63B-4583-B434-371C925FE18C}.Release|Any CPU.Build.0 = Release|Any CPU
28 | {84A7D6AB-D0C5-4A83-A205-35FE232F8547}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29 | {84A7D6AB-D0C5-4A83-A205-35FE232F8547}.Debug|Any CPU.Build.0 = Debug|Any CPU
30 | {84A7D6AB-D0C5-4A83-A205-35FE232F8547}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {84A7D6AB-D0C5-4A83-A205-35FE232F8547}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {546EC5FE-779D-4CFA-9679-091162FE0C6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 | {546EC5FE-779D-4CFA-9679-091162FE0C6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 | {546EC5FE-779D-4CFA-9679-091162FE0C6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
35 | {546EC5FE-779D-4CFA-9679-091162FE0C6F}.Release|Any CPU.Build.0 = Release|Any CPU
36 | EndGlobalSection
37 | GlobalSection(SolutionProperties) = preSolution
38 | HideSolutionNode = FALSE
39 | EndGlobalSection
40 | EndGlobal
41 |
--------------------------------------------------------------------------------
/StompNet/Helpers/ActionObserver.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 |
21 | namespace StompNet.Helpers
22 | {
23 | ///
24 | /// General-purpose IObserver configured using custom actions/delegates.
25 | ///
26 | internal class ActionObserver : IObserver
27 | {
28 | private readonly Action _onNext;
29 | private readonly Action _onError;
30 | private readonly Action _onCompleted;
31 |
32 | ///
33 | /// Constructor.
34 | ///
35 | /// Action to be invoked when the observable calls OnNext.
36 | /// Action to be invoked when the observable calls OnError.
37 | /// Action to be invoked when the observable calls OnCompleted.
38 | public ActionObserver(Action onNext = null, Action onError = null, Action onCompleted = null)
39 | {
40 | _onNext = onNext;
41 | _onError = onError;
42 | _onCompleted = onCompleted;
43 | }
44 |
45 | public void OnNext(T value)
46 | {
47 | if(_onNext != null) _onNext(value);
48 | }
49 |
50 | public void OnError(Exception error)
51 | {
52 | if (_onError != null) _onError(error);
53 | }
54 |
55 | public void OnCompleted()
56 | {
57 | if (_onCompleted != null) _onCompleted();
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/StompNet/IO/StompSerialFrameWriter.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System.Threading;
20 | using System.Threading.Tasks;
21 | using StompNet.Helpers;
22 | using StompNet.Models.Frames;
23 |
24 | namespace StompNet.IO
25 | {
26 | ///
27 | /// Wrapper around an IStompFrameWriter for thread-safety.
28 | /// STOMP frames will be written in a sequential/serial FIFO manner.
29 | ///
30 | public class StompSerialFrameWriter : IStompFrameWriter
31 | {
32 | private readonly IStompFrameWriter _writer;
33 | private readonly ITaskExecuter _serialTaskExecuter;
34 |
35 | public string ProtocolVersion
36 | {
37 | get { return _writer.ProtocolVersion; }
38 | }
39 |
40 | ///
41 | /// Constructor.
42 | ///
43 | /// Frame writer to be wrapped.
44 | public StompSerialFrameWriter(IStompFrameWriter writer)
45 | {
46 | _writer = writer;
47 | _serialTaskExecuter = new SerialTaskExecuter();
48 | }
49 |
50 | public Task WriteAsync(Frame frame, CancellationToken cancellationToken)
51 | {
52 | return _serialTaskExecuter.Execute(() => _writer.WriteAsync(frame, cancellationToken), cancellationToken);
53 | }
54 |
55 | public void Dispose()
56 | {
57 | Dispose(true);
58 | }
59 |
60 | protected virtual void Dispose(bool disposing)
61 | {
62 |
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/StompNet/IO/StompSerialFrameReader.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System.Threading;
20 | using System.Threading.Tasks;
21 | using StompNet.Helpers;
22 | using StompNet.Models.Frames;
23 |
24 | namespace StompNet.IO
25 | {
26 | ///
27 | /// Wrapper around an IStompFrameReader for thread-safety.
28 | /// STOMP frames will be read in a sequential/serial FIFO manner.
29 | ///
30 | public class StompSerialFrameReader : IStompFrameReader
31 | {
32 | private readonly IStompFrameReader _reader;
33 | private readonly ITaskExecuter _serialTaskExecuter;
34 |
35 | public string ProtocolVersion
36 | {
37 | get { return _reader.ProtocolVersion; }
38 | }
39 |
40 | ///
41 | /// Constructor.
42 | ///
43 | /// Frame reader to be wrapped.
44 | public StompSerialFrameReader(IStompFrameReader reader)
45 | {
46 | _reader = reader;
47 | _serialTaskExecuter = new SerialTaskExecuter();
48 | }
49 |
50 | public Task ReadFrameAsync(CancellationToken cancellationToken)
51 | {
52 | return _serialTaskExecuter.Execute(() => _reader.ReadFrameAsync(cancellationToken), cancellationToken);
53 | }
54 |
55 | public void Dispose()
56 | {
57 | Dispose(true);
58 | }
59 |
60 | protected virtual void Dispose(bool disposing)
61 | {
62 |
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/StompNet/Helpers/EnumerableExtensions.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using System.Collections.Generic;
21 |
22 | namespace StompNet.Helpers
23 | {
24 | ///
25 | /// Some IEnumerable extensions.
26 | ///
27 | internal static class EnumerableExtensions
28 | {
29 | ///
30 | /// For each element of the IEnumerable, invoke an action.
31 | ///
32 | /// IEnumerable source of the elements.
33 | /// Action to be invoked for each element of the IEnumerable.
34 | public static void Do(this IEnumerable source, Action action)
35 | {
36 | foreach (var item in source)
37 | {
38 | action(item);
39 | }
40 | }
41 |
42 | ///
43 | /// For each element of the IEnumerable, invoke an action.
44 | /// If the action fails, continue with the next one.
45 | ///
46 | /// IEnumerable source of the elements.
47 | /// Action to be invoked for each element of the IEnumerable.
48 | public static void DoIgnoringExceptions(this IEnumerable source, Action action)
49 | {
50 | foreach (var item in source)
51 | {
52 | try
53 | {
54 | action(item);
55 | }
56 | catch { }
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/StompNet/StompTransaction.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System.Collections.Generic;
20 | using System.Threading;
21 | using System.Threading.Tasks;
22 | using StompNet.IO;
23 |
24 | namespace StompNet
25 | {
26 | ///
27 | /// Stomp Transaction.
28 | ///
29 | internal class StompTransaction : StompConnectionBase, IStompTransaction
30 | {
31 | public string Id
32 | {
33 | get { return TransactionId; }
34 | }
35 |
36 | public StompTransaction(StompClient client, string id)
37 | : base(client, id)
38 | {
39 | }
40 |
41 | public Task CommitAsync(
42 | bool useReceipt = false,
43 | IEnumerable> extraHeaders = null,
44 | CancellationToken? cancellationToken = null)
45 | {
46 | return Client.WriteCommitAsync(
47 | Id,
48 | useReceipt ? Client.GetNextReceiptId() : null,
49 | extraHeaders,
50 | cancellationToken);
51 | }
52 |
53 | public Task AbortAsync(
54 | bool useReceipt = false,
55 | IEnumerable> extraHeaders = null,
56 | CancellationToken? cancellationToken = null)
57 | {
58 | return Client.WriteAbortAsync(
59 | Id,
60 | useReceipt ? Client.GetNextReceiptId() : null,
61 | extraHeaders,
62 | cancellationToken);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/StompNet/StompConnection.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System.Collections.Generic;
20 | using System.Threading;
21 | using System.Threading.Tasks;
22 | using StompNet.IO;
23 |
24 | namespace StompNet
25 | {
26 | ///
27 | /// Stomp Connection.
28 | ///
29 | internal class StompConnection : StompConnectionBase, IStompConnection
30 | {
31 | public StompConnection(StompClient client)
32 | : base(client)
33 | {
34 |
35 | }
36 |
37 | public async Task BeginTransactionAsync(
38 | bool useReceipt = false,
39 | IEnumerable> extraHeaders = null,
40 | CancellationToken? cancellationToken = null)
41 | {
42 | string transactionId = Client.GetNextTransactionId();
43 | await Client.WriteBeginAsync(
44 | transactionId,
45 | useReceipt ? Client.GetNextReceiptId() : null,
46 | extraHeaders,
47 | cancellationToken);
48 |
49 | return new StompTransaction(Client, transactionId);
50 | }
51 |
52 | public Task DisconnectAsync(
53 | bool useReceipt = false,
54 | IEnumerable> extraHeaders = null,
55 | CancellationToken? cancellationToken = null)
56 | {
57 | return Client.WriteDisconnectAsync(
58 | useReceipt ? Client.GetNextReceiptId() : null,
59 | extraHeaders,
60 | cancellationToken);
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/StompNet/Models/Frames/Heartbeat.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 |
21 | namespace StompNet.Models.Frames
22 | {
23 | ///
24 | /// Class representing a Heartbeat.
25 | ///
26 | public class Heartbeat
27 | {
28 | public readonly static Heartbeat NoHeartbeat = new Heartbeat(0, 0);
29 |
30 | public int Outgoing { get; private set; }
31 | public int Incoming { get; private set; }
32 | public string RawHeartbeat { get; private set; }
33 |
34 | public Heartbeat(int outgoing, int incoming)
35 | {
36 | Outgoing = outgoing;
37 | Incoming = incoming;
38 | RawHeartbeat = outgoing + "," + incoming;
39 | }
40 |
41 | public static Heartbeat GetHeartbeat(string heartbeat)
42 | {
43 | if (string.IsNullOrEmpty(heartbeat))
44 | return NoHeartbeat;
45 |
46 | string[] heartBeatParts = heartbeat.Split(',');
47 |
48 | if (heartBeatParts.Length != 2)
49 | throw new FormatException("A heart-beat header MUST contain two positive integers separated by a comma.");
50 |
51 | int outgoing, incoming;
52 | if (!int.TryParse(heartBeatParts[0], out outgoing) || outgoing < 0 || !int.TryParse(heartBeatParts[1], out incoming) || incoming < 0)
53 | throw new FormatException("A heart-beat header MUST contain two positive integers separated by a comma.");
54 |
55 | if(outgoing == 0 && incoming == 0)
56 | return NoHeartbeat;
57 |
58 | return new Heartbeat(outgoing, incoming);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/StompNet/Models/Frames/ErrorFrame.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System.Collections.Generic;
20 |
21 | namespace StompNet.Models.Frames
22 | {
23 | ///
24 | /// Class representing a STOMP ERROR frame.
25 | ///
26 | public class ErrorFrame : Frame
27 | {
28 | public string ReceiptId { get; private set; }
29 |
30 | public string Message { get; private set; }
31 |
32 | public string ContentType { get; private set; }
33 |
34 | public int ContentLength { get; private set; }
35 |
36 | internal ErrorFrame(IEnumerable> headers, byte[] body = null)
37 | : base (StompCommands.Error, headers, body)
38 | {
39 | int missingHeaders = 3;
40 |
41 | foreach (var header in Headers)
42 | {
43 | if (ReceiptId == null && header.Key == StompHeaders.ReceiptId)
44 | {
45 | ReceiptId = header.Value;
46 | missingHeaders--;
47 | }
48 | else if (Message == null && header.Key == StompHeaders.Message)
49 | {
50 | Message = header.Value;
51 | missingHeaders--;
52 | }
53 | else if (ContentType == null && header.Key == StompHeaders.ContentType)
54 | {
55 | ContentType = header.Value;
56 | missingHeaders--;
57 | }
58 |
59 | if (missingHeaders == 0) break;
60 | }
61 |
62 | ContentLength = BodyArray.Length;
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/StompNet/IStompConnection.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System.Collections.Generic;
20 | using System.Threading;
21 | using System.Threading.Tasks;
22 |
23 | namespace StompNet
24 | {
25 | ///
26 | /// Stomp connection interface.
27 | ///
28 | public interface IStompConnection : IStompConnectionBase
29 | {
30 | ///
31 | /// Begin a transaction.
32 | ///
33 | /// Indicates whether to require the service to confirm receipt of the message.
34 | /// Non-standard headers to include in the connect request frame.
35 | /// The token to monitor for cancellation requests.
36 | /// A task representing the commit operation. The result of this task is a transaction instance.
37 | Task BeginTransactionAsync(
38 | bool useReceipt = false,
39 | IEnumerable> extraHeaders = null,
40 | CancellationToken? cancellationToken = null);
41 |
42 | ///
43 | /// Disconnect from STOMP service.
44 | ///
45 | /// Indicates whether to require the service to confirm receipt of the message.
46 | /// Non-standard headers to include in the connect request frame.
47 | /// The token to monitor for cancellation requests.
48 | /// A task representing the disconnect operation.
49 | Task DisconnectAsync(
50 | bool useReceipt = false,
51 | IEnumerable> extraHeaders = null,
52 | CancellationToken? cancellationToken = null);
53 | }
54 | }
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/StompNet/IStompTransaction.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System.Collections.Generic;
20 | using System.Threading;
21 | using System.Threading.Tasks;
22 |
23 | namespace StompNet
24 | {
25 | ///
26 | /// Stomp transaction interface.
27 | ///
28 | public interface IStompTransaction : IStompConnectionBase
29 | {
30 | string Id { get; }
31 |
32 | /////
33 | ///// Connect to the STOMP service.
34 | /////
35 |
36 |
37 | ///
38 | /// Commit the transaction.
39 | ///
40 | /// Indicates whether to require the service to confirm receipt of the message.
41 | /// Non-standard headers to include in the connect request frame.
42 | /// The token to monitor for cancellation requests.
43 | /// A task representing the commit operation.
44 | Task CommitAsync(
45 | bool useReceipt = false,
46 | IEnumerable> extraHeaders = null,
47 | CancellationToken? cancellationToken = null);
48 |
49 | ///
50 | /// Abort the transaction.
51 | ///
52 | /// Indicates whether to require the service to confirm receipt of the message.
53 | /// Non-standard headers to include in the connect request frame.
54 | /// The token to monitor for cancellation requests.
55 | /// A task representing the abort operation.
56 | Task AbortAsync(
57 | bool useReceipt = false,
58 | IEnumerable> extraHeaders = null,
59 | CancellationToken? cancellationToken = null);
60 | }
61 | }
--------------------------------------------------------------------------------
/StompNet/Models/StompCommands.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System.Collections.Generic;
20 |
21 | namespace StompNet.Models
22 | {
23 | ///
24 | /// Commands as defined by STOMP protocol specification.
25 | ///
26 | public static class StompCommands
27 | {
28 | #region Client Commands
29 |
30 | public const string Abort = "ABORT";
31 | public const string Ack = "ACK";
32 | public const string Begin = "BEGIN";
33 | public const string Commit = "COMMIT";
34 | public const string Connect = "CONNECT";
35 | public const string Disconnect = "DISCONNECT";
36 | public const string Nack = "NACK";
37 | public const string Send = "SEND";
38 | public const string Stomp = "STOMP";
39 | public const string Subscribe = "SUBSCRIBE";
40 | public const string Unsubscribe = "UNSUBSCRIBE";
41 |
42 | private static readonly ISet _clientCommandSet = new HashSet { Send, Subscribe, Unsubscribe, Begin, Commit, Abort, Ack, Nack, Disconnect, Connect, Stomp };
43 |
44 | public static bool IsClientCommand(string command)
45 | {
46 | return _clientCommandSet.Contains(command);
47 | }
48 |
49 | #endregion
50 |
51 | #region Server Commands
52 |
53 | public const string Connected = "CONNECTED";
54 | public const string Error = "ERROR";
55 | public const string Message = "MESSAGE";
56 | public const string Receipt = "RECEIPT";
57 | public const string Heartbeat = "HEARTBEAT"; // THIS IS AN 'ARTIFICIAL' COMMAND
58 |
59 | private static readonly ISet _serverCommandSet = new HashSet { Connected, Message, Receipt, Error };
60 |
61 | public static bool IsServerCommand(string command)
62 | {
63 | return _serverCommandSet.Contains(command);
64 | }
65 |
66 | #endregion
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/StompNet/Models/Frames/ConnectedFrame.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System.Collections.Generic;
20 |
21 | namespace StompNet.Models.Frames
22 | {
23 | ///
24 | /// Class representing a STOMP CONNECTED frame.
25 | ///
26 | public class ConnectedFrame : Frame
27 | {
28 | public string Version { get; private set; }
29 |
30 | public string Session { get; private set; }
31 |
32 | public string Server { get; private set; }
33 |
34 | public Heartbeat Heartbeat { get; private set; }
35 |
36 | public ConnectedFrame(IEnumerable> headers)
37 | : base (StompCommands.Connected, headers)
38 | {
39 | int missingHeaders = 4;
40 |
41 | foreach (var header in Headers)
42 | {
43 | if (Version == null && header.Key == StompHeaders.Version)
44 | {
45 | Version = header.Value;
46 | missingHeaders--;
47 | }
48 | else if (Session == null && header.Key == StompHeaders.Session)
49 | {
50 | Session = header.Value;
51 | missingHeaders--;
52 | }
53 | else if (Server == null && header.Key == StompHeaders.Server)
54 | {
55 | Server = header.Value;
56 | missingHeaders--;
57 | }
58 | else if (Heartbeat == null && header.Key == StompHeaders.Heartbeat)
59 | {
60 | Heartbeat = Heartbeat.GetHeartbeat(header.Value);
61 | missingHeaders--;
62 | }
63 |
64 | if (missingHeaders == 0) break;
65 | }
66 |
67 | if (missingHeaders != 0)
68 | {
69 | if (string.IsNullOrEmpty(Version))
70 | {
71 | Version = "1.0";
72 | }
73 | }
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/StompNet/Models/StompInterpreter.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using System.IO;
21 | using StompNet.Models.Frames;
22 |
23 | namespace StompNet.Models
24 | {
25 | ///
26 | /// Class to transform frames into an instance of a 'subclass' matching its command.
27 | ///
28 | public static class StompInterpreter
29 | {
30 | ///
31 | /// Transform a frame into a 'subclass' matching its command.
32 | /// These subclasses are: ReceiptFrame, MessageFrame, ErrorFrame, ConnectedFrame.
33 | ///
34 | /// Frame to be interpreted.
35 | /// A new frame which class matches its command type.
36 | public static Frame Interpret(Frame frame)
37 | {
38 | if (frame == null)
39 | throw new ArgumentNullException("frame");
40 |
41 | switch (frame.Command)
42 | {
43 | case StompCommands.Heartbeat:
44 | return frame;
45 | case StompCommands.Receipt:
46 | if (frame.BodyArray != Frame.EmptyBody)
47 | throw new InvalidDataException("Receipt frame MUST NOT have a body.");
48 | return new ReceiptFrame(frame.Headers);
49 | case StompCommands.Message:
50 | return new MessageFrame(frame.Headers, frame.BodyArray);
51 | case StompCommands.Error:
52 | return new ErrorFrame(frame.Headers, frame.BodyArray);
53 | case StompCommands.Connected:
54 | if (frame.BodyArray != Frame.EmptyBody)
55 | throw new InvalidDataException("Connected frame MUST NOT have a body.");
56 | return new ConnectedFrame(frame.Headers);
57 | default:
58 | throw new InvalidDataException(string.Format("'{0}' is not a valid STOMP server command.", frame.Command));
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 |
11 | [Dd]ebug/
12 | [Rr]elease/
13 | x64/
14 | build/
15 | [Bb]in/
16 | [Oo]bj/
17 |
18 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
19 | !packages/*/build/
20 |
21 | # MSTest test Results
22 | [Tt]est[Rr]esult*/
23 | [Bb]uild[Ll]og.*
24 |
25 | *_i.c
26 | *_p.c
27 | *.ilk
28 | *.meta
29 | *.obj
30 | *.pch
31 | *.pdb
32 | *.pgc
33 | *.pgd
34 | *.rsp
35 | *.sbr
36 | *.tlb
37 | *.tli
38 | *.tlh
39 | *.tmp
40 | *.tmp_proj
41 | *.log
42 | *.vspscc
43 | *.vssscc
44 | .builds
45 | *.pidb
46 | *.log
47 | *.scc
48 |
49 | # Visual C++ cache files
50 | ipch/
51 | *.aps
52 | *.ncb
53 | *.opensdf
54 | *.sdf
55 | *.cachefile
56 |
57 | # Visual Studio profiler
58 | *.psess
59 | *.vsp
60 | *.vspx
61 |
62 | # Guidance Automation Toolkit
63 | *.gpState
64 |
65 | # ReSharper is a .NET coding add-in
66 | _ReSharper*/
67 | *.[Rr]e[Ss]harper
68 |
69 | # TeamCity is a build add-in
70 | _TeamCity*
71 |
72 | # DotCover is a Code Coverage Tool
73 | *.dotCover
74 |
75 | # NCrunch
76 | *.ncrunch*
77 | .*crunch*.local.xml
78 |
79 | # Installshield output folder
80 | [Ee]xpress/
81 |
82 | # DocProject is a documentation generator add-in
83 | DocProject/buildhelp/
84 | DocProject/Help/*.HxT
85 | DocProject/Help/*.HxC
86 | DocProject/Help/*.hhc
87 | DocProject/Help/*.hhk
88 | DocProject/Help/*.hhp
89 | DocProject/Help/Html2
90 | DocProject/Help/html
91 |
92 | # Click-Once directory
93 | publish/
94 |
95 | # Publish Web Output
96 | *.Publish.xml
97 |
98 | # NuGet Packages Directory
99 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
100 | #packages/
101 |
102 | # Windows Azure Build Output
103 | csx
104 | *.build.csdef
105 |
106 | # Windows Store app package directory
107 | AppPackages/
108 |
109 | # Others
110 | sql/
111 | *.Cache
112 | ClientBin/
113 | [Ss]tyle[Cc]op.*
114 | ~$*
115 | *~
116 | *.dbmdl
117 | *.[Pp]ublish.xml
118 | *.pfx
119 | *.publishsettings
120 |
121 | # RIA/Silverlight projects
122 | Generated_Code/
123 |
124 | # Backup & report files from converting an old project file to a newer
125 | # Visual Studio version. Backup files are not needed, because we have git ;-)
126 | _UpgradeReport_Files/
127 | Backup*/
128 | UpgradeLog*.XML
129 | UpgradeLog*.htm
130 |
131 | # SQL Server files
132 | App_Data/*.mdf
133 | App_Data/*.ldf
134 |
135 |
136 | #LightSwitch generated files
137 | GeneratedArtifacts/
138 | _Pvt_Extensions/
139 | ModelManifest.xml
140 |
141 | # =========================
142 | # Windows detritus
143 | # =========================
144 |
145 | # Windows image file caches
146 | Thumbs.db
147 | ehthumbs.db
148 |
149 | # Folder config file
150 | Desktop.ini
151 |
152 | # Recycle Bin used on file shares
153 | $RECYCLE.BIN/
154 |
155 | # Mac desktop service store files
156 | .DS_Store
157 | /.vs
158 |
--------------------------------------------------------------------------------
/StompNet/IO/Stomp12Client.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using System.IO;
21 |
22 | namespace StompNet.IO
23 | {
24 | ///
25 | /// STOMP 1.2 Client.
26 | ///
27 | /// ATTENTION: This is a disposable class.
28 | ///
29 | public class Stomp12Client : StompClient
30 | {
31 |
32 | ///
33 | /// Constructor of a client for STOMP 1.2.
34 | ///
35 | /// Stream for incoming/outgoing data from/to STOMP service.
36 | /// When sending messages that require receipt confirmation,
37 | /// this interval specifies how much time to wait before sending the frame again if
38 | /// no receipt is received.
39 | /// Flag to indicate random numbers must
40 | /// be used when creating sequence numbers for receipts, subscriptions and transactions
41 | public Stomp12Client(Stream stream, TimeSpan? retryInterval = null, bool useRandomNumberGenerator = false)
42 | : this (stream, stream, retryInterval, useRandomNumberGenerator)
43 | {
44 |
45 | }
46 |
47 | ///
48 | /// Constructor of a client for STOMP 1.2.
49 | ///
50 | /// Stream for incoming data from STOMP service.
51 | /// Stream for outgoing data to STOMP service.
52 | /// When sending messages that requires receipt confirmation,
53 | /// this interval specifies how much time to wait before sending the frame again if
54 | /// no receipt is received.
55 | /// Flag to indicate random numbers must
56 | /// be used when creating sequence numbers for receipts, subscriptions and transactions
57 | public Stomp12Client(Stream inStream, Stream outStream, TimeSpan? retryInterval = null, bool useRandomNumberGenerator = false)
58 | : base (new Stomp12FrameReader(inStream), new Stomp12FrameWriter(outStream), retryInterval, true, useRandomNumberGenerator)
59 | {
60 |
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/StompNet.Examples/StompNet.Examples.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {84A7D6AB-D0C5-4A83-A205-35FE232F8547}
8 | Exe
9 | Properties
10 | StompNet.Examples
11 | StompNet.Examples
12 | v4.5
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | {2be5619b-b63b-4583-b434-371c925fe18c}
58 | StompNet
59 |
60 |
61 |
62 |
69 |
--------------------------------------------------------------------------------
/StompNet/Models/Frames/MessageFrame.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using StompNet.Helpers;
20 | using System.Collections.Generic;
21 |
22 | namespace StompNet.Models.Frames
23 | {
24 | ///
25 | /// Class representing a STOMP message frame.
26 | ///
27 | public class MessageFrame : Frame
28 | {
29 | public string Destination { get; private set; }
30 |
31 | public string MessageId { get; private set; }
32 |
33 | public string Subscription { get; private set; }
34 |
35 | public string Ack { get; private set; }
36 |
37 | public string ContentType { get; private set; }
38 |
39 | public int ContentLength { get; private set; }
40 |
41 | internal MessageFrame(IEnumerable> headers, byte[] body = null)
42 | : base (StompCommands.Message, headers, body)
43 | {
44 | int missingHeaders = 5;
45 |
46 | foreach(var header in Headers)
47 | {
48 | if (Destination == null && header.Key == StompHeaders.Destination)
49 | {
50 | Destination = header.Value;
51 | missingHeaders--;
52 | }
53 | else if (MessageId == null && header.Key == StompHeaders.MessageId)
54 | {
55 | MessageId = header.Value;
56 | missingHeaders--;
57 | }
58 | else if (Subscription == null && header.Key == StompHeaders.Subscription)
59 | {
60 | Subscription = header.Value;
61 | missingHeaders--;
62 | }
63 | else if (ContentType == null && header.Key == StompHeaders.ContentType)
64 | {
65 | ContentType = header.Value;
66 | missingHeaders--;
67 | }
68 | else if (Ack == null && header.Key == StompHeaders.Ack)
69 | {
70 | Ack = header.Value;
71 | missingHeaders--;
72 | }
73 |
74 | if(missingHeaders == 0) break;
75 | }
76 |
77 | if(missingHeaders != 0)
78 | {
79 | if (string.IsNullOrEmpty(Destination))
80 | ThrowMandatoryHeaderException(StompHeaders.Destination);
81 | if (string.IsNullOrEmpty(MessageId))
82 | ThrowMandatoryHeaderException(StompHeaders.MessageId);
83 | if (string.IsNullOrEmpty(Subscription))
84 | ThrowMandatoryHeaderException(StompHeaders.Subscription);
85 | if(string.IsNullOrEmpty(ContentType))
86 | ContentType = MediaTypeNames.ApplicationOctet;
87 | }
88 |
89 | ContentLength = BodyArray.Length;
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/StompNet/Helpers/SerialTaskExecuter.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | *
3 | * Copyright (c) 2014 Carlos Campo
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | *******************************************************************************/
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Threading;
23 | using System.Threading.Tasks;
24 |
25 | namespace StompNet.Helpers
26 | {
27 | ///
28 | /// Class to execute tasks serially.
29 | ///
30 | internal class SerialTaskExecuter : ITaskExecuter where T : class
31 | {
32 | private readonly LinkedList> _queue;
33 |
34 | public SerialTaskExecuter()
35 | {
36 | _queue = new LinkedList>();
37 | }
38 |
39 | public Task Execute(Func> task, CancellationToken cancellationToken)
40 | {
41 | return Execute(task as Func, cancellationToken) as Task;
42 | }
43 |
44 | public Task Execute(Func task, CancellationToken cancellationToken)
45 | {
46 | TaskCompletionSource tcs = new TaskCompletionSource();
47 |
48 | Func nextTask =
49 | () =>
50 | Task.Run(task, cancellationToken).ContinueWith(
51 | awaitedTask =>
52 | {
53 | tcs.TrySet(awaitedTask);
54 | Monitor.Enter(_queue);
55 | _queue.RemoveFirst();
56 | Func next = _queue.FirstOrDefault();
57 | Monitor.Exit(_queue);
58 | if(next != null) next();
59 | });
60 |
61 |
62 | Monitor.Enter(_queue);
63 | _queue.AddLast(nextTask);
64 | bool start = _queue.Count == 1;
65 | Monitor.Exit(_queue);
66 | if (start) nextTask();
67 |
68 | return tcs.Task;
69 | }
70 | }
71 |
72 | ///
73 | /// Class to execute tasks serially.
74 | ///
75 | internal class SerialTaskExecuter : SerialTaskExecuter