Jekyll2023-02-14T16:33:45+00:00https://stomp-js.github.io/feed.xmlStompJS FamilyJavascript/Typescript client for STOMP protocol. Specialized versions for RxJS/Angular.stompjsng2-stompjs to rx-stomp2022-03-01T19:21:00+00:002022-03-01T19:21:00+00:00https://stomp-js.github.io/guide/rx-stomp/ng2-stompjs/ng2-stompjs-to-rx-stomp<p>These steps have been tested with Angular 7 and Angular 13. So these should work for Angular 7+.</p>
<p>See also <a href="/guide/rx-stomp/rx-stomp-with-angular.html">Using rx-stomp with Angular</a>.</p>
<h2 id="instructions">Instructions</h2>
<h3 id="compile-target">Compile target</h3>
<p><a href="/api-docs/latest/classes/RxStomp.html">rx-stomp</a> uses ES6 classes, so the Angular project needs to set compile target at least <code class="language-plaintext highlighter-rouge">es6</code>. Please check and adjust <code class="language-plaintext highlighter-rouge">target</code> in your <code class="language-plaintext highlighter-rouge">tsconfig.json</code>.</p>
<h3 id="uninstall-ng2-stompjs-install-rx-stomp">Uninstall ng2-stompjs, install rx-stomp</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>npm uninstall @stomp/ng2-stompjs
<span class="nv">$ </span>npm i @stomp/rx-stomp
</code></pre></div></div>
<h3 id="change-classes-and-imports">Change classes and imports</h3>
<p>Change <code class="language-plaintext highlighter-rouge">InjectableRxStompConfig</code> from <code class="language-plaintext highlighter-rouge">@stomp/ng2-stompjs</code> -> <a href="/api-docs/latest/classes/RxStompConfig.html">RxStompConfig</a> from <code class="language-plaintext highlighter-rouge">@stomp/rx-stomp</code>.</p>
<p>Next, we will create <code class="language-plaintext highlighter-rouge">RxStompService</code> and <code class="language-plaintext highlighter-rouge">rxStompServiceFactory</code>. These were provided by <code class="language-plaintext highlighter-rouge">ng2-stompjs</code>. If you were using code similar to the tutorials, the following would work as-is.</p>
<p>Create <code class="language-plaintext highlighter-rouge">rx-stomp.service.ts</code> file inside <code class="language-plaintext highlighter-rouge">src/app/</code> with the following content:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">Injectable</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@angular/core</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">RxStomp</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@stomp/rx-stomp</span><span class="dl">'</span><span class="p">;</span>
<span class="p">@</span><span class="nd">Injectable</span><span class="p">({</span>
<span class="na">providedIn</span><span class="p">:</span> <span class="dl">'</span><span class="s1">root</span><span class="dl">'</span><span class="p">,</span>
<span class="p">})</span>
<span class="k">export</span> <span class="kd">class</span> <span class="nx">RxStompService</span> <span class="kd">extends</span> <span class="nx">RxStomp</span> <span class="p">{</span>
<span class="kd">constructor</span><span class="p">()</span> <span class="p">{</span>
<span class="k">super</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Create <code class="language-plaintext highlighter-rouge">rx-stomp-service-factory.ts</code> file inside <code class="language-plaintext highlighter-rouge">src/app/</code> with the following content:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">RxStompService</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./rx-stomp.service</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">myRxStompConfig</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./my-rx-stomp.config</span><span class="dl">'</span><span class="p">;</span>
<span class="k">export</span> <span class="kd">function</span> <span class="nx">rxStompServiceFactory</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">rxStomp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">RxStompService</span><span class="p">();</span>
<span class="nx">rxStomp</span><span class="p">.</span><span class="nx">configure</span><span class="p">(</span><span class="nx">myRxStompConfig</span><span class="p">);</span>
<span class="nx">rxStomp</span><span class="p">.</span><span class="nx">activate</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">rxStomp</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>If you are using a custom setup, you may need to adjust the factory code.</p>
<h3 id="angular-di-setup">Angular DI setup</h3>
<p>You will need to update the configuration for Angular DI.</p>
<p>Remove the provider configuration for <code class="language-plaintext highlighter-rouge">InjectableRxStompConfig</code> and adjust the setup for <code class="language-plaintext highlighter-rouge">RxStompService</code>.</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">providers</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="na">provide</span><span class="p">:</span> <span class="nx">RxStompService</span><span class="p">,</span>
<span class="na">useFactory</span><span class="p">:</span> <span class="nx">rxStompServiceFactory</span><span class="p">,</span>
<span class="p">},</span>
<span class="p">];</span>
</code></pre></div></div>
<p>Remove the old imports and add the imports from the newly created modules.</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">RxStompService</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./rx-stomp.service</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">rxStompServiceFactory</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./rx-stomp-service-factory</span><span class="dl">'</span><span class="p">;</span>
</code></pre></div></div>
<h3 id="adjust-imports">Adjust imports</h3>
<p>Change the import path for <code class="language-plaintext highlighter-rouge">RxStompService</code> from <code class="language-plaintext highlighter-rouge">@stomp/ng2-stompjs</code> to the local module.</p>StompJSThese steps have been tested with Angular 7 and Angular 13. So these should work for Angular 7+.rx-stomp with Angular2022-03-01T03:50:00+00:002022-03-01T03:50:00+00:00https://stomp-js.github.io/guide/rx-stomp/rx-stomp-with-angular<p>This step-by-step guide will create a new Angular application
and demonstrate usage of <a href="/api-docs/latest/classes/RxStomp.html">rx-stomp</a>.</p>
<p>While preparing this guide, <code class="language-plaintext highlighter-rouge">Angular</code> <code class="language-plaintext highlighter-rouge">13.2.0</code> and
<code class="language-plaintext highlighter-rouge">@stomp/rx-stomp</code> <code class="language-plaintext highlighter-rouge">1.1.4</code> are used.</p>
<p>For the impatient, the final code from this tutorial is at:
<a href="https://github.com/stomp-js/rx-stomp-angular">https://github.com/stomp-js/rx-stomp-angular</a></p>
<h2 id="prerequisites">Prerequisites</h2>
<p>You need to have <a href="https://nodejs.org">Node.js</a>
and <a href="https://www.npmjs.com/">npm</a> installed.</p>
<p>You must have basic familiarity with Angular and Typescript.
If you are unsure, please go through the famous <a href="https://angular.io/tutorial">Tour of Heroes</a>.</p>
<h2 id="instructions">Instructions</h2>
<h3 id="create-a-new-angular-application">Create a new Angular Application</h3>
<p>Install the latest Angular CLI as below:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>npm i @angular/cli <span class="nt">-g</span>
</code></pre></div></div>
<p>Change to the intended folder and create your new application:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>ng new rx-stomp-angular <span class="nt">--skip-install</span> <span class="nt">--defaults</span>
</code></pre></div></div>
<p>Change to newly created folder and install all dependencies:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">cd </span>rx-stomp-angular/
<span class="nv">$ </span>npm i
</code></pre></div></div>
<p>To run the application locally, execute the following and
point your browser to <a href="http://localhost:4200/">http://localhost:4200/</a>.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>ng serve
</code></pre></div></div>
<p>You can keep it running in a terminal and keep the browser tab open.
It will detect changes, recompile and reload the browser tab.</p>
<p><em>At this stage, you can use your favorite IDE and be ready to edit the code.</em></p>
<h3 id="add-stomprx-stomp-inject-rxstompservice">Add @stomp/rx-stomp, Inject RxStompService</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>npm i @stomp/rx-stomp
</code></pre></div></div>
<p>We will need to define our configuration.
This configuration will get injected by the Angular Dependency Injection mechanism
while creating an instance of <code class="language-plaintext highlighter-rouge">RxStompService</code>.</p>
<h4 id="configuration">Configuration</h4>
<p>Create <code class="language-plaintext highlighter-rouge">my-rx-stomp.config.ts</code> file inside <code class="language-plaintext highlighter-rouge">src/app/</code> with the following content:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">RxStompConfig</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@stomp/rx-stomp</span><span class="dl">'</span><span class="p">;</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">myRxStompConfig</span><span class="p">:</span> <span class="nx">RxStompConfig</span> <span class="o">=</span> <span class="p">{</span>
<span class="c1">// Which server?</span>
<span class="na">brokerURL</span><span class="p">:</span> <span class="dl">'</span><span class="s1">ws://127.0.0.1:15674/ws</span><span class="dl">'</span><span class="p">,</span>
<span class="c1">// Headers</span>
<span class="c1">// Typical keys: login, passcode, host</span>
<span class="na">connectHeaders</span><span class="p">:</span> <span class="p">{</span>
<span class="na">login</span><span class="p">:</span> <span class="dl">'</span><span class="s1">guest</span><span class="dl">'</span><span class="p">,</span>
<span class="na">passcode</span><span class="p">:</span> <span class="dl">'</span><span class="s1">guest</span><span class="dl">'</span><span class="p">,</span>
<span class="p">},</span>
<span class="c1">// How often to heartbeat?</span>
<span class="c1">// Interval in milliseconds, set to 0 to disable</span>
<span class="na">heartbeatIncoming</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="c1">// Typical value 0 - disabled</span>
<span class="na">heartbeatOutgoing</span><span class="p">:</span> <span class="mi">20000</span><span class="p">,</span> <span class="c1">// Typical value 20000 - every 20 seconds</span>
<span class="c1">// Wait in milliseconds before attempting auto reconnect</span>
<span class="c1">// Set to 0 to disable</span>
<span class="c1">// Typical value 500 (500 milli seconds)</span>
<span class="na">reconnectDelay</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span>
<span class="c1">// Will log diagnostics on console</span>
<span class="c1">// It can be quite verbose, not recommended in production</span>
<span class="c1">// Skip this key to stop logging to console</span>
<span class="na">debug</span><span class="p">:</span> <span class="p">(</span><span class="na">msg</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="k">void</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="k">new</span> <span class="nb">Date</span><span class="p">(),</span> <span class="nx">msg</span><span class="p">);</span>
<span class="p">},</span>
<span class="p">};</span>
</code></pre></div></div>
<p>The above should work for an out-of-the-box installation of RabbitMQ broker.
Please change as per your broker configuration.</p>
<h4 id="the-rxstompservice">The RxStompService</h4>
<p>Create <code class="language-plaintext highlighter-rouge">rx-stomp.service.ts</code> file inside <code class="language-plaintext highlighter-rouge">src/app/</code> with the following content:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">Injectable</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@angular/core</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">RxStomp</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@stomp/rx-stomp</span><span class="dl">'</span><span class="p">;</span>
<span class="p">@</span><span class="nd">Injectable</span><span class="p">({</span>
<span class="na">providedIn</span><span class="p">:</span> <span class="dl">'</span><span class="s1">root</span><span class="dl">'</span><span class="p">,</span>
<span class="p">})</span>
<span class="k">export</span> <span class="kd">class</span> <span class="nx">RxStompService</span> <span class="kd">extends</span> <span class="nx">RxStomp</span> <span class="p">{</span>
<span class="kd">constructor</span><span class="p">()</span> <span class="p">{</span>
<span class="k">super</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="factory-to-create-and-initialize-rxstompservice">Factory to create and initialize RxStompService</h4>
<p>Create <code class="language-plaintext highlighter-rouge">rx-stomp-service-factory.ts</code> file inside <code class="language-plaintext highlighter-rouge">src/app/</code> with the following content:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">RxStompService</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./rx-stomp.service</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">myRxStompConfig</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./my-rx-stomp.config</span><span class="dl">'</span><span class="p">;</span>
<span class="k">export</span> <span class="kd">function</span> <span class="nx">rxStompServiceFactory</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">rxStomp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">RxStompService</span><span class="p">();</span>
<span class="nx">rxStomp</span><span class="p">.</span><span class="nx">configure</span><span class="p">(</span><span class="nx">myRxStompConfig</span><span class="p">);</span>
<span class="nx">rxStomp</span><span class="p">.</span><span class="nx">activate</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">rxStomp</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="angular-di-setup">Angular DI setup</h4>
<p>Next, we need the service to get injected. Open <code class="language-plaintext highlighter-rouge">src/app/app.module.ts</code>
Add the following to the <code class="language-plaintext highlighter-rouge">providers</code> array of your <code class="language-plaintext highlighter-rouge">@NgModule</code>:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">providers</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="na">provide</span><span class="p">:</span> <span class="nx">RxStompService</span><span class="p">,</span>
<span class="na">useFactory</span><span class="p">:</span> <span class="nx">rxStompServiceFactory</span><span class="p">,</span>
<span class="p">},</span>
<span class="p">];</span>
</code></pre></div></div>
<p>Also, add appropriate import lines towards the top of this file (after the existing import
statements):</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">RxStompService</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./rx-stomp.service</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">rxStompServiceFactory</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./rx-stomp-service-factory</span><span class="dl">'</span><span class="p">;</span>
</code></pre></div></div>
<h3 id="messages">Messages</h3>
<p>We will create a component that will do the following:</p>
<ul>
<li>It will have a clickable button to send a message.</li>
<li>It will subscribe and keep listing all received messages.</li>
</ul>
<h4 id="skeleton">Skeleton</h4>
<p>Create the <code class="language-plaintext highlighter-rouge">Messages</code> component:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>ng generate component messages
</code></pre></div></div>
<p>Inspect the files generated in <code class="language-plaintext highlighter-rouge">src/app/messages/</code>.</p>
<p>Now we will create the basic HTML in
<code class="language-plaintext highlighter-rouge">src/app/messages/messages.component.html</code> - put the following content:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><div</span> <span class="na">id=</span><span class="s">"messages"</span><span class="nt">></span>
<span class="nt"><button</span> <span class="na">class=</span><span class="s">"btn btn-primary"</span><span class="nt">></span>Send Test Message<span class="nt"></button></span>
<span class="nt"><h2></span>Received messages<span class="nt"></h2></span>
<span class="nt"><ol></span>
<span class="c"><!-- we will use Angular binding to populate list of messages --></span>
<span class="nt"><li</span> <span class="na">class=</span><span class="s">"message"</span><span class="nt">></span>message<span class="nt"></li></span>
<span class="nt"></ol></span>
<span class="nt"></div></span>
</code></pre></div></div>
<p>We will add this component to the main UI by editing <code class="language-plaintext highlighter-rouge">src/app/app.component.html</code>.
We will remove most of the default HTML generated by Angular CLI in this process.
Edit <code class="language-plaintext highlighter-rouge">src/app/app.component.html</code> to look like the following:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><div</span> <span class="na">style=</span><span class="s">"text-align:center"</span><span class="nt">></span>
<span class="nt"><h1></span>Welcome to !<span class="nt"></h1></span>
<span class="nt"></div></span>
<span class="nt"><app-messages></app-messages></span>
</code></pre></div></div>
<p>Now is a great time to check the browser tab to see that display has changed
and it should show the HTML that we have added to <code class="language-plaintext highlighter-rouge">src/app/messages/messages.component.html</code>.</p>
<p>If you find an empty screen, please check the terminal where you executed <code class="language-plaintext highlighter-rouge">ng serve</code>.
If there are compilation errors, you will see them here. Also, check the browser Javascript console. Sometimes, you may notice errors here.</p>
<h4 id="sending-messages">Sending messages</h4>
<p>We will now inject <code class="language-plaintext highlighter-rouge">RxStompService</code> as a dependency in <code class="language-plaintext highlighter-rouge">MessageComponent</code>.
To achieve that, we will add it to the constructor in <code class="language-plaintext highlighter-rouge">src/app/messages/messages.component.ts</code>,
which should look like the following:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">rxStompService</span><span class="p">:</span> <span class="nx">RxStompService</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span>
</code></pre></div></div>
<p>We will now add code to send a message:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nx">onSendMessage</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">message</span> <span class="o">=</span> <span class="s2">`Message generated at </span><span class="p">${</span><span class="k">new</span> <span class="nb">Date</span><span class="p">()}</span><span class="s2">`</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">rxStompService</span><span class="p">.</span><span class="nx">publish</span><span class="p">({</span> <span class="na">destination</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/topic/demo</span><span class="dl">'</span><span class="p">,</span> <span class="na">body</span><span class="p">:</span> <span class="nx">message</span> <span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>
<p><em>Please see <a href="/api-docs/latest/classes/RxStomp.html#publish">RxStomp#publish</a>.
Keep this page open as we will be using more methods from this class soon.</em></p>
<p>The entire content of <code class="language-plaintext highlighter-rouge">src/app/messages/messages.component.ts</code> should look like
the following:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">Component</span><span class="p">,</span> <span class="nx">OnInit</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@angular/core</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">RxStompService</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">../rx-stomp.service</span><span class="dl">'</span><span class="p">;</span>
<span class="p">@</span><span class="nd">Component</span><span class="p">({</span>
<span class="na">selector</span><span class="p">:</span> <span class="dl">'</span><span class="s1">app-messages</span><span class="dl">'</span><span class="p">,</span>
<span class="na">templateUrl</span><span class="p">:</span> <span class="dl">'</span><span class="s1">./messages.component.html</span><span class="dl">'</span><span class="p">,</span>
<span class="na">styleUrls</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">./messages.component.css</span><span class="dl">'</span><span class="p">],</span>
<span class="p">})</span>
<span class="k">export</span> <span class="kd">class</span> <span class="nx">MessagesComponent</span> <span class="k">implements</span> <span class="nx">OnInit</span> <span class="p">{</span>
<span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">rxStompService</span><span class="p">:</span> <span class="nx">RxStompService</span><span class="p">)</span> <span class="p">{}</span>
<span class="nx">ngOnInit</span><span class="p">():</span> <span class="k">void</span> <span class="p">{}</span>
<span class="nx">onSendMessage</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">message</span> <span class="o">=</span> <span class="s2">`Message generated at </span><span class="p">${</span><span class="k">new</span> <span class="nb">Date</span><span class="p">()}</span><span class="s2">`</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">rxStompService</span><span class="p">.</span><span class="nx">publish</span><span class="p">({</span> <span class="na">destination</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/topic/demo</span><span class="dl">'</span><span class="p">,</span> <span class="na">body</span><span class="p">:</span> <span class="nx">message</span> <span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>We will attach <code class="language-plaintext highlighter-rouge">onSendMessage</code> to the button in the HTML.
Edit <code class="language-plaintext highlighter-rouge">src/app/messages/messages.component.html</code> and add <code class="language-plaintext highlighter-rouge">(click)="onSendMessage()"</code>
to the button. The file should look like the following now:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><div</span> <span class="na">id=</span><span class="s">"messages"</span><span class="nt">></span>
<span class="nt"><button</span> <span class="na">class=</span><span class="s">"btn btn-primary"</span> <span class="na">(click)=</span><span class="s">"onSendMessage()"</span><span class="nt">></span>
Send Test Message
<span class="nt"></button></span>
<span class="nt"><h2></span>Received messages<span class="nt"></h2></span>
<span class="nt"><ol></span>
<span class="c"><!-- we will use Angular binding to populate list of messages --></span>
<span class="nt"><li</span> <span class="na">class=</span><span class="s">"message"</span><span class="nt">></span>message<span class="nt"></li></span>
<span class="nt"></ol></span>
<span class="nt"></div></span>
</code></pre></div></div>
<p>You should go back to the browser tab and open the web console at this stage.
When you click on the <code class="language-plaintext highlighter-rouge">Send Message</code> button, you can see that the message
is being sent to the broker in the console.</p>
<h4 id="receiving-messages">Receiving messages</h4>
<p>The <a href="/api-docs/latest/classes/RxStomp.html#watch">RxStomp#watch</a> method
initiates a subscription with the broker.
<code class="language-plaintext highlighter-rouge">this.rxStompService.watch('/topic/demo')</code> will initiate a subscription
with the broker for topic <code class="language-plaintext highlighter-rouge">/topic/demo</code> and returns an <code class="language-plaintext highlighter-rouge">RxJS Observable</code>.
Typically we will subscribe this <code class="language-plaintext highlighter-rouge">Observable</code> to receive actual messages.</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nx">ngOnInit</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">rxStompService</span><span class="p">.</span><span class="nx">watch</span><span class="p">(</span><span class="dl">'</span><span class="s1">/topic/demo</span><span class="dl">'</span><span class="p">).</span><span class="nx">subscribe</span><span class="p">((</span><span class="nx">message</span><span class="p">:</span> <span class="nx">Message</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">receivedMessages</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">message</span><span class="p">.</span><span class="nx">body</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>
<p>We will need to add a declaration for <code class="language-plaintext highlighter-rouge">receivedMessages</code> and import <code class="language-plaintext highlighter-rouge">Message</code> from <code class="language-plaintext highlighter-rouge">@stomp/stompjs</code>.
A few other modules also expose <code class="language-plaintext highlighter-rouge">Message</code> classes, so you need to be careful.</p>
<p><em>If you are coming from <code class="language-plaintext highlighter-rouge">@stomp/stompjs</code>, please notice that you do not
need to subscribe within the callback of stomp getting connected.
This library internally ensures that actual subscription happens
when the broker is actually connected.
It also keeps tracking of broker re-connections and automatically resubscribes.</em></p>
<p>Now is the time to link the HTML template to the received messages.
We will use <code class="language-plaintext highlighter-rouge">ngFor</code> to bind the list of messages to <code class="language-plaintext highlighter-rouge"><li></code>.
Edit <code class="language-plaintext highlighter-rouge">src/app/messages/messages.component.html</code>:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><li</span> <span class="na">class=</span><span class="s">"message"</span> <span class="na">*ngFor=</span><span class="s">"let message of receivedMessages"</span><span class="nt">></li></span>
</code></pre></div></div>
<p>Now your <code class="language-plaintext highlighter-rouge">src/app/messages/messages.component.ts</code> and
<code class="language-plaintext highlighter-rouge">src/app/messages/messages.component.html</code> should look like:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">Component</span><span class="p">,</span> <span class="nx">OnInit</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@angular/core</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">RxStompService</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">../rx-stomp.service</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">Message</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@stomp/stompjs</span><span class="dl">'</span><span class="p">;</span>
<span class="p">@</span><span class="nd">Component</span><span class="p">({</span>
<span class="na">selector</span><span class="p">:</span> <span class="dl">'</span><span class="s1">app-messages</span><span class="dl">'</span><span class="p">,</span>
<span class="na">templateUrl</span><span class="p">:</span> <span class="dl">'</span><span class="s1">./messages.component.html</span><span class="dl">'</span><span class="p">,</span>
<span class="na">styleUrls</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">./messages.component.css</span><span class="dl">'</span><span class="p">],</span>
<span class="p">})</span>
<span class="k">export</span> <span class="kd">class</span> <span class="nx">MessagesComponent</span> <span class="k">implements</span> <span class="nx">OnInit</span> <span class="p">{</span>
<span class="nl">receivedMessages</span><span class="p">:</span> <span class="kr">string</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>
<span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">rxStompService</span><span class="p">:</span> <span class="nx">RxStompService</span><span class="p">)</span> <span class="p">{}</span>
<span class="nx">ngOnInit</span><span class="p">():</span> <span class="k">void</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">rxStompService</span><span class="p">.</span><span class="nx">watch</span><span class="p">(</span><span class="dl">'</span><span class="s1">/topic/demo</span><span class="dl">'</span><span class="p">).</span><span class="nx">subscribe</span><span class="p">((</span><span class="na">message</span><span class="p">:</span> <span class="nx">Message</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">receivedMessages</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">message</span><span class="p">.</span><span class="nx">body</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="nx">onSendMessage</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">message</span> <span class="o">=</span> <span class="s2">`Message generated at </span><span class="p">${</span><span class="k">new</span> <span class="nb">Date</span><span class="p">()}</span><span class="s2">`</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">rxStompService</span><span class="p">.</span><span class="nx">publish</span><span class="p">({</span> <span class="na">destination</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/topic/demo</span><span class="dl">'</span><span class="p">,</span> <span class="na">body</span><span class="p">:</span> <span class="nx">message</span> <span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><div</span> <span class="na">id=</span><span class="s">"messages"</span><span class="nt">></span>
<span class="nt"><button</span> <span class="na">class=</span><span class="s">"btn btn-primary"</span> <span class="na">(click)=</span><span class="s">"onSendMessage()"</span><span class="nt">></span>
Send Test Message
<span class="nt"></button></span>
<span class="nt"><h2></span>Received messages<span class="nt"></h2></span>
<span class="nt"><ol></span>
<span class="c"><!-- we will use Angular binding to populate list of messages --></span>
<span class="nt"><li</span> <span class="na">class=</span><span class="s">"message"</span> <span class="na">*ngFor=</span><span class="s">"let message of receivedMessages"</span><span class="nt">></span>
<span class="nt"></li></span>
<span class="nt"></ol></span>
<span class="nt"></div></span>
</code></pre></div></div>
<p>Check your application in the browser now — try sending a few messages. Then open another browser window/tab and see that both receive messages.</p>
<h3 id="stopping-the-watch">Stopping the watch</h3>
<p>We are almost done. We need to stop the watch when the component is destroyed. For this, we need to call <code class="language-plaintext highlighter-rouge">unsubscribe</code> on the RxJS subscription. We will need to do the following:</p>
<ul>
<li>Add <code class="language-plaintext highlighter-rouge">OnDestroy</code> to the <code class="language-plaintext highlighter-rouge">implements</code> list (by default, <code class="language-plaintext highlighter-rouge">OnInit</code> will be there).</li>
<li>Implement <code class="language-plaintext highlighter-rouge">ngOnDestroy</code> method.</li>
<li>Add <code class="language-plaintext highlighter-rouge">OnDestroy</code> to the imports.</li>
</ul>
<p>After this, we will modify the code in <code class="language-plaintext highlighter-rouge">ngOnInit</code> to store the RxJS
subscription in a member variable and call <code class="language-plaintext highlighter-rouge">unsubscribe</code> in <code class="language-plaintext highlighter-rouge">ngOnDestroy</code>.</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">ngOnInit</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">topicSubscription</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">rxStompService</span>
<span class="p">.</span><span class="nx">watch</span><span class="p">(</span><span class="dl">'</span><span class="s1">/topic/demo</span><span class="dl">'</span><span class="p">)</span>
<span class="p">.</span><span class="nx">subscribe</span><span class="p">((</span><span class="nx">message</span><span class="p">:</span> <span class="nx">Message</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">receivedMessages</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">message</span><span class="p">.</span><span class="nx">body</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="nx">ngOnDestroy</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">topicSubscription</span><span class="p">.</span><span class="nx">unsubscribe</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Type of <code class="language-plaintext highlighter-rouge">topicSubscription</code> will be <code class="language-plaintext highlighter-rouge">Subscription</code> from <code class="language-plaintext highlighter-rouge">rxjs</code>.
Your <code class="language-plaintext highlighter-rouge">src/app/messages/messages.component.ts</code> should look like the following:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">Component</span><span class="p">,</span> <span class="nx">OnDestroy</span><span class="p">,</span> <span class="nx">OnInit</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@angular/core</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">RxStompService</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">../rx-stomp.service</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">Message</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@stomp/stompjs</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">Subscription</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">rxjs</span><span class="dl">'</span><span class="p">;</span>
<span class="p">@</span><span class="nd">Component</span><span class="p">({</span>
<span class="na">selector</span><span class="p">:</span> <span class="dl">'</span><span class="s1">app-messages</span><span class="dl">'</span><span class="p">,</span>
<span class="na">templateUrl</span><span class="p">:</span> <span class="dl">'</span><span class="s1">./messages.component.html</span><span class="dl">'</span><span class="p">,</span>
<span class="na">styleUrls</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">./messages.component.css</span><span class="dl">'</span><span class="p">],</span>
<span class="p">})</span>
<span class="k">export</span> <span class="kd">class</span> <span class="nx">MessagesComponent</span> <span class="k">implements</span> <span class="nx">OnInit</span><span class="p">,</span> <span class="nx">OnDestroy</span> <span class="p">{</span>
<span class="nl">receivedMessages</span><span class="p">:</span> <span class="kr">string</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>
<span class="c1">// @ts-ignore, to suppress warning related to being undefined</span>
<span class="k">private</span> <span class="nx">topicSubscription</span><span class="p">:</span> <span class="nx">Subscription</span><span class="p">;</span>
<span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">rxStompService</span><span class="p">:</span> <span class="nx">RxStompService</span><span class="p">)</span> <span class="p">{}</span>
<span class="nx">ngOnInit</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">topicSubscription</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">rxStompService</span>
<span class="p">.</span><span class="nx">watch</span><span class="p">(</span><span class="dl">'</span><span class="s1">/topic/demo</span><span class="dl">'</span><span class="p">)</span>
<span class="p">.</span><span class="nx">subscribe</span><span class="p">((</span><span class="nx">message</span><span class="p">:</span> <span class="nx">Message</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">receivedMessages</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">message</span><span class="p">.</span><span class="nx">body</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="nx">ngOnDestroy</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">topicSubscription</span><span class="p">.</span><span class="nx">unsubscribe</span><span class="p">();</span>
<span class="p">}</span>
<span class="nx">onSendMessage</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">message</span> <span class="o">=</span> <span class="s2">`Message generated at </span><span class="p">${</span><span class="k">new</span> <span class="nb">Date</span><span class="p">()}</span><span class="s2">`</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">rxStompService</span><span class="p">.</span><span class="nx">publish</span><span class="p">({</span> <span class="na">destination</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/topic/demo</span><span class="dl">'</span><span class="p">,</span> <span class="na">body</span><span class="p">:</span> <span class="nx">message</span> <span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="where-next">Where next</h2>
<ul>
<li>Browse the code at <a href="https://github.com/stomp-js/rx-stomp-angular">https://github.com/stomp-js/rx-stomp-angular</a></li>
<li>Explore <a href="/api-docs/latest/classes/RxStomp.html">RxStomp</a> to understand other interesting methods exposed by the library.</li>
<li>Go through <a href="https://angular.io/guide/dependency-injection">Angular Dependency Injection</a> — mastering it will take you places.</li>
<li><a href="/guide/ng2-stompjs/rx-stomp/connection-status-ng2-stompjs.html">Observing STOMP connection</a> status and showing a visual indicator.</li>
<li>Using <a href="/faqs/faqs.html#p-can-i-use-token-based-authentication-with-these-libraries-p">token authentication</a>
with the STOMP broker.</li>
</ul>StompJSThis step-by-step guide will create a new Angular application and demonstrate usage of rx-stomp.Upgrading to stompjs@6, rx-stomp@1, ng2-stompjs@82020-10-21T16:51:09+00:002020-10-21T16:51:09+00:00https://stomp-js.github.io/guide/stompjs/rx-stomp/upgrading-to-stompjs-6-rx-stomp-1<p>These releases are synchronized releases and add similar changes.
It is expected that these releases are fully backwards compatible.
However, you may need to recompile your code.</p>
<h2 id="user-visible-changes">User visible changes</h2>
<h3 id="discardwebsocketoncommfailure">discardWebsocketOnCommFailure</h3>
<p>Websocket specification does not provide any mechanism for quickly
dropping a connection.
If the underlying connection is dropped and the incoming pings fail,
the actual closure of the Websocket may take significant time (several minutes).
This new option discards the websocket immediately.
This will allow a quicker reconnection.</p>
<p>Under the hood if the Websocket library supports <code class="language-plaintext highlighter-rouge">terminate</code> method
(which <code class="language-plaintext highlighter-rouge">ws</code> npm package does), it will call that to quickly drop
the connection.
None of the Web browsers supports any equivalent method.</p>
<p>In this release this flag is <code class="language-plaintext highlighter-rouge">off</code> by default, set it to <code class="language-plaintext highlighter-rouge">true</code>
to activate it.</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Set it directly or part of configuration</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">discardWebsocketOnCommFailure</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
</code></pre></div></div>
<p>Ref:</p>
<ul>
<li><a href="https://stomp-js.github.io/api-docs/latest/classes/Client.html#discardWebsocketOnCommFailure">Client#discardWebsocketOnCommFailure</a></li>
<li><a href="https://stomp-js.github.io/api-docs/latest/classes/StompConfig.html#discardWebsocketOnCommFailure">StompConfig#discardWebsocketOnCommFailure</a></li>
<li><a href="https://stomp-js.github.io/api-docs/latest/classes/RxStompConfig.html#discardWebsocketOnCommFailure">RxStompConfig#discardWebsocketOnCommFailure</a></li>
</ul>
<h3 id="connectiontimeout">connectionTimeout</h3>
<p>The STOMP standard supports Heartbeats which allow detecting stale connections.
However, this mechanism activates after a successful connection (under the hood,
after <code class="language-plaintext highlighter-rouge">CONNECTED</code> STOMP frame has been received from the broker).</p>
<p>This setting guards against the case that connection setup takes a long time to
establish. If it takes longer it will abandon the attempt and retry.</p>
<p>The value is the number of milliseconds to wait for a successful connection.</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Set it directly or part of configuration</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">connectionTimeout</span> <span class="o">=</span> <span class="mi">500</span><span class="p">;</span>
</code></pre></div></div>
<p>Ref:</p>
<ul>
<li><a href="https://stomp-js.github.io/api-docs/latest/classes/Client.html#connectionTimeout">Client#connectionTimeout</a></li>
<li><a href="https://stomp-js.github.io/api-docs/latest/classes/StompConfig.html#connectionTimeout">StompConfig#connectionTimeout</a></li>
<li><a href="https://stomp-js.github.io/api-docs/latest/classes/RxStompConfig.html#connectionTimeout">RxStompConfig#connectionTimeout</a></li>
</ul>
<h3 id="deactivate---async">deactivate - async</h3>
<p>You are unlikely to be affected by this change.
<code class="language-plaintext highlighter-rouge">deactivate</code> has now been made <code class="language-plaintext highlighter-rouge">async</code>, if there is an underlying
active connection, the call will wait till that is terminated.
This prevents a race condition that may cause more than one
active underlying connection in case <code class="language-plaintext highlighter-rouge">deativate</code> and <code class="language-plaintext highlighter-rouge">activate</code> were
invoked in quick succession.</p>
<p>If you were calling <code class="language-plaintext highlighter-rouge">deativate</code> and <code class="language-plaintext highlighter-rouge">activate</code> in succession,
you should await for <code class="language-plaintext highlighter-rouge">deativate</code>.</p>
<h3 id="rx-stompng-stomp-js-specific">rx-stomp/ng-stomp-js specific</h3>
<p><a href="https://stomp-js.github.io/api-docs/latest/classes/RxStomp.html#watch">RxStomp#watch</a> now allows setting unsubscribe headers.
These headers can be set as fixed values or a callback that would return headers.
See <a href="https://stomp-js.github.io/api-docs/latest/interfaces/IWatchParams.html#unsubHeaders">IWatchParams#unsubHeaders</a> for details and an example.</p>
<p>See:</p>
<ul>
<li><a href="https://stomp-js.github.io/api-docs/latest/classes/RxStomp.html#watch">RxStomp#watch</a></li>
<li><a href="https://stomp-js.github.io/api-docs/latest/interfaces/IWatchParams.html#unsubHeaders">IWatchParams#unsubHeaders</a></li>
</ul>
<h4 id="subscribeonlyonce">subscribeOnlyOnce</h4>
<p>By default, when you initiate a watch, it will be reestablished in case of
a reconnection to the broker.
You can set this flag while initiating a watch to subscribe only once.</p>
<p>See:</p>
<ul>
<li><a href="https://stomp-js.github.io/api-docs/latest/classes/RxStomp.html#watch">RxStomp#watch</a></li>
<li><a href="https://stomp-js.github.io/api-docs/latest/interfaces/IWatchParams.html#subscribeOnlyOnce">IWatchParams#subscribeOnlyOnce</a></li>
</ul>
<h2 id="non-visible-changes">Non visible changes</h2>
<ul>
<li>The output target is <code class="language-plaintext highlighter-rouge">es2015</code>. We wanted <code class="language-plaintext highlighter-rouge">es2017</code>, however,
that causes issue with Angular.</li>
<li>The tree-shaking support is quite consistent now.
In previous version <code class="language-plaintext highlighter-rouge">rx-stomp</code> used <code class="language-plaintext highlighter-rouge">commonjs</code> module system,
which, was not very friendly to tree shaking.</li>
<li>Remove dom lib dependency for usage with NodeJS/Typescript.</li>
</ul>StompJSThese releases are synchronized releases and add similar changes. It is expected that these releases are fully backwards compatible. However, you may need to recompile your code.React Native - Additional notes2019-06-10T15:31:01+00:002019-06-10T15:31:01+00:00https://stomp-js.github.io/workaround/stompjs/rx-stomp/react-native-additional-notes<h1 id="polyfills">Polyfills</h1>
<p>Before you proceed, ensure you have <a href="/guide/stompjs/rx-stomp/polyfills-for-stompjs.html">polyfills for
TextEncoder/TextDecoder</a>.</p>
<h1 id="insecure-connection-issue-in-android">Insecure connection issue in Android</h1>
<p>Recent versions of Android SDK do not allow insecure (not HTTPS) HTTP connections.
This is likely to show up in production builds only.
You will notice STOMP connection not getting established and reconnect attempt being made.</p>
<p>To bypass the checks, please follow suggestions at
<a href="https://github.com/stomp-js/stompjs/issues/149#issuecomment-633734719">https://github.com/stomp-js/stompjs/issues/149#issuecomment-633734719</a>
and <a href="https://blog.usejournal.com/6-daily-issues-in-android-cleartext-traffic-error-52ab31dd86c2">https://blog.usejournal.com/6-daily-issues-in-android-cleartext-traffic-error-52ab31dd86c2</a>.</p>
<h1 id="null-chopping">Null Chopping</h1>
<p>Some versions of React Native (including the current production
version as on June 10, 2019) have an underlying issue that prevents these libraries
from working correctly.
Please see:</p>
<ul>
<li><a href="https://github.com/facebook/react-native/issues/12731">react-native/issues/12731</a></li>
<li><a href="https://github.com/facebook/react-native/issues/22043">react-native/issues/22043</a></li>
<li><a href="https://github.com/facebook/metro/issues/365">metro/issues/365</a></li>
</ul>
<p>Reported in <code class="language-plaintext highlighter-rouge">stompjs</code>:</p>
<ul>
<li><a href="https://github.com/stomp-js/stompjs/issues/55">stompjs/issues/55</a></li>
<li><a href="https://github.com/stomp-js/stompjs/issues/89">stompjs/issues/89</a></li>
</ul>
<p>The best solution would have been for the underlying issue to be fixed.
However, it seems there is not much interest in that.</p>
<p>It has been observed that NULL chopping happens only with strings, buffers works correctly.
Workaround 2, avoids using strings altogether by using binary
for both incoming and outgoing packets.
Workaround 1, uses outgoing binary packets and tries to reverse the damage by appending
the missing NULL.</p>
<p><strong>Workaround 1:</strong></p>
<p><em>This approach has been reported to work by multiple users.</em></p>
<ul>
<li>Upgrade to the latest version of <code class="language-plaintext highlighter-rouge">stompjs</code> (at least 5.4.1).</li>
<li>In you configuration set both
<a href="/api-docs/latest/classes/Client.html#forceBinaryWSFrames">forceBinaryWSFrames</a> and
<a href="/api-docs/latest/classes/Client.html#appendMissingNULLonIncoming">appendMissingNULLonIncoming</a> to <code class="language-plaintext highlighter-rouge">true</code>.</li>
</ul>
<p>The <code class="language-plaintext highlighter-rouge">forceBinaryWSFrames</code> is completely safe — it will not cause any data loss
or incorrect protocol behavior.</p>
<p>However, the <code class="language-plaintext highlighter-rouge">appendMissingNULLonIncoming</code> flag may cause
data loss or unexpected connection termination.
If you are only using small messages (which do not cause fragmentation),
you should be fine.</p>
<p><strong>Workaround 2:</strong></p>
<p><em>This approach has been reported to work by one user.</em></p>
<p>If your broker supports forcing binary frames, you may try this approach.</p>
<ul>
<li>Upgrade to the latest version of <code class="language-plaintext highlighter-rouge">stompjs</code> (at least 5.4.1).</li>
<li>In you configuration set
<a href="/api-docs/latest/classes/Client.html#forceBinaryWSFrames">forceBinaryWSFrames</a> to <code class="language-plaintext highlighter-rouge">true</code>.</li>
<li>Force the broker to send only binary frames.
(For example, in RabbitMQ set <code class="language-plaintext highlighter-rouge">web_stomp.ws_frame = binary</code> in <code class="language-plaintext highlighter-rouge">rabbitmq.conf</code>)</li>
</ul>
<p>The approach is completely safe — it will not cause any data loss
or incorrect protocol behavior.</p>StompJSPolyfillsFrequently Asked Questions2019-05-20T06:36:34+00:002019-05-20T06:36:34+00:00https://stomp-js.github.io/faqs/faqs<style type="text/css">
#answers .question {
font-weight: bold;
margin-top: 1.9em;
margin-bottom: 0.3em;
}
h2 {
margin-top: 2em;
}
</style>
<p>
<b><i>Under heavy construction</i></b>
</p>
<div id="question-list">
<h3>General</h3>
<ol class="list">
<li>
<a href="#p-what-are-stomp-and-webstomp-p"
>What are STOMP and WebStomp?</a
>
</li>
<li>
<a href="#p-what-documentation-is-available-p"
>What documentation is available?</a
>
</li>
<li>
<a href="#p-which-one-should-i-use-stompjs-or-rx-stomp-p"
>Which one should I use - stompjs or rx-stomp?</a
>
</li>
<li>
<a href="#p-can-these-libraries-be-used-with-es6-or-typescript-p"
>Can these libraries be used with ES6 or Typescript?</a
>
</li>
<li>
<a href="#p-i-am-using-angular-which-of-stompjs-or-rx-stomp-should-i-use-p"
>I am using Angular. Which of stompjs or rx-stomp should I use?</a
>
</li>
<li>
<a href="#p-can-i-use-libraries-with-bundlers-like-rollup-or-webpack-p"
>Can I use libraries with bundlers like Rollup or Webpack?</a
>
</li>
<li>
<a href="#p-do-these-libraries-work-well-with-tree-shaking-p"
>Do these libraries work well with tree shaking?</a
>
</li>
<li>
<a href="#p-what-are-heartbeats-should-i-bother-p"
>What are Heartbeats? Should I bother?</a
>
</li>
<li>
<a href="#p-how-do-i-enable-logging-p"
>How do I enable logging?</a
>
</li>
<li>
<a href="#p-help-me-i-am-getting-errors-about-missing-classes-textencoder-textdecoder-websocket-p"
>Help me, I am getting errors about missing classes - TextEncoder/TextDecoder/WebSocket</a
>
</li>
</ol>
<h3>SockJS</h3>
<ol class="list">
<li>
<a href="#p-is-sockjs-needed-to-use-these-libraries-p"
>Is SockJS needed to use these libraries?</a
>
</li>
<li>
<a href="#p-i-am-using-sockjs-my-automatic-reconnection-does-not-work-p"
>I am using SockJS, my automatic reconnection does not work?</a
>
</li>
<li>
<a href="#p-i-am-using-sockjs-and-i-am-facing-issues-where-do-i-look-p"
>I am using SockJS and I am facing issues, where do I look?</a
>
</li>
</ol>
<h3>Authentication</h3>
<ol class="list">
<li>
<a href="#p-can-i-use-token-based-authentication-with-these-libraries-p"
>Can I use Token-based authentication with these libraries?</a
>
</li>
<li>
<a href="#p-my-authentication-tokens-expire-where-should-i-write-code-to-acquire-fresh-tokens-p"
>My authentication tokens expire, where should I write code to acquire fresh tokens?</a
>
</li>
</ol>
<h3>NodeJS</h3>
<ol class="list">
<li>
<a href="#p-can-this-library-be-used-with-nodejs-p"
>Can this library be used with NodeJS?</a
>
</li>
</ol>
<h3>React Native</h3>
<ol class="list">
<li>
<a href="#p-i-am-using-it-with-react-native-i-have-started-facing-strange-issues-p"
>I am using it with React Native, I have started facing strange issues?</a
>
</li>
</ol>
<h3>Jeff Mesnil's stompjs</h3>
<ol class="list">
<li>
<a href="#p-how-is-it-related-to-stompjs-from-jeff-mesnil-p"
>How is it related to stompjs from Jeff Mesnil?</a
>
</li>
<li>
<a href="#p-how-do-i-migrate-from-jeff-mesnil-s-stompjs-p"
>How do I migrate from Jeff Mesnil's stompjs?</a
>
</li>
<li>
<a href="#p-are-there-any-missing-features-from-jeff-mesnil-s-stompjs-p"
>Are there any missing features from Jeff Mesnil's stompjs?</a
>
</li>
</ol>
</div>
<div id="answers">
<h2>General</h2>
<div class="item" id="p-what-are-stomp-and-webstomp-p">
<p class="question">Q: What are STOMP and WebStomp?</p>
<div class="answer"><p><a href="https://stomp.github.io/index.html">STOMP</a> is a simple text protocol to
interact with messaging brokers.
Usually, one of <a href="https://www.amqp.org/">AMQP</a>,
<a href="http://mqtt.org/">MQTT</a>, <a href="https://en.wikipedia.org/wiki/Java_Message_Service">JMS</a>,
or a similar protocol is used to connect to a messaging broker.
In a language like JavaScript, it may not be easy to implement any of these protocols.
So, STOMP becomes a reasonable option.</p>
<p>In addition, web browsers do not allow TCP connections from web pages.
To overcome this limitation,
most of the brokers support STOMP over <a href="https://en.wikipedia.org/wiki/WebSocket">WebSockets</a>.
The STOMP over WebSockets is referred to as WebStomp.</p>
</div>
</div>
<div class="item" id="p-what-documentation-is-available-p">
<p class="question">Q: What documentation is available?</p>
<div class="answer"><ul>
<li>Comprehensive <a href="/api-docs/latest/">API documentation</a>.</li>
<li>Several <a href="/">guides</a>.</li>
<li><a href="https://github.com/stomp-js/samples/">Samples</a> for <code class="language-plaintext highlighter-rouge">@stomp/stompjs</code> and <code class="language-plaintext highlighter-rouge">@stompjs/rx-stomp</code>.</li>
<li><a href="https://github.com/stomp-js/rx-stomp-angular">Sample</a> for using <code class="language-plaintext highlighter-rouge">@stompjs/rx-stomp</code> with Angular.</li>
</ul>
</div>
</div>
<div class="item" id="p-which-one-should-i-use-stompjs-or-rx-stomp-p">
<p class="question">Q: Which one should I use - stompjs or rx-stomp?</p>
<div class="answer"><p><code class="language-plaintext highlighter-rouge">stompjs</code> is the underlying core library, usable almost everywhere.</p>
<p><code class="language-plaintext highlighter-rouge">rx-stomp</code> exposes functionality as <a href="https://github.com/ReactiveX/RxJS">RxJS</a> primitives.
If you are already using RxJS in your project or are familiar with it, please consider using <code class="language-plaintext highlighter-rouge">rx-stomp</code>.</p>
<p>Other than syntactical differences,
these two variants have a very important difference.
In <code class="language-plaintext highlighter-rouge">stompjs</code>, the <a href="/api-docs/latest/classes/Client.html">client</a> must only be used within the <a href="/api-docs/latest/classes/Client.html#onConnect">onConnect</a> callback.
Using it outside may produce strange errors.
The <code class="language-plaintext highlighter-rouge">rx-stomp</code> does not suffer from this limitation.</p>
<p>So, as a rule of thumb, if your application needs to use the <a href="/api-docs/latest/classes/Client.html">client</a> object
outside the <a href="/api-docs/latest/classes/Client.html#onConnect">onConnect</a> callback, use <code class="language-plaintext highlighter-rouge">rx-stomp</code>.</p>
<p>When using with Angular, <code class="language-plaintext highlighter-rouge">rx-stomp</code> seems natual as
Angular relies heavily on <a href="https://github.com/ReactiveX/RxJS">RxJS</a>.</p>
</div>
</div>
<div class="item" id="p-can-these-libraries-be-used-with-es6-or-typescript-p">
<p class="question">Q: Can these libraries be used with ES6 or Typescript?</p>
<div class="answer"><p>Yes.</p>
<p>From 2023, these libraries are distributed as Javascript modules as default.
These can be used with <code class="language-plaintext highlighter-rouge">import</code>.</p>
<p>All these libraries have been developed in TypeScript and type definition
files are included in releases.</p>
<p>In addition, a UMD bundle is included to be used as a html script tag.</p>
</div>
</div>
<div class="item" id="p-i-am-using-angular-which-of-stompjs-or-rx-stomp-should-i-use-p">
<p class="question">Q: I am using Angular. Which of stompjs or rx-stomp should I use?</p>
<div class="answer"><p>Angular makes heavy use of <a href="https://github.com/ReactiveX/RxJS">RxJS</a>. So using <code class="language-plaintext highlighter-rouge">rx-stomp</code> should feel natural with Angular.</p>
<p>There is a tutorial for using <code class="language-plaintext highlighter-rouge">rx-stomp</code> with Angular. Please see <a href="/#getting-started">guides</a>.</p>
<p>Having said all of these, you can use any of the variants.
Developers have reported successfully using <code class="language-plaintext highlighter-rouge">stompjs</code> directly with Angular.</p>
</div>
</div>
<div class="item" id="p-can-i-use-libraries-with-bundlers-like-rollup-or-webpack-p">
<p class="question">Q: Can I use libraries with bundlers like Rollup or Webpack?</p>
<div class="answer"><p>Yes.</p>
<p>These libraries include ES6 modules in the distribution,
so, any environment that uses <code class="language-plaintext highlighter-rouge">import</code> will be able to find modules
without any additional configuration.</p>
</div>
</div>
<div class="item" id="p-do-these-libraries-work-well-with-tree-shaking-p">
<p class="question">Q: Do these libraries work well with tree shaking?</p>
<div class="answer"><p>Yes.</p>
<p>Please update the latest versions before reporting any issues related to tree shaking.</p>
</div>
</div>
<div class="item" id="p-what-are-heartbeats-should-i-bother-p">
<p class="question">Q: What are Heartbeats? Should I bother?</p>
<div class="answer"><p>Most STOMP 1.1+ brokers will support heart beats.
These can be from the broker to the client (incoming)
or the client to the broker (outgoing).
When enabled, periodic heartbeats are sent.
If heartbeats are not received within specified time (along with some grace time),
the connection is assumed to be stale and will be terminated.</p>
<p>SockJS may not support heart beats.
See <a href="/guide/stompjs/rx-stomp/using-stomp-with-sockjs.html">using STOMP with SockJS</a>.</p>
<p>Whether you should use heart beats is a complex decision.
If you use it, a stale connection will be detected sooner.
However, it also means packets (actually a one-byte payload) will keep getting sent/received even when
there is no application traffic.</p>
<p>Please see the <a href="/guide/stompjs/using-stompjs-v5.html#heart-beating">Heart Beats</a>
topic for usage details.</p>
</div>
</div>
<div class="item" id="p-how-do-i-enable-logging-p">
<p class="question">Q: How do I enable logging?</p>
<div class="answer"><p>Please see <a href="/guide/stompjs/using-stompjs-v5.html#debug">enabling debug log</a>.</p>
<p>The console debug output may have NULL characters, which will prevent it from copying and pasting
into a GitHub issue.
In such cases, save it as a text file and attach with the issue.</p>
</div>
</div>
<div class="item" id="p-help-me-i-am-getting-errors-about-missing-classes-textencoder-textdecoder-websocket-p">
<p class="question">Q: Help me, I am getting errors about missing classes - TextEncoder/TextDecoder/WebSocket</p>
<div class="answer"><p>Please see <a href="/guide/stompjs/rx-stomp/polyfills-for-stompjs.html">StompJs v5: Polyfills</a></p>
</div>
</div>
<h2>SockJS</h2>
<div class="item" id="p-is-sockjs-needed-to-use-these-libraries-p">
<p class="question">Q: Is SockJS needed to use these libraries?</p>
<div class="answer"><p>No SockJS is not mandatory to use this library.</p>
<p>SockJS, however, is supported.
Please see
<a href="/guide/stompjs/rx-stomp/using-stomp-with-sockjs.html">using StompJS with SockJS</a>.</p>
</div>
</div>
<div class="item" id="p-i-am-using-sockjs-my-automatic-reconnection-does-not-work-p">
<p class="question">Q: I am using SockJS, my automatic reconnection does not work?</p>
<div class="answer"><p>You need to pass a factory that returns a SockJS instance.</p>
<p>Please see
<a href="/guide/stompjs/rx-stomp/using-stomp-with-sockjs.html">Using STOMP with SockJS</a>
if you are using recent versions of these libraries.</p>
<p>If you are using <code class="language-plaintext highlighter-rouge">Stomp.over</code> compatibility mode (or older version), please refer to
<a href="/api-docs/latest/classes/Stomp.html#over">Stomp.over API docs</a>.</p>
</div>
</div>
<div class="item" id="p-i-am-using-sockjs-and-i-am-facing-issues-where-do-i-look-p">
<p class="question">Q: I am using SockJS and I am facing issues, where do I look?</p>
<div class="answer"><p>Several topics related to SockJS have been compiled at
<a href="/guide/stompjs/rx-stomp/using-stomp-with-sockjs.html">Using STOMP with SockJS</a>.</p>
</div>
</div>
<h2>Authentication</h2>
<div class="item" id="p-can-i-use-token-based-authentication-with-these-libraries-p">
<p class="question">Q: Can I use Token-based authentication with these libraries?</p>
<div class="answer"><p>Even though <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket">WebSocket</a>
is somewhat similar to HTTP(S), it differs in one very important aspect — it
does not allow control of headers.</p>
<p>This poses a limitation on using token-based authentication schemes using HTTP headers.</p>
<p>Conventional brokers do not expect any authentication information as part of
HTTP headers or HTTP connection parameters.
These instead rely on STOMP protocol’s
<a href="https://stomp.github.io/stomp-specification-1.2.html#CONNECT_or_STOMP_Frame">CONNECT Frame</a>.
This frame can have headers as key/value pairs.
You can control these by setting
<a href="https://stomp-js.github.io/api-docs/latest/classes/Client.html#connectHeaders">connectHeaders</a>
configuration option.
You can pass any pair of strings as keys and values.</p>
<p>So, typically, for token-based authentication you will pass the token as part of
<a href="https://stomp-js.github.io/api-docs/latest/classes/Client.html#connectHeaders">connectHeaders</a>.
Check your broker documentation for details.</p>
<p>If you are using Spring, please check
<a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#websocket-stomp-authentication-token-based">https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#websocket-stomp-authentication-token-based</a></p>
</div>
</div>
<div class="item" id="p-my-authentication-tokens-expire-where-should-i-write-code-to-acquire-fresh-tokens-p">
<p class="question">Q: My authentication tokens expire, where should I write code to acquire fresh tokens?</p>
<div class="answer"><p>The suggested place to acquire fresh tokens is
<a href="https://stomp-js.github.io/api-docs/latest/classes/Client.html#beforeConnect">beforeConnect</a>
callback.
You can update the
<a href="https://stomp-js.github.io/api-docs/latest/classes/Client.html#connectHeaders">connectHeaders</a>
after you have acquired a fresh token.</p>
<p>If you need to fetch a token using an async request (say using an XHR),
you can set an async function as the callback.</p>
</div>
</div>
<h2>NodeJS</h2>
<div class="item" id="p-can-this-library-be-used-with-nodejs-p">
<p class="question">Q: Can this library be used with NodeJS?</p>
<div class="answer"><p>Yes, NodeJS is supported using WebSockets as the communication mechanism.
Please see <a href="/guide/stompjs/using-stompjs-v5.html#in-nodejs">NodeJS topic in using StompJS guide</a>.
In addition, check the needed <a href="/guide/stompjs/rx-stomp/polyfills-for-stompjs.html">PolyFills</a>.</p>
<p>While this library can be used with NodeJS, if your broker supports,
you should consider
<a href="https://www.amqp.org/">AMQP</a> or
<a href="http://mqtt.org/">MQTT</a>.
These protocols are likely to give more flexibility than STOMP.</p>
</div>
</div>
<h2>React Native</h2>
<div class="item" id="p-i-am-using-it-with-react-native-i-have-started-facing-strange-issues-p">
<p class="question">Q: I am using it with React Native, I have started facing strange issues?</p>
<div class="answer"><p>Please see
<a href="/workaround/stompjs/rx-stomp/react-native-additional-notes.html">React Native - Additional Notes</a>.</p>
</div>
</div>
<h2>Jeff Mesnil's stompjs</h2>
<div class="item" id="p-how-is-it-related-to-stompjs-from-jeff-mesnil-p">
<p class="question">Q: How is it related to stompjs from Jeff Mesnil?</p>
<div class="answer"><p><a href="https://www.npmjs.com/package/stompjs">stompjs</a>
from <a href="http://jmesnil.net/">Jeff Mesnil</a> has been one of the initial
STOMP implementations for JavaScript.
However, the original author has no longer been maintaining it since 2016.
<code class="language-plaintext highlighter-rouge">@stomp/stompjs</code> started as a maintained fork.</p>
<p><code class="language-plaintext highlighter-rouge">@stomp/stompjs</code> v4 is an enhanced version of
<a href="https://www.npmjs.com/package/stompjs">stompjs</a>
from <a href="http://jmesnil.net/">Jeff Mesnil</a>.</p>
<p>Version 5 of <code class="language-plaintext highlighter-rouge">@stomp/stompjs</code> has been bottom up rewritten in TypeScript.
This version supports the older API in compatibility mode.</p>
</div>
</div>
<div class="item" id="p-how-do-i-migrate-from-jeff-mesnil-s-stompjs-p">
<p class="question">Q: How do I migrate from Jeff Mesnil's stompjs?</p>
<div class="answer"><p>Please see <a href="/guide/stompjs/upgrading-stompjs.html">upgrading stompjs</a>
guide.</p>
<p>The v4 of this library is backwards compatible with the original stompjs.
In all likelihoods your working code would work under compatibility mode of
v5.</p>
<p>To use newer features like automatic reconnection, compliance with STOMP
standards, and binary payloads, you would need to upgrade to newer syntax.</p>
</div>
</div>
<div class="item" id="p-are-there-any-missing-features-from-jeff-mesnil-s-stompjs-p">
<p class="question">Q: Are there any missing features from Jeff Mesnil's stompjs?</p>
<div class="answer"><p>Jeff Mesnil’s stompjs supports STOMP over TCP when used in the NodeJS environment.
Other than this, there is no known missing functionality.
If you intend to use this feature, please raise an issue.</p>
<p>Jeff Mesnil’s stompjs is not fully compliant to STOMP protocol.
The <code class="language-plaintext highlighter-rouge">@stomp/stompjs</code> strictly adheres the protocol.
This might, in some cases, give behavioral differences.
If you are facing any such issues, please raise an issue.</p>
</div>
</div>
</div>StompJS#answers .question { font-weight: bold; margin-top: 1.9em; margin-bottom: 0.3em; }Connection status in ng2-stompjs2018-12-18T13:52:37+00:002018-12-18T13:52:37+00:00https://stomp-js.github.io/guide/ng2-stompjs/rx-stomp/connection-status-ng2-stompjs<p>This guide extends the sample created in <a href="/guide/rx-stomp/rx-stomp-with-angular.html">ng2-stompjs-with-angular7</a>.</p>
<p>Original and extended source code at <a href="https://github.com/stomp-js/ng2-stompjs-angular7">ng2-stompjs-angular7-sample</a>.
Branch <code class="language-plaintext highlighter-rouge">connection-status</code> has code from this guide.</p>
<p>This guide applies to both <code class="language-plaintext highlighter-rouge">ng2-stompjs</code> and <code class="language-plaintext highlighter-rouge">rx-stomp</code>.</p>
<h2 id="the-api">The API</h2>
<p><a href="/api-docs/latest/injectables/RxStompService.html">RxStompService</a> and <a href="/api-docs/latest/injectables/InjectableRxStompConfig.html">InjectableRxStompConfig</a> are injectable versions of <a href="/api-docs/latest/classes/RxStomp.html">RxStomp</a>
and <a href="/api-docs/latest/classes/RxStompConfig.html">RxStompConfig</a> respectively. These offer same functionality otherwise.</p>
<p><a href="/api-docs/latest/classes/RxStomp.html">RxStomp</a> exposes <a href="https://stomp-js.github.io/api-docs/latest/classes/RxStomp.html#connectionState$">RxStomp#connectionState$</a> as an <a href="http://reactivex.io/rxjs/manual/overview.html#behaviorsubject">RxJS BehaviorSubject</a>.
It will yield the current state immediately and subsequently notify each state change.
State is defined as <a href="/api-docs/latest/miscellaneous/enumerations.html#RxStompState">RxStompState</a> - an Enum using same values as <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState">WebSocket States</a>.</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">rxStompService</span><span class="p">.</span><span class="nx">connectionState$</span><span class="p">.</span><span class="nx">subscribe</span><span class="p">(</span><span class="nx">state</span> <span class="o">=></span> <span class="p">{</span>
<span class="c1">// state is an Enum (Integer), RxStompState[state] is the corresponding string</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">RxStompState</span><span class="p">[</span><span class="nx">state</span><span class="p">]);</span>
<span class="p">});</span>
</code></pre></div></div>
<p><a href="/api-docs/latest/miscellaneous/enumerations.html#RxStompState">RxStompState</a> can have one of the following values:</p>
<ul>
<li>CONNECTING</li>
<li>OPEN</li>
<li>CLOSING</li>
<li>CLOSED</li>
</ul>
<p>This allows to easily write an indicator for UI. See the following code from the sample:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">StatusComponent</span> <span class="p">{</span>
<span class="k">public</span> <span class="nx">connectionStatus$</span><span class="p">:</span> <span class="nx">Observable</span><span class="o"><</span><span class="kr">string</span><span class="o">></span><span class="p">;</span>
<span class="kd">constructor</span><span class="p">(</span><span class="k">public</span> <span class="nx">rxStompService</span><span class="p">:</span> <span class="nx">RxStompService</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">connectionStatus$</span> <span class="o">=</span> <span class="nx">rxStompService</span><span class="p">.</span><span class="nx">connectionState$</span><span class="p">.</span><span class="nx">pipe</span><span class="p">(</span>
<span class="nx">map</span><span class="p">(</span><span class="nx">state</span> <span class="o">=></span> <span class="p">{</span>
<span class="c1">// convert numeric RxStompState to string</span>
<span class="k">return</span> <span class="nx">RxStompState</span><span class="p">[</span><span class="nx">state</span><span class="p">];</span>
<span class="p">})</span>
<span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<pre><code class="language-angular2html"><div id="status">
<div id="indicator" class="{{connectionStatus$|async}}"></div>
<span id="status-label">{{connectionStatus$|async}}</span>
</div>
</code></pre>
<p>With little CSS the indicator can be made to change color red/ember/green.</p>
<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">/* Make it a circle */</span>
<span class="c">/* Make it a circle */</span>
<span class="nt">div</span><span class="nf">#indicator</span> <span class="p">{</span>
<span class="nl">width</span><span class="p">:</span> <span class="m">12px</span><span class="p">;</span>
<span class="nl">height</span><span class="p">:</span> <span class="m">12px</span><span class="p">;</span>
<span class="nl">border-radius</span><span class="p">:</span> <span class="m">6px</span><span class="p">;</span>
<span class="nl">margin</span><span class="p">:</span> <span class="m">0</span> <span class="m">10px</span><span class="p">;</span>
<span class="nl">display</span><span class="p">:</span> <span class="n">inline-block</span><span class="p">;</span>
<span class="nl">background</span><span class="p">:</span> <span class="m">#ffbf00</span><span class="p">;</span> <span class="c">/* Ember by default, will be used for CONNECTING and CLOSING */</span>
<span class="p">}</span>
<span class="nt">div</span><span class="nc">.CLOSED</span><span class="nf">#indicator</span> <span class="p">{</span>
<span class="nl">background</span><span class="p">:</span> <span class="no">red</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">div</span><span class="nc">.OPEN</span><span class="nf">#indicator</span> <span class="p">{</span>
<span class="nl">background</span><span class="p">:</span> <span class="no">green</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="responding-to-successful-connection">Responding to successful connection</h2>
<p><a href="https://stomp-js.github.io/api-docs/latest/classes/RxStomp.html#connected$">RxStomp#connected$</a> is an <a href="http://reactivex.io/rxjs/manual/overview.html#observable">RxJS Observable</a> which will trigger immediately if Stomp broker
is already connected. It will trigger in each subsequent connect.</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// In case you want to respond to each connection establishment</span>
<span class="nx">rxStompService</span><span class="p">.</span><span class="nx">connected$</span><span class="p">.</span><span class="nx">subscribe</span><span class="p">(()</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">I will be called for each time connection is established.</span><span class="dl">'</span><span class="p">);</span>
<span class="p">});</span>
<span class="c1">// If you want to execute only once. It will execute immediately if connected</span>
<span class="c1">// otherwise on first subsequent connection.</span>
<span class="nx">rxStompService</span><span class="p">.</span><span class="nx">connected$</span><span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">take</span><span class="p">(</span><span class="mi">1</span><span class="p">)).</span><span class="nx">subscribe</span><span class="p">(()</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">I will be called only once.</span><span class="dl">'</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>
<p>The following is the code from the library. <a href="https://stomp-js.github.io/api-docs/latest/classes/RxStomp.html#connected$">RxStomp#connected$</a> is filtered <a href="https://stomp-js.github.io/api-docs/latest/classes/RxStomp.html#connectionState$">RxStomp#connectionState$</a>.</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">this</span><span class="p">.</span><span class="nx">connected$</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">connectionState$</span><span class="p">.</span><span class="nx">pipe</span><span class="p">(</span>
<span class="nx">filter</span><span class="p">((</span><span class="nx">currentState</span><span class="p">:</span> <span class="nx">RxStompState</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">currentState</span> <span class="o">===</span> <span class="nx">RxStompState</span><span class="p">.</span><span class="nx">OPEN</span><span class="p">;</span>
<span class="p">})</span>
<span class="p">);</span>
</code></pre></div></div>
<p>The above can be used to implement watch for any other state (like <code class="language-plaintext highlighter-rouge">CLOSED</code>).</p>StompJSThis guide extends the sample created in ng2-stompjs-with-angular7.RPC - Remote Procedure Call2018-10-12T03:42:00+00:002018-10-12T03:42:00+00:00https://stomp-js.github.io/guide/rx-stomp/remote-procedure-call<p><strong>This is an advanced topic.
You may choose to understand the philosophy by reading the initial sections,
or, you may just skip to the <a href="#usage">usage</a> sections which are not complicated.</strong></p>
<p>Messaging usually works one way.
There is, however, a convention for two-way communication (i.e. request/response).
This involves <code class="language-plaintext highlighter-rouge">reply-to</code> queues which routes the response back to correct client program
and <code class="language-plaintext highlighter-rouge">correlation-id</code> to uniquely match a response to the correct request.</p>
<p>See: [https://www.rabbitmq.com/tutorials/tutorial-six-python.html]
(https://www.rabbitmq.com/tutorials/tutorial-six-python.html)
for a sample using a very similar approach.</p>
<p>See sample RPC servers and clients at:
<a href="https://github.com/stomp-js/samples/">https://github.com/stomp-js/samples/</a></p>
<h2 id="why-rpc-using-messaging">Why RPC using messaging</h2>
<p>REST calls using JSON encoded payloads over http(s) are quite popular.
These have become almost ubiquitous and supported by a variety of frameworks
and have become the most common technique to access third party APIs.</p>
<p>There are, however, some limitations with REST/JSON/http(s) approach:</p>
<ul>
<li>http(s) can only wait for finite time before timing out.
Typically, for long-running operations as an alternative a request will be submitted
and the client will keep polling to check if results are ready.</li>
<li>There are some other interesting scenarios where the request is submitted to process A.
However, the final response is better handled by process B.
REST/JSON/http(s) will mandate that B communicates back to A which then intimates the client.
This scenario is quite common in credit card processing.</li>
<li>As an extension to the long-running tasks, there is no easy way to intimate the client about the
progress of the task.</li>
<li>We have gotten accustomed to the overheads of the REST /JSON/http(s) approach.
However, for every request, there is connection setup (including TLS/SSL)
before a request is made.</li>
</ul>
<p>The approach suggested in this guide solves all of the above issues/patterns.
On top of that, it offers some interesting bonus as well:</p>
<ul>
<li>It offers <em>natural</em> load balancing. Just boot up a new servers.</li>
<li>Even more — this form of load balancing automatically takes care of fast and slow
instances.</li>
<li>It allows fault tolerance — if a process dies before completing,
it would be submitted to another node.</li>
<li>If there are no servers available when a request is made, these can be queued
till a server becomes available.</li>
<li>It offers a mechanism where a server may indicate a temporary failure while processing
a request.
This will allow the request to be resubmitted for processing again.</li>
</ul>
<p>The samples at <a href="https://github.com/stomp-js/samples/">https://github.com/stomp-js/samples/</a> demonstrate most of the above.</p>
<h2 id="usage">Usage</h2>
<p>This feature will work with <code class="language-plaintext highlighter-rouge">@stomp/rx-stomp</code>.</p>
<h2 id="implementing-the-rpc-server-endpoint">Implementing the RPC server endpoint</h2>
<p>All code snippets are from <a href="https://github.com/stomp-js/samples/">https://github.com/stomp-js/samples/</a>.</p>
<p>This can be implemented in any language. In most cases, it will be executed in a backend server.</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="c1">// Destination is RabbitMQ specific, change as per your environment</span>
<span class="kd">const</span> <span class="nx">rpcEndPoint</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">/amq/queue/integer-addition</span><span class="dl">'</span><span class="p">;</span>
<span class="c1">// We will implement an endpoint</span>
<span class="c1">// This endpoint will wait for random period before responding to simulate real RPC servers</span>
<span class="nx">rxStomp</span><span class="p">.</span><span class="nx">watch</span><span class="p">(</span><span class="nx">rpcEndPoint</span><span class="p">).</span><span class="nx">subscribe</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">request</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">RPC Server: Request: </span><span class="dl">"</span> <span class="o">+</span> <span class="nx">request</span><span class="p">.</span><span class="nx">body</span><span class="p">);</span>
<span class="c1">// The response needs to be sent back here, it can safely be inlined</span>
<span class="kd">const</span> <span class="nx">replyTo</span> <span class="o">=</span> <span class="nx">request</span><span class="p">.</span><span class="nx">headers</span><span class="p">[</span><span class="dl">'</span><span class="s1">reply-to</span><span class="dl">'</span><span class="p">];</span>
<span class="c1">// Same correlation id needs to be sent back as message header, it can safely be inlined</span>
<span class="kd">const</span> <span class="nx">correlationId</span> <span class="o">=</span> <span class="nx">request</span><span class="p">.</span><span class="nx">headers</span><span class="p">[</span><span class="dl">'</span><span class="s1">correlation-id</span><span class="dl">'</span><span class="p">];</span>
<span class="c1">// simulate a random delay while computing</span>
<span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="c1">// Process the request, compute the response</span>
<span class="kd">const</span> <span class="nx">operands</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">request</span><span class="p">.</span><span class="nx">body</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="p">{</span><span class="na">result</span><span class="p">:</span> <span class="nb">Number</span><span class="p">.</span><span class="nb">parseInt</span><span class="p">(</span><span class="nx">operands</span><span class="p">.</span><span class="nx">x</span><span class="p">)</span> <span class="o">+</span> <span class="nb">Number</span><span class="p">.</span><span class="nb">parseInt</span><span class="p">(</span><span class="nx">operands</span><span class="p">.</span><span class="nx">y</span><span class="p">)};</span>
<span class="c1">// Completed processing</span>
<span class="kd">const</span> <span class="nx">responseBody</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">result</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">RPC Server: Response: </span><span class="dl">"</span> <span class="o">+</span> <span class="nx">responseBody</span> <span class="o">+</span> <span class="dl">"</span><span class="s2"> for </span><span class="dl">"</span> <span class="o">+</span> <span class="nx">request</span><span class="p">.</span><span class="nx">body</span><span class="p">);</span>
<span class="c1">// Send the response back to destination `replyTo` with `correlation-id` header</span>
<span class="nx">rxStomp</span><span class="p">.</span><span class="nx">publish</span><span class="p">({</span>
<span class="na">destination</span><span class="p">:</span> <span class="nx">replyTo</span><span class="p">,</span>
<span class="na">body</span><span class="p">:</span> <span class="nx">responseBody</span><span class="p">,</span>
<span class="na">headers</span><span class="p">:</span> <span class="p">{</span><span class="dl">'</span><span class="s1">correlation-id</span><span class="dl">'</span><span class="p">:</span> <span class="nx">correlationId</span><span class="p">}</span>
<span class="p">});</span>
<span class="p">},</span> <span class="nx">randomInt</span><span class="p">(</span><span class="mi">10000</span><span class="p">));</span>
</code></pre></div></div>
<p>A very similar server in Ruby (it is a single-threaded blocking server):</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">amqp_conn</span> <span class="o">=</span> <span class="no">Bunny</span><span class="p">.</span><span class="nf">new</span>
<span class="n">amqp_conn</span><span class="p">.</span><span class="nf">start</span>
<span class="n">channel</span> <span class="o">=</span> <span class="n">amqp_conn</span><span class="p">.</span><span class="nf">create_channel</span>
<span class="c1"># Notice that RabbitMQ STOMP adaptor maps queue/exchange names</span>
<span class="n">queue</span> <span class="o">=</span> <span class="n">channel</span><span class="p">.</span><span class="nf">queue</span><span class="p">(</span><span class="s2">"integer-addition"</span><span class="p">)</span>
<span class="n">queue</span><span class="p">.</span><span class="nf">subscribe</span><span class="p">(</span><span class="ss">block: </span><span class="kp">true</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">delivery_info</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">payload</span><span class="o">|</span>
<span class="nb">puts</span> <span class="s2">"Received: </span><span class="si">#{</span><span class="n">payload</span><span class="si">}</span><span class="s2">"</span>
<span class="c1"># Process the request, compute the response</span>
<span class="n">operands</span> <span class="o">=</span> <span class="no">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="p">{</span><span class="ss">result: </span><span class="n">operands</span><span class="p">[</span><span class="s1">'x'</span><span class="p">].</span><span class="nf">to_i</span> <span class="o">+</span> <span class="n">operands</span><span class="p">[</span><span class="s1">'y'</span><span class="p">].</span><span class="nf">to_i</span><span class="p">}</span>
<span class="n">response_body</span> <span class="o">=</span> <span class="n">result</span><span class="p">.</span><span class="nf">to_json</span>
<span class="c1"># Completed processing</span>
<span class="nb">puts</span> <span class="s2">"RPC Server: Response: </span><span class="si">#{</span><span class="n">response_body</span><span class="si">}</span><span class="s2"> for </span><span class="si">#{</span><span class="n">payload</span><span class="si">}</span><span class="s2">"</span>
<span class="n">default_exchange</span> <span class="o">=</span> <span class="n">channel</span><span class="p">.</span><span class="nf">default_exchange</span>
<span class="n">default_exchange</span><span class="p">.</span><span class="nf">publish</span> <span class="n">response_body</span><span class="p">,</span> <span class="ss">routing_key: </span><span class="n">metadata</span><span class="p">[</span><span class="ss">:reply_to</span><span class="p">],</span> <span class="ss">correlation_id: </span><span class="n">metadata</span><span class="p">[</span><span class="ss">:correlation_id</span><span class="p">]</span>
<span class="k">end</span>
</code></pre></div></div>
<h2 id="using-it-from-the-client">Using it from the client</h2>
<h3 id="rabbitmq">RabbitMQ</h3>
<p>RabbitMQ has special support for <code class="language-plaintext highlighter-rouge">temp-queues</code> in <code class="language-plaintext highlighter-rouge">reply-to</code> messages
which make things to work magically. Please check details at
<a href="https://www.rabbitmq.com/stomp.html#d.tqd">https://www.rabbitmq.com/stomp.html#d.tqd</a></p>
<p>The client code looks simple and similar to JSON and HTTP-based backend services.</p>
<p>Create an instance of <a href="/api-docs/latest/classes/RxStompRPC.html">RxStompRPC</a>,
you will need an instance of <a href="/api-docs/latest/classes/RxStomp.html">RxStomp</a> in the constructor:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">rxStompRPC</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">RxStompRPC</span><span class="p">(</span><span class="nx">rxStomp</span><span class="p">);</span>
</code></pre></div></div>
<p>Making the RPC call is simple, takes same parameters as <a href="/api-docs/latest/classes/RxStomp.html#publish">RxStomp#publish</a>
and returns an <code class="language-plaintext highlighter-rouge">Observable</code> which will trigger once.</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">myServiceEndPoint</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">/topic/echo</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">request</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Hello</span><span class="dl">'</span><span class="p">;</span>
<span class="c1">// It accepts a optional third argument a Hash of headers to be sent as part of the request</span>
<span class="nx">rxStompRPC</span>
<span class="p">.</span><span class="nx">rpc</span><span class="p">({</span> <span class="na">destination</span><span class="p">:</span> <span class="nx">myServiceEndPoint</span><span class="p">,</span> <span class="na">body</span><span class="p">:</span> <span class="nx">request</span> <span class="p">})</span>
<span class="p">.</span><span class="nx">subscribe</span><span class="p">((</span><span class="nx">message</span><span class="p">:</span> <span class="nx">Message</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
<span class="c1">// Consume the response</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">message</span><span class="p">.</span><span class="nx">body</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>
<p>You can notice similarity with Angular HTTP calls.</p>
<p>See <a href="https://github.com/stomp-js/samples/">https://github.com/stomp-js/samples/</a> for a sample client.</p>
<h3 id="other-brokers">Other Brokers</h3>
<p>There are few requirements:</p>
<ul>
<li>the reply queue name <strong>must</strong> be unique across the broker.</li>
<li>ideally, for security reasons, only the client creating the queue should have access to it.</li>
</ul>
<p>Many brokers have <code class="language-plaintext highlighter-rouge">temp-queue</code> concept which should simplify your work.</p>
<p>The following gives an outline:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">stompRPCConfigForActiveMQ</span> <span class="o">=</span> <span class="p">{</span>
<span class="c1">// A unique name, BTW angular2-uuid module is already added as dependency</span>
<span class="na">replyQueueName</span><span class="p">:</span> <span class="s2">`/topic/replies.</span><span class="p">${</span><span class="nx">UUID</span><span class="p">.</span><span class="nx">UUID</span><span class="p">()}</span><span class="s2">`</span><span class="p">,</span>
<span class="c1">// Simply subscribe, you would need to secure by adding broker specific options</span>
<span class="na">setupReplyQueue</span><span class="p">:</span> <span class="p">(</span><span class="na">replyQueueName</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="na">stompService</span><span class="p">:</span> <span class="nx">StompRService</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">stompService</span><span class="p">.</span><span class="nx">subscribe</span><span class="p">(</span><span class="nx">replyQueueName</span><span class="p">);</span>
<span class="p">},</span>
<span class="p">};</span>
</code></pre></div></div>
<p>Apart from this additional setup step usage remains the same as RabbitMQ as documented above.</p>
<h2 id="what-next">What Next</h2>
<p>In <a href="#why-rpc-using-messaging">Why RPC using messaging</a>, few additional benefits
like reporting progress, fault tolerance etc. are discussed.</p>
<p>There are samples which cover some of these patterns:</p>
<ul>
<li>Multithreaded Ruby server.</li>
<li>Manual acknowledgement — it will retry in case of failure.</li>
<li>Factoring out boilerplate server code.</li>
<li>Implementing server/client using <a href="/api-docs/latest/classes/RxStompRPC.html#stream">RxStompRPC#stream</a> to report progress.</li>
</ul>
<p>If you have questions, or you would like to see more guides, please raise an issue at
<a href="https://github.com/stomp-js/rx-stomp/issues">https://github.com/stomp-js/rx-stomp/issues</a>.</p>StompJSThis is an advanced topic. You may choose to understand the philosophy by reading the initial sections, or, you may just skip to the usage sections which are not complicated.Using STOMP with SockJS2018-09-10T06:36:34+00:002018-09-10T06:36:34+00:00https://stomp-js.github.io/guide/stompjs/rx-stomp/using-stomp-with-sockjs<p><strong>There are a large number of obsolete (and copied from one another)
examples for these libraries that use SockJS.
In reality, there is very little chance that you need SockJS.
Unless you know, for sure, you do not need SockJS.</strong></p>
<p>This guide covers how to use <a href="https://github.com/sockjs/sockjs-client">SockJS client</a> instead of WebSockets as underlying transport.</p>
<p><strong>For Spring STOMP users:</strong>
<em>There are few tutorials/guides that implicitly suggest that you need SockJS to use STOMP.
That is incorrect, you only need SockJS if you need to support old browsers.</em></p>
<h2 id="do-you-need-sockjs">Do you need SockJS?</h2>
<p>As of 2018, WebSocket support in browsers is ubiquitous.
Please check <a href="https://caniuse.com/#feat=websockets">https://caniuse.com/#feat=websockets</a>.
Depending on your user base, you can skip this page.</p>
<p>You can use <a href="https://github.com/sockjs/sockjs-client">SockJS client</a> to support browsers that do not support WebSockets natively.</p>
<p>You would need to consider the following:</p>
<ul>
<li>URL protocol conventions are different for WebSockets (<code class="language-plaintext highlighter-rouge">ws:</code>/<code class="language-plaintext highlighter-rouge">wss:</code>) and SockJS (<code class="language-plaintext highlighter-rouge">http:</code> or <code class="language-plaintext highlighter-rouge">https:</code>).</li>
<li>Internal handshake sequences are different — so, some brokers will use different end points for
both protocols.</li>
<li>Neither of these allows custom headers to be set during the HTTP handshake.</li>
<li>SockJS internally supports different transport mechanisms. You might face specific limitations
depending on actual transport in use.</li>
<li>Auto reconnect is not quite reliable with SockJS.</li>
<li>Heartbeats may not be supported over SockJS by some brokers.</li>
<li>SockJS does not allow more than one simultaneous connection to the same broker.
This usually is not a problem for most of the applications.</li>
</ul>
<p>It is advised to use WebSockets by default and then fall back to SockJS if the browser does not support.</p>
<h2 id="basic-installation">Basic installation</h2>
<h3 id="in-nodejs-environments">In Node.js environments</h3>
<p>Please install the latest<a href="https://github.com/sockjs/sockjs-client">SockJS client</a>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>npm <span class="nb">install </span>sockjs-client <span class="nt">--save</span>
</code></pre></div></div>
<h3 id="import-sockjs-class">Import SockJS class</h3>
<p>Depending on your programming language/environment, you may have to <code class="language-plaintext highlighter-rouge">import</code> or <code class="language-plaintext highlighter-rouge">require</code> it:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">SockJS</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">sockjs-client</span><span class="dl">'</span><span class="p">;</span>
</code></pre></div></div>
<h3 id="in-the-browser">In the browser</h3>
<p>Add the following to include directly in the browser:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"</span><span class="nt">></script></span>
</code></pre></div></div>
<h2 id="implement-a-websocketfactory">Implement a webSocketFactory</h2>
<p>Create a function that returns an object similar to WebSocket (typically SockJS instance).</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">mySocketFactory</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">SockJS</span><span class="p">(</span><span class="dl">'</span><span class="s1">http://127.0.0.1:15674/stomp</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>This function should return a WebSocket compatible object.</p>
<p><strong>Note: this function may be invoked multiple times.
Each time a broker (re)connects, it needs a new instance of WebSocket/SockJS.</strong></p>
<h2 id="usage">Usage</h2>
<p>You should set <a href="/api-docs/latest/classes/Client.html#webSocketFactory">webSocketFactory</a> instead of <a href="/api-docs/latest/classes/Client.html#brokerURL">brokerURL</a> in your configuration.</p>
<p>You can even check if WebSocket is available and accordingly use SockJS as a fallback.
See the example below.</p>
<p><strong>Note: if you set both <a href="/api-docs/latest/classes/Client.html#webSocketFactory">webSocketFactory</a> takes precedence.</strong></p>
<h2 id="example-with-stompjs">Example with stompjs</h2>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">StompJs</span><span class="p">.</span><span class="nx">Client</span><span class="p">({</span>
<span class="na">brokerURL</span><span class="p">:</span> <span class="dl">'</span><span class="s1">ws://localhost:15674/ws</span><span class="dl">'</span><span class="p">,</span>
<span class="na">connectHeaders</span><span class="p">:</span> <span class="p">{</span>
<span class="na">login</span><span class="p">:</span> <span class="dl">'</span><span class="s1">user</span><span class="dl">'</span><span class="p">,</span>
<span class="na">passcode</span><span class="p">:</span> <span class="dl">'</span><span class="s1">password</span><span class="dl">'</span><span class="p">,</span>
<span class="p">},</span>
<span class="na">debug</span><span class="p">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">str</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">str</span><span class="p">);</span>
<span class="p">},</span>
<span class="na">reconnectDelay</span><span class="p">:</span> <span class="mi">5000</span><span class="p">,</span>
<span class="na">heartbeatIncoming</span><span class="p">:</span> <span class="mi">4000</span><span class="p">,</span>
<span class="na">heartbeatOutgoing</span><span class="p">:</span> <span class="mi">4000</span><span class="p">,</span>
<span class="p">});</span>
<span class="c1">// Fallback code</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">WebSocket</span> <span class="o">!==</span> <span class="dl">'</span><span class="s1">function</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// For SockJS you need to set a factory that creates a new SockJS instance</span>
<span class="c1">// to be used for each (re)connect</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">webSocketFactory</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="c1">// Note that the URL is different from the WebSocket URL</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">SockJS</span><span class="p">(</span><span class="dl">'</span><span class="s1">http://localhost:15674/stomp</span><span class="dl">'</span><span class="p">);</span>
<span class="p">};</span>
<span class="p">}</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">onConnect</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">frame</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Do something, all subscribes must be done is this callback</span>
<span class="c1">// This is needed because this will be executed after a (re)connect</span>
<span class="p">};</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">onStompError</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">frame</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Will be invoked in case of error encountered at Broker</span>
<span class="c1">// Bad login/passcode typically will cause an error</span>
<span class="c1">// Complaint brokers will set `message` header with a brief message. Body may contain details.</span>
<span class="c1">// Compliant brokers will terminate the connection after any error</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Broker reported error: </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">frame</span><span class="p">.</span><span class="nx">headers</span><span class="p">[</span><span class="dl">'</span><span class="s1">message</span><span class="dl">'</span><span class="p">]);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Additional details: </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">frame</span><span class="p">.</span><span class="nx">body</span><span class="p">);</span>
<span class="p">};</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">activate</span><span class="p">();</span>
</code></pre></div></div>
<p>Compare the above against the sample in <a href="/guide/stompjs/using-stompjs-v5.html">using StompJS</a>,
only addition is the fallback code trying to use SockJS if WebSocket is unavailable.
You will need to include latest <a href="https://github.com/sockjs/sockjs-client">SockJS client</a> in your web page.</p>
<h2 id="sockjs-in-angular6">SockJS in Angular6</h2>
<p>See: <a href="https://github.com/stomp-js/ng2-stompjs/issues/70">ng2-stompjs/issues/70</a>.</p>
<p>When you are using SockJS in an Angular6 project you might get <strong>“global is not defined”</strong>.</p>
<p>The underlying issue can only be fixed by SockJS or Angular teams.
Try any of the following workarounds (from <a href="https://github.com/stomp-js/ng2-stompjs/issues/70">ng2-stompjs/issues/70</a>):</p>
<ul>
<li>In your index.html file, in the header add the following:</li>
</ul>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><script </span><span class="na">type=</span><span class="s">"application/javascript"</span><span class="nt">></span>
<span class="kd">var</span> <span class="nb">global</span> <span class="o">=</span> <span class="nb">window</span><span class="p">;</span>
<span class="nt"></script></span>
</code></pre></div></div>
<ul>
<li>Add following to your <code class="language-plaintext highlighter-rouge">polyfill.ts</code>:</li>
</ul>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">window</span> <span class="k">as</span> <span class="kr">any</span><span class="p">).</span><span class="nb">global</span> <span class="o">=</span> <span class="nb">window</span><span class="p">;</span>
</code></pre></div></div>StompJSThere are a large number of obsolete (and copied from one another) examples for these libraries that use SockJS. In reality, there is very little chance that you need SockJS. Unless you know, for sure, you do not need SockJS.Upgrading StompJs2018-09-08T11:34:43+00:002018-09-08T11:34:43+00:00https://stomp-js.github.io/guide/stompjs/upgrading-stompjs<h2 id="upgrading-from-version-34">Upgrading from version 3/4</h2>
<p><em>Important: For NodeJS and React Native, please check <a href="/guide/stompjs/rx-stomp/polyfills-for-stompjs.html">Polyfills</a>.</em></p>
<h3 id="basic-changes">Basic changes</h3>
<p>Please follow section <a href="/guide/stompjs/using-stompjs-v5.html#include-stompjs">Include STOMP.js</a>
to add the latest version.</p>
<p>The following is for convenience, — to keep the code change to the minimum.</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Depending on your JS version you may have to use var instead of const</span>
<span class="c1">// To use compatibility mode</span>
<span class="kd">const</span> <span class="nx">Stomp</span> <span class="o">=</span> <span class="nx">StompJs</span><span class="p">.</span><span class="nx">Stomp</span><span class="p">;</span>
</code></pre></div></div>
<h3 id="for-the-lazy-use-the-compatibility-mode">For the lazy: use the compatibility mode</h3>
<p>With the changes above, your code should now work. If you face issues, please
raise an issue at https://github.com/stomp-js/stompjs/issues.</p>
<p><em>Note: no new features will be added to the compatibility mode.
Attempt would be made so that code working in version 3/4 continues
to work. The compatibility mode will be maintained till 2020.</em></p>
<h3 id="take-control-proper-upgrade">Take control: proper upgrade</h3>
<p>This section covers the rationale of new features and
changes needed to take full advantage.</p>
<h4 id="creating-a-client-and-connecting">Creating a client and connecting</h4>
<p>In version 3/4, typically, a client instance is created and one of the
variants of connect is called.
Over the years, connect has gotten many variants with a different
combination of parameters.</p>
<p>The new version makes all options settable on client instance.
These options can be passed during creation of a client or while
calling <a href="/api-docs/latest/classes/Client.html#activate">client.activate</a>.</p>
<p><strong>Old</strong></p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">client</span> <span class="o">=</span> <span class="nx">Stomp</span><span class="p">.</span><span class="nx">client</span><span class="p">(</span><span class="dl">'</span><span class="s1">ws://localhost:15674/ws</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">debug</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">str</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">str</span><span class="p">);</span>
<span class="p">};</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">heartbeat</span><span class="p">.</span><span class="nx">incoming</span> <span class="o">=</span> <span class="mi">4000</span><span class="p">;</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">heartbeat</span><span class="p">.</span><span class="nx">outgoing</span> <span class="o">=</span> <span class="mi">4000</span><span class="p">;</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">reconnect_delay</span> <span class="o">=</span> <span class="mi">5000</span><span class="p">;</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">connect</span><span class="p">(</span><span class="dl">'</span><span class="s1">user</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">password</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="c1">// Do something</span>
<span class="p">});</span>
</code></pre></div></div>
<p><strong>Updated</strong></p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">StompJs</span><span class="p">.</span><span class="nx">Client</span><span class="p">({</span>
<span class="na">brokerURL</span><span class="p">:</span> <span class="dl">'</span><span class="s1">ws://localhost:15674/ws</span><span class="dl">'</span><span class="p">,</span>
<span class="na">connectHeaders</span><span class="p">:</span> <span class="p">{</span>
<span class="na">login</span><span class="p">:</span> <span class="dl">'</span><span class="s1">user</span><span class="dl">'</span><span class="p">,</span>
<span class="na">passcode</span><span class="p">:</span> <span class="dl">'</span><span class="s1">password</span><span class="dl">'</span><span class="p">,</span>
<span class="p">},</span>
<span class="na">debug</span><span class="p">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">str</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">str</span><span class="p">);</span>
<span class="p">},</span>
<span class="na">reconnectDelay</span><span class="p">:</span> <span class="mi">5000</span><span class="p">,</span>
<span class="na">heartbeatIncoming</span><span class="p">:</span> <span class="mi">4000</span><span class="p">,</span>
<span class="na">heartbeatOutgoing</span><span class="p">:</span> <span class="mi">4000</span><span class="p">,</span>
<span class="p">});</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">onConnect</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">frame</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Do something</span>
<span class="p">};</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">activate</span><span class="p">();</span>
</code></pre></div></div>
<p>Please see <a href="/api-docs/latest/classes/StompConfig.html">StompConfig</a> for all possible options.
These options can be set onto <a href="/api-docs/latest/classes/Client.html">client</a>.
Alternatively, these can be passed
as options to the <a href="/api-docs/latest/classes/Client.html#constructor">Client constructor</a> constructor,
the <a href="/api-docs/latest/classes/Client.html#activate">Client#activate</a>
or the <a href="/api-docs/latest/classes/Client.html#deactivate">Client#deactivate</a> calls.
If you want to set options in bulk, you can use <a href="/api-docs/latest/classes/Client.html#configure">Client#configure</a>.</p>
<h4 id="publishing-messages">Publishing messages</h4>
<p><strong>Old</strong></p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">client</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="dl">'</span><span class="s1">/topic/general</span><span class="dl">'</span><span class="p">,</span> <span class="p">{},</span> <span class="dl">'</span><span class="s1">Hello world</span><span class="dl">'</span><span class="p">);</span>
<span class="c1">// Skip content length header</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="dl">'</span><span class="s1">/topic/general</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span> <span class="dl">'</span><span class="s1">content-length</span><span class="dl">'</span><span class="p">:</span> <span class="kc">false</span> <span class="p">},</span> <span class="dl">'</span><span class="s1">Hello world</span><span class="dl">'</span><span class="p">);</span>
<span class="c1">// Additional headers</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="dl">'</span><span class="s1">/topic/general</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span> <span class="na">priority</span><span class="p">:</span> <span class="dl">'</span><span class="s1">9</span><span class="dl">'</span> <span class="p">},</span> <span class="dl">'</span><span class="s1">Hello world</span><span class="dl">'</span><span class="p">);</span>
</code></pre></div></div>
<p><strong>Updated</strong></p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">client</span><span class="p">.</span><span class="nx">publish</span><span class="p">({</span> <span class="na">destination</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/topic/general</span><span class="dl">'</span><span class="p">,</span> <span class="na">body</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Hello world</span><span class="dl">'</span> <span class="p">});</span>
<span class="c1">// There is an option to skip content length header</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">publish</span><span class="p">({</span>
<span class="na">destination</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/topic/general</span><span class="dl">'</span><span class="p">,</span>
<span class="na">body</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Hello world</span><span class="dl">'</span><span class="p">,</span>
<span class="na">skipContentLengthHeader</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="p">});</span>
<span class="c1">// Additional headers</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">publish</span><span class="p">({</span>
<span class="na">destination</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/topic/general</span><span class="dl">'</span><span class="p">,</span>
<span class="na">body</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Hello world</span><span class="dl">'</span><span class="p">,</span>
<span class="na">headers</span><span class="p">:</span> <span class="p">{</span> <span class="na">priority</span><span class="p">:</span> <span class="dl">'</span><span class="s1">9</span><span class="dl">'</span> <span class="p">},</span>
<span class="p">});</span>
</code></pre></div></div>
<h4 id="semantic-changes">Semantic changes</h4>
<ul>
<li><a href="/api-docs/latest/classes/Stomp.html#client">Stomp.client</a> –> <a href="/api-docs/latest/classes/Client.html#constructor">Client constructor</a>
and <a href="/api-docs/latest/classes/Client.html#brokerURL">Client#brokerURL</a></li>
<li><a href="/api-docs/latest/classes/Stomp.html#over">Stomp.over</a> –> <a href="/api-docs/latest/classes/Client.html#constructor">Client constructor</a>
and <a href="/api-docs/latest/classes/Client.html#webSocketFactory">Client#webSocketFactory</a></li>
<li><a href="/api-docs/latest/classes/CompatClient.html#connect">connect</a> –> <a href="/api-docs/latest/classes/Client.html#activate">Client#activate</a>
<ul>
<li>login, passcode, host –> <a href="/api-docs/latest/classes/Client.html#connectHeaders">Client#connectHeaders</a></li>
<li>connectCallback –> <a href="/api-docs/latest/classes/Client.html#onConnect">Client#onConnect</a></li>
<li>errorCallback –> <a href="/api-docs/latest/classes/Client.html#onStompError">Client#onStompError</a></li>
<li>closeEventCallback –> <a href="/api-docs/latest/classes/Client.html#onWebSocketClose">Client#onWebSocketClose</a></li>
</ul>
</li>
<li><a href="/api-docs/latest/classes/CompatClient.html#disconnect">disconnect</a> –> <a href="/api-docs/latest/classes/Client.html#deactivate">Client#deactivate</a>
<ul>
<li>disconnectCallback –> <a href="/api-docs/latest/classes/Client.html#onDisconnect">Client#onDisconnect</a></li>
</ul>
</li>
<li><a href="/api-docs/latest/classes/CompatClient.html#send">send</a> –> <a href="/api-docs/latest/classes/Client.html#publish">Client#publish</a></li>
</ul>
<h4 id="name-changes">Name changes</h4>
<p>These changes have been carried out in order to make a consistent naming convention (lowerCamelCase)
and to make the meaning of the option clearer.</p>
<ul>
<li><a href="/api-docs/latest/classes/CompatClient.html#reconnect_delay">reconnect_delay</a> –> <a href="/api-docs/latest/classes/Client.html#reconnectDelay">Client#reconnectDelay</a></li>
<li><a href="/api-docs/latest/classes/CompatClient.html#ws">ws</a> –> <a href="/api-docs/latest/classes/Client.html#webSocket">Client#webSocket</a></li>
<li><a href="/api-docs/latest/classes/CompatClient.html#version">version</a> –> <a href="/api-docs/latest/classes/Client.html#connectedVersion">Client#connectedVersion</a></li>
<li><a href="/api-docs/latest/classes/CompatClient.html#onreceive">onreceive</a> –> <a href="/api-docs/latest/classes/Client.html#onUnhandledMessage">Client#onUnhandledMessage</a></li>
<li><a href="/api-docs/latest/classes/CompatClient.html#onreceipt">onreceipt</a> –> <a href="/api-docs/latest/classes/Client.html#onUnhandledReceipt">Client#onUnhandledReceipt</a></li>
<li><a href="/api-docs/latest/classes/CompatClient.html#heartbeat">heartbeat</a>.incoming –> <a href="/api-docs/latest/classes/Client.html#heartbeatIncoming">Client#heartbeatIncoming</a></li>
<li><a href="/api-docs/latest/classes/CompatClient.html#heartbeat">heartbeat</a>.outgoing –> <a href="/api-docs/latest/classes/Client.html#heartbeatOutgoing">Client#heartbeatOutgoing</a></li>
</ul>
<h4 id="dropped-apis">Dropped APIs</h4>
<ul>
<li><a href="/api-docs/latest/classes/CompatClient.html#maxWebSocketFrameSize">maxWebSocketFrameSize</a> — large messages
work without this. Test cases have been added to test large text and binary messages.</li>
</ul>
<h2 id="migrating-from-version-2">Migrating from Version 2</h2>
<p>You will need to follow the instructions above with few additional considerations.</p>
<p>Please note:</p>
<ul>
<li>Auto reconnect is switched on by default.
Set <a href="/api-docs/latest/classes/Client.html#reconnectDelay">Client#reconnectDelay</a> to <code class="language-plaintext highlighter-rouge">0</code> to disable.</li>
<li>After each connect (i.e., the initial connect as well each reconnection) the
<a href="/api-docs/latest/classes/Client.html#onConnect">Client#onConnect</a> (connectCallback in earlier versions)
will be called.</li>
<li>After reconnecting, it will not automatically subscribe to queues that were subscribed.
So, if all subscriptions are part of the
<a href="/api-docs/latest/classes/Client.html#onConnect">Client#onConnect</a> (which it would in most of the cases),
you will not need to do any additional handling.</li>
</ul>
<p>Additional notes:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">Stomp.overWS</code> is same as <code class="language-plaintext highlighter-rouge">Stomp.client</code>. Follow the instructions for <code class="language-plaintext highlighter-rouge">Stomp.client</code> above.</li>
<li><code class="language-plaintext highlighter-rouge">NodeJS</code> is supported at same level as browser. Test suits are executed for both NodJS and browser.
Follow the instructions as above.</li>
<li><code class="language-plaintext highlighter-rouge">Stomp.overTCP</code> is no longer supported. If your broker supports WebStomp (STOMP over WebSocket),
you may switch to that.</li>
<li>If you are using <code class="language-plaintext highlighter-rouge">SockJS</code> please also see <a href="/guide/stompjs/rx-stomp/using-stomp-with-sockjs.html">SockJS support</a></li>
</ul>StompJSUpgrading from version 3/4StompJs v5+, RxStomp: Polyfills2018-06-29T02:29:22+00:002018-06-29T02:29:22+00:00https://stomp-js.github.io/guide/stompjs/rx-stomp/polyfills-for-stompjs<p>This guide covers critical dependencies and polyfills for version 5+ of <code class="language-plaintext highlighter-rouge">@stomp/stompjs</code>;
which is internally used by <code class="language-plaintext highlighter-rouge">@stomp/rx-stomp</code> as well.</p>
<h2 id="in-nodejs">In NodeJS</h2>
<h3 id="websocket">WebSocket</h3>
<p>There are two alternate libraries <code class="language-plaintext highlighter-rouge">websocket</code> and <code class="language-plaintext highlighter-rouge">ws</code> which have been reported to work.</p>
<h4 id="websocket-1">websocket</h4>
<ul>
<li>
<p>Add <code class="language-plaintext highlighter-rouge">websocket</code> npm module:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>npm <span class="nb">install </span>websocket
</code></pre></div> </div>
</li>
<li>
<p>Using <code class="language-plaintext highlighter-rouge">import</code> syntax</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nx">websocket</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">websocket</span><span class="dl">'</span><span class="p">;</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">assign</span><span class="p">(</span><span class="nb">global</span><span class="p">,</span> <span class="p">{</span> <span class="na">WebSocket</span><span class="p">:</span> <span class="nx">websocket</span><span class="p">.</span><span class="nx">w3cwebsocket</span> <span class="p">});</span>
</code></pre></div> </div>
</li>
</ul>
<h4 id="ws">ws</h4>
<ul>
<li>Instead of <code class="language-plaintext highlighter-rouge">websocket</code> lib <code class="language-plaintext highlighter-rouge">ws</code> has also been reported to work.
See: <a href="https://github.com/stomp-js/stompjs/issues/28">stompjs/issues/28</a>.</li>
<li>
<p>Add <code class="language-plaintext highlighter-rouge">ws</code> npm module:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>npm <span class="nb">install </span>ws
</code></pre></div> </div>
</li>
<li>
<p>Require the module and expose it through <code class="language-plaintext highlighter-rouge">global</code></p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">WebSocket</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">ws</span><span class="dl">'</span><span class="p">;</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">assign</span><span class="p">(</span><span class="nb">global</span><span class="p">,</span> <span class="p">{</span> <span class="nx">WebSocket</span> <span class="p">});</span>
</code></pre></div> </div>
</li>
</ul>
<h2 id="in-react-native">In React Native</h2>
<h3 id="textencodertextdecoder">TextEncoder/TextDecoder</h3>
<ul>
<li>React Native makes it deceptive.
When an application is executed in debug mode, it works, as it is executed on an actual browser
where TextEncoder/TextDecoder is available.
However, when executed in production mode, it fails as TextEncoder/TextDecoder is not available.</li>
<li>Please install <code class="language-plaintext highlighter-rouge">text-encoding</code>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>npm <span class="nb">install </span>text-encoding
</code></pre></div> </div>
</li>
<li>
<p>Add the following to your <code class="language-plaintext highlighter-rouge">index.js</code> or <code class="language-plaintext highlighter-rouge">App.js</code>:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">encoding</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">text-encoding</span><span class="dl">'</span><span class="p">;</span>
</code></pre></div> </div>
</li>
<li>There are additional issues with React Native in some device/version combinations. Please see:
<a href="/workaround/stompjs/rx-stomp/ng2-stompjs/react-native-additional-notes.html">React Native - Additional Notes</a></li>
</ul>StompJSThis guide covers critical dependencies and polyfills for version 5+ of @stomp/stompjs; which is internally used by @stomp/rx-stomp as well.