├── SampleHardwareServiceApp ├── App.config ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── packages.config ├── Program.cs ├── SampleHardwareServiceApp.csproj ├── Form1.cs ├── Form1.resx └── Form1.Designer.cs ├── SampleHardwareServiceWithStomp ├── packages.config ├── App.config ├── Properties │ └── AssemblyInfo.cs ├── Program.cs └── SampleHardwareServiceWithStomp.csproj ├── README.md ├── StompHelper ├── StompCommand.cs ├── Properties │ └── AssemblyInfo.cs ├── StompMessageSerializer.cs ├── StompMessage.cs └── StompHelper.csproj └── SampleHardwareServiceWithStomp.sln /SampleHardwareServiceApp/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SampleHardwareServiceWithStomp/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /SampleHardwareServiceApp/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # websocket-csharp-net-stomp-client 2 | A C# implementation of STOMP client over websocket 3 | 4 | ### Introduction 5 | 6 | 7 | ### Prerequisite 8 | 9 | 10 | ### Reference GIT Project 11 | - https://github.com/sta/websocket-sharp 12 | - https://github.com/ernstnaezer/ultralight/tree/master/src/Ultralight 13 | -------------------------------------------------------------------------------- /SampleHardwareServiceApp/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SampleHardwareServiceWithStomp/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /SampleHardwareServiceApp/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace SampleHardwareServiceApp 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new Form1()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /StompHelper/StompCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StompHelper 8 | { 9 | public class StompFrame 10 | { 11 | //Client Command 12 | public const string CONNECT = "CONNECT"; 13 | public const string DISCONNECT = "DISCONNECT"; 14 | public const string SUBSCRIBE = "SUBSCRIBE"; 15 | public const string UNSUBSCRIBE = "UNSUBSCRIBE"; 16 | public const string SEND = "SEND"; 17 | 18 | //Server Response 19 | public const string CONNECTED = "CONNECTED"; 20 | public const string MESSAGE = "MESSAGE"; 21 | public const string ERROR = "ERROR"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SampleHardwareServiceApp/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18408 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SampleHardwareServiceApp.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /StompHelper/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("StompHelper")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Ezypay")] 12 | [assembly: AssemblyProduct("StompHelper")] 13 | [assembly: AssemblyCopyright("Copyright © Ezypay 2015")] 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("df17f980-54da-439b-93f7-b561cbe5c9b7")] 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 | -------------------------------------------------------------------------------- /SampleHardwareServiceApp/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("SampleHardwareServiceApp")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Ezypay")] 12 | [assembly: AssemblyProduct("SampleHardwareServiceApp")] 13 | [assembly: AssemblyCopyright("Copyright © Ezypay 2015")] 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("2de0707b-d2a5-4c35-881b-ef8cafecb097")] 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 | -------------------------------------------------------------------------------- /SampleHardwareServiceWithStomp/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("SampleHardwareServiceWithStomp")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Ezypay")] 12 | [assembly: AssemblyProduct("SampleHardwareServiceWithStomp")] 13 | [assembly: AssemblyCopyright("Copyright © Ezypay 2015")] 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("9b79423e-3d7f-434d-ba66-8dbdba4862db")] 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 | -------------------------------------------------------------------------------- /SampleHardwareServiceWithStomp.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30723.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleHardwareServiceWithStomp", "SampleHardwareServiceWithStomp\SampleHardwareServiceWithStomp.csproj", "{916F3832-CB10-42FE-8442-F8A0C0764D4A}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleHardwareServiceApp", "SampleHardwareServiceApp\SampleHardwareServiceApp.csproj", "{6AD5867D-FEF5-4F60-A86E-371DF0B9CF58}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StompHelper", "StompHelper\StompHelper.csproj", "{4446ECFE-BC73-4483-B1CD-8AAA77D0248E}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {916F3832-CB10-42FE-8442-F8A0C0764D4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {916F3832-CB10-42FE-8442-F8A0C0764D4A}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {916F3832-CB10-42FE-8442-F8A0C0764D4A}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {916F3832-CB10-42FE-8442-F8A0C0764D4A}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {6AD5867D-FEF5-4F60-A86E-371DF0B9CF58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {6AD5867D-FEF5-4F60-A86E-371DF0B9CF58}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {6AD5867D-FEF5-4F60-A86E-371DF0B9CF58}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {6AD5867D-FEF5-4F60-A86E-371DF0B9CF58}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {4446ECFE-BC73-4483-B1CD-8AAA77D0248E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {4446ECFE-BC73-4483-B1CD-8AAA77D0248E}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {4446ECFE-BC73-4483-B1CD-8AAA77D0248E}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {4446ECFE-BC73-4483-B1CD-8AAA77D0248E}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /StompHelper/StompMessageSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace StompHelper 9 | { 10 | public class StompMessageSerializer 11 | { 12 | /// 13 | /// Serializes the specified message. 14 | /// 15 | /// The message. 16 | /// A serialized version of the given 17 | public string Serialize(StompMessage message) 18 | { 19 | var buffer = new StringBuilder(); 20 | 21 | buffer.Append(message.Command + "\n"); 22 | 23 | if (message.Headers != null) 24 | { 25 | foreach (var header in message.Headers) 26 | { 27 | buffer.Append(header.Key + ":" + header.Value + "\n"); 28 | } 29 | } 30 | 31 | buffer.Append("\n"); 32 | buffer.Append(message.Body); 33 | buffer.Append('\0'); 34 | 35 | return buffer.ToString(); 36 | } 37 | 38 | /// 39 | /// Deserializes the specified message. 40 | /// 41 | /// The message. 42 | /// A instance 43 | public StompMessage Deserialize(string message) 44 | { 45 | var reader = new StringReader(message); 46 | 47 | var command = reader.ReadLine(); 48 | 49 | var headers = new Dictionary(); 50 | 51 | var header = reader.ReadLine(); 52 | while (!string.IsNullOrEmpty(header)) 53 | { 54 | var split = header.Split(':'); 55 | if (split.Length == 2) headers[split[0].Trim()] = split[1].Trim(); 56 | header = reader.ReadLine() ?? string.Empty; 57 | } 58 | 59 | var body = reader.ReadToEnd() ?? string.Empty; 60 | body = body.TrimEnd('\r', '\n', '\0'); 61 | 62 | return new StompMessage(command, body, headers); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /StompHelper/StompMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StompHelper 8 | { 9 | public class StompMessage 10 | { 11 | private readonly Dictionary _headers = new Dictionary(); 12 | 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | /// The command. 17 | public StompMessage(string command) 18 | : this(command, string.Empty) 19 | { 20 | } 21 | 22 | /// 23 | /// Initializes a new instance of the class. 24 | /// 25 | /// The command. 26 | /// The body. 27 | public StompMessage(string command, string body) 28 | : this(command, body, new Dictionary()) 29 | { 30 | } 31 | 32 | /// 33 | /// Initializes a new instance of the class. 34 | /// 35 | /// The command. 36 | /// The body. 37 | /// The headers. 38 | internal StompMessage(string command, string body, Dictionary headers) 39 | { 40 | Command = command; 41 | Body = body; 42 | _headers = headers; 43 | 44 | this["content-length"] = body.Length.ToString(); 45 | } 46 | 47 | public Dictionary Headers 48 | { 49 | get { return _headers; } 50 | } 51 | 52 | /// 53 | /// Gets the body. 54 | /// 55 | public string Body { get; private set; } 56 | 57 | /// 58 | /// Gets the command. 59 | /// 60 | public string Command { get; private set; } 61 | 62 | /// 63 | /// Gets or sets the specified header attribute. 64 | /// 65 | public string this[string header] 66 | { 67 | get { return _headers.ContainsKey(header) ? _headers[header] : string.Empty; } 68 | set { _headers[header] = value; } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /StompHelper/StompHelper.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {4446ECFE-BC73-4483-B1CD-8AAA77D0248E} 8 | Library 9 | Properties 10 | StompHelper 11 | StompHelper 12 | v4.5.1 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 | 55 | -------------------------------------------------------------------------------- /SampleHardwareServiceApp/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18408 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SampleHardwareServiceApp.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SampleHardwareServiceApp.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /SampleHardwareServiceWithStomp/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using Newtonsoft.Json; 8 | using StompHelper; 9 | //using System.Net.WebSockets; 10 | using WebSocketSharp; 11 | 12 | namespace SampleHardwareServiceWithStomp 13 | { 14 | class Program 15 | { 16 | static void Main(string[] args) 17 | { 18 | using (var ws = new WebSocket("ws://localhost:8080/spring-websocket-stomp-apollo/chat/websocket")) 19 | { 20 | ws.OnMessage += ws_OnMessage; 21 | ws.OnOpen += ws_OnOpen; 22 | ws.OnError += ws_OnError; 23 | ws.Connect(); 24 | Thread.Sleep(1000); 25 | 26 | StompMessageSerializer serializer = new StompMessageSerializer(); 27 | 28 | var connect = new StompMessage("CONNECT"); 29 | connect["accept-version"] = "1.2"; 30 | connect["host"] = ""; 31 | ws.Send(serializer.Serialize(connect)); 32 | 33 | var clientId = RandomString(5); 34 | Console.WriteLine("Client Id :" + clientId); 35 | Thread.Sleep(1000); 36 | 37 | var sub = new StompMessage("SUBSCRIBE"); 38 | sub["id"] = "sub-0"; 39 | sub["destination"] = "/topic/broadcast"; 40 | ws.Send(serializer.Serialize(sub)); 41 | 42 | var sub1 = new StompMessage("SUBSCRIBE"); 43 | sub1["id"] = "sub-1"; 44 | sub1["destination"] = "/queue/message-" + clientId; 45 | ws.Send(serializer.Serialize(sub1)); 46 | 47 | Thread.Sleep(1000); 48 | var content = new Content(){ Subject ="Stomp client", Message = "Hello World!!"}; 49 | var broad = new StompMessage("SEND", JsonConvert.SerializeObject(content)); 50 | broad["content-type"] = "application/json"; 51 | broad["destination"] = "/app/broadcast"; 52 | ws.Send(serializer.Serialize(broad)); 53 | 54 | Console.ReadKey(true); 55 | } 56 | 57 | } 58 | 59 | public static string RandomString(int length) 60 | { 61 | const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 62 | var random = new Random(); 63 | return new string(Enumerable.Repeat(chars, length) 64 | .Select(s => s[random.Next(s.Length)]).ToArray()); 65 | } 66 | static void ws_OnOpen(object sender, EventArgs e) 67 | { 68 | Console.WriteLine(DateTime.Now.ToString() + " ws_OnOpen says: " + e.ToString()); 69 | } 70 | 71 | static void ws_OnMessage(object sender, MessageEventArgs e) 72 | { 73 | Console.WriteLine("-----------------------------"); 74 | Console.WriteLine(DateTime.Now.ToString() + " ws_OnMessage says: " + e.Data); 75 | 76 | } 77 | 78 | static void ws_OnError(object sender, ErrorEventArgs e) 79 | { 80 | Console.WriteLine(DateTime.Now.ToString() + " ws_OnError says: " + e.Message); 81 | } 82 | 83 | public class Content 84 | { 85 | public string Subject { get; set; } 86 | public string Message { get; set; } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /SampleHardwareServiceWithStomp/SampleHardwareServiceWithStomp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {916F3832-CB10-42FE-8442-F8A0C0764D4A} 8 | Exe 9 | Properties 10 | SampleHardwareServiceWithStomp 11 | SampleHardwareServiceWithStomp 12 | v4.5.1 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | False 38 | ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | ..\packages\WebSocketSharp.1.0.3-rc9\lib\websocket-sharp.dll 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | {4446ecfe-bc73-4483-b1cd-8aaa77d0248e} 62 | StompHelper 63 | 64 | 65 | 66 | 73 | -------------------------------------------------------------------------------- /SampleHardwareServiceApp/SampleHardwareServiceApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6AD5867D-FEF5-4F60-A86E-371DF0B9CF58} 8 | WinExe 9 | Properties 10 | SampleHardwareServiceApp 11 | SampleHardwareServiceApp 12 | v4.5.1 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | False 38 | ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | ..\packages\WebSocketSharp.1.0.3-rc9\lib\websocket-sharp.dll 52 | 53 | 54 | 55 | 56 | Form 57 | 58 | 59 | Form1.cs 60 | 61 | 62 | 63 | 64 | Form1.cs 65 | 66 | 67 | ResXFileCodeGenerator 68 | Resources.Designer.cs 69 | Designer 70 | 71 | 72 | True 73 | Resources.resx 74 | 75 | 76 | 77 | SettingsSingleFileGenerator 78 | Settings.Designer.cs 79 | 80 | 81 | True 82 | Settings.settings 83 | True 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | {4446ecfe-bc73-4483-b1cd-8aaa77d0248e} 92 | StompHelper 93 | 94 | 95 | 96 | 103 | -------------------------------------------------------------------------------- /SampleHardwareServiceApp/Form1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using Newtonsoft.Json; 11 | using StompHelper; 12 | using WebSocketSharp; 13 | 14 | namespace SampleHardwareServiceApp 15 | { 16 | public partial class Form1 : Form 17 | { 18 | public Form1() 19 | { 20 | InitializeComponent(); 21 | } 22 | 23 | WebSocket ws = new WebSocket("ws://localhost:8080/spring-websocket-stomp-apollo/chat/websocket"); 24 | StompMessageSerializer serializer = new StompMessageSerializer(); 25 | String clientId = string.Empty; 26 | 27 | private void button1_Click(object sender, EventArgs e) 28 | { 29 | ws.OnMessage += ws_OnMessage; 30 | ws.OnClose += ws_OnClose; 31 | ws.OnOpen += ws_OnOpen; 32 | ws.OnError += ws_OnError; 33 | ws.Connect(); 34 | 35 | this.clientId = RandomString(5); 36 | this.label3.Text = this.clientId; 37 | } 38 | private void ConnectStomp() 39 | { 40 | var connect = new StompMessage(StompFrame.CONNECT); 41 | connect["accept-version"] = "1.2"; 42 | connect["host"] = ""; 43 | // first number Zero mean client not able to send Heartbeat, 44 | //Second number mean Server will sending heartbeat to client instead 45 | connect["heart-beat"] = "0,10000"; 46 | ws.Send(serializer.Serialize(connect)); 47 | } 48 | 49 | private void SubscribeStomp() 50 | { 51 | var sub = new StompMessage(StompFrame.SUBSCRIBE); 52 | //unique Key per subscription 53 | sub["id"] = "sub-0"; 54 | sub["destination"] = "/topic/broadcast"; 55 | ws.Send(serializer.Serialize(sub)); 56 | 57 | var sub1 = new StompMessage(StompFrame.SUBSCRIBE); 58 | //unique Key per subscription 59 | sub1["id"] = "sub-1"; 60 | sub1["destination"] = "/queue/message-" + clientId; 61 | ws.Send(serializer.Serialize(sub1)); 62 | } 63 | 64 | private void button3_Click(object sender, EventArgs e) 65 | { 66 | var content = new Content() { Subject = "Stomp client", Message = "Hello World!!" }; 67 | var broad = new StompMessage(StompFrame.SEND, JsonConvert.SerializeObject(content)); 68 | broad["content-type"] = "application/json"; 69 | broad["destination"] = "/app/broadcast"; 70 | ws.Send(serializer.Serialize(broad)); 71 | } 72 | 73 | private void button2_Click(object sender, EventArgs e) 74 | { 75 | var content = new Content() { Subject = "Stomp client", Message = "Hello World!!" }; 76 | var broad = new StompMessage(StompFrame.SEND, JsonConvert.SerializeObject(content)); 77 | broad["content-type"] = "application/json"; 78 | broad["destination"] = "/queue/message-" + txtTarget.Text; 79 | ws.Send(serializer.Serialize(broad)); 80 | } 81 | 82 | void ws_OnOpen(object sender, EventArgs e) 83 | { 84 | UpdateListBox(" ws_OnOpen says: " + e.ToString()); 85 | ConnectStomp(); 86 | } 87 | 88 | void ws_OnMessage(object sender, MessageEventArgs e) 89 | { 90 | Console.WriteLine("-----------------------------"); 91 | Console.WriteLine(" ws_OnMessage says: " + e.Data); 92 | StompMessage msg = serializer.Deserialize(e.Data); 93 | if (msg.Command == StompFrame.CONNECTED) 94 | { 95 | UpdateListBox(e.Data); 96 | SubscribeStomp(); 97 | } 98 | else if (msg.Command == StompFrame.MESSAGE) 99 | { 100 | UpdateListBox(e.Data); 101 | } 102 | } 103 | 104 | void ws_OnClose(object sender, CloseEventArgs e) 105 | { 106 | UpdateListBox(" ws_OnClose says: " + e.ToString()); 107 | ConnectStomp(); 108 | } 109 | 110 | 111 | void UpdateListBox(string data) 112 | { 113 | if (this.listBox1.InvokeRequired) 114 | { 115 | this.listBox1.Invoke(new MethodInvoker(delegate { UpdateListBox(DateTime.Now.ToString() + data); })); 116 | } 117 | else 118 | this.listBox1.Items.Add(data); 119 | } 120 | 121 | void ws_OnError(object sender, ErrorEventArgs e) 122 | { 123 | UpdateListBox(DateTime.Now.ToString() + " ws_OnError says: " + e.ToString()); 124 | } 125 | 126 | public class Content 127 | { 128 | public string Subject { get; set; } 129 | public string Message { get; set; } 130 | } 131 | public string RandomString(int length) 132 | { 133 | const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 134 | var random = new Random(); 135 | return new string(Enumerable.Repeat(chars, length) 136 | .Select(s => s[random.Next(s.Length)]).ToArray()); 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /SampleHardwareServiceApp/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /SampleHardwareServiceApp/Form1.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /SampleHardwareServiceApp/Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SampleHardwareServiceApp 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.button1 = new System.Windows.Forms.Button(); 32 | this.label1 = new System.Windows.Forms.Label(); 33 | this.label2 = new System.Windows.Forms.Label(); 34 | this.button2 = new System.Windows.Forms.Button(); 35 | this.txtTarget = new System.Windows.Forms.TextBox(); 36 | this.button3 = new System.Windows.Forms.Button(); 37 | this.listBox1 = new System.Windows.Forms.ListBox(); 38 | this.label3 = new System.Windows.Forms.Label(); 39 | this.SuspendLayout(); 40 | // 41 | // button1 42 | // 43 | this.button1.Location = new System.Drawing.Point(11, 33); 44 | this.button1.Name = "button1"; 45 | this.button1.Size = new System.Drawing.Size(75, 23); 46 | this.button1.TabIndex = 0; 47 | this.button1.Text = "Connect"; 48 | this.button1.UseVisualStyleBackColor = true; 49 | this.button1.Click += new System.EventHandler(this.button1_Click); 50 | // 51 | // label1 52 | // 53 | this.label1.AutoSize = true; 54 | this.label1.Location = new System.Drawing.Point(8, 8); 55 | this.label1.Name = "label1"; 56 | this.label1.Size = new System.Drawing.Size(51, 13); 57 | this.label1.TabIndex = 1; 58 | this.label1.Text = "ClientId : "; 59 | // 60 | // label2 61 | // 62 | this.label2.AutoSize = true; 63 | this.label2.Location = new System.Drawing.Point(89, 8); 64 | this.label2.Name = "label2"; 65 | this.label2.Size = new System.Drawing.Size(85, 13); 66 | this.label2.TabIndex = 2; 67 | this.label2.Text = "Target ClientId : "; 68 | // 69 | // button2 70 | // 71 | this.button2.Location = new System.Drawing.Point(198, 33); 72 | this.button2.Name = "button2"; 73 | this.button2.Size = new System.Drawing.Size(75, 23); 74 | this.button2.TabIndex = 3; 75 | this.button2.Text = "Send"; 76 | this.button2.UseVisualStyleBackColor = true; 77 | this.button2.Click += new System.EventHandler(this.button2_Click); 78 | // 79 | // txtTarget 80 | // 81 | this.txtTarget.Location = new System.Drawing.Point(173, 5); 82 | this.txtTarget.Name = "txtTarget"; 83 | this.txtTarget.Size = new System.Drawing.Size(100, 20); 84 | this.txtTarget.TabIndex = 4; 85 | // 86 | // button3 87 | // 88 | this.button3.Location = new System.Drawing.Point(108, 33); 89 | this.button3.Name = "button3"; 90 | this.button3.Size = new System.Drawing.Size(75, 23); 91 | this.button3.TabIndex = 5; 92 | this.button3.Text = "Broadcast"; 93 | this.button3.UseVisualStyleBackColor = true; 94 | this.button3.Click += new System.EventHandler(this.button3_Click); 95 | // 96 | // listBox1 97 | // 98 | this.listBox1.FormattingEnabled = true; 99 | this.listBox1.Location = new System.Drawing.Point(11, 72); 100 | this.listBox1.Name = "listBox1"; 101 | this.listBox1.Size = new System.Drawing.Size(546, 173); 102 | this.listBox1.TabIndex = 6; 103 | // 104 | // label3 105 | // 106 | this.label3.AutoSize = true; 107 | this.label3.Location = new System.Drawing.Point(54, 9); 108 | this.label3.Name = "label3"; 109 | this.label3.Size = new System.Drawing.Size(0, 13); 110 | this.label3.TabIndex = 7; 111 | // 112 | // Form1 113 | // 114 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 115 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 116 | this.ClientSize = new System.Drawing.Size(569, 262); 117 | this.Controls.Add(this.label3); 118 | this.Controls.Add(this.listBox1); 119 | this.Controls.Add(this.button3); 120 | this.Controls.Add(this.txtTarget); 121 | this.Controls.Add(this.button2); 122 | this.Controls.Add(this.label2); 123 | this.Controls.Add(this.label1); 124 | this.Controls.Add(this.button1); 125 | this.Name = "Form1"; 126 | this.Text = "Form1"; 127 | this.ResumeLayout(false); 128 | this.PerformLayout(); 129 | 130 | } 131 | 132 | #endregion 133 | 134 | private System.Windows.Forms.Button button1; 135 | private System.Windows.Forms.Label label1; 136 | private System.Windows.Forms.Label label2; 137 | private System.Windows.Forms.Button button2; 138 | private System.Windows.Forms.TextBox txtTarget; 139 | private System.Windows.Forms.Button button3; 140 | private System.Windows.Forms.ListBox listBox1; 141 | private System.Windows.Forms.Label label3; 142 | } 143 | } 144 | 145 | --------------------------------------------------------------------------------