<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Your Realtime Data Stream Network Blog</title>
	<atom:link href="https://www.pubnub.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.pubnub.com/</link>
	<description>Best Realtime Apps Powered by Global Data Stream Network</description>
	<lastBuildDate>Mon, 16 Sep 2019 07:24:12 +0000</lastBuildDate>
	<language>en-US</language>
   <image>
    <url>https://www.pubnub.com/static/images/structure/pubnub.png</url>
    <title>PubNub secure global data stream network and easy to use API for realtime Apps</title>
    <link>https://www.pubnub.com/</link>
    <width>513</width>
    <height>112</height>
  </image>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
	<item>
		<title>Delivering Live Updating Streams of GPS Coordinates with PubNub Signals</title>
		<link>https://www.pubnub.com/blog/send-a-stream-of-gps-coordinates-pubnub-signals/</link>
				<pubDate>Tue, 03 Sep 2019 16:40:51 +0000</pubDate>
		<dc:creator><![CDATA[Oscar Castro]]></dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Maps and Geolocation]]></category>
		<category><![CDATA[GoogleMaps API]]></category>
		<category><![CDATA[Dispatch and Tracking]]></category>
		<category><![CDATA[PubNub Signals]]></category>
		<description><![CDATA[<p>How to stream geolocation coodinates in realtime for mobile applications with PubNub Signals, a messaging feature for low-cost, small payloads.</p>
<p>The post <a  href="https://www.pubnub.com/blog/send-a-stream-of-gps-coordinates-pubnub-signals/">Delivering Live Updating Streams of GPS Coordinates with PubNub Signals</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Not all message sizes are the same. For example, the size for sending a text message is much greater than sending GPS coordinates. Not only that, text messages must be encrypted and stored in history for later retrieval while coordinates are useful for a brief moment of time. It seems fair that larger payloads should be priced higher than smaller payloads. With this in mind, PubNub has launched Signals.</p>
<h2>PubNub Signals</h2>
<p>PubNub Signals is small message payload messaging, no greater than <strong>30 bytes</strong>, that offers a <strong>low-cost</strong> data delivery rate while still leveraging PubNub&#8217;s secure and reliable <a href="https://www.pubnub.com/products/global-data-stream-network/" target="_blank" rel="noopener noreferrer">Data Stream Network</a>. Some use cases for Signals include:</p>
<ol>
<li><a href="https://www.pubnub.com/blog/chat-typing-indicators-javascript-pubnub-signals/">Typing indicators in a chat app</a></li>
<li>GPS lat/long updates (what we&#8217;ll cover in this tutorial)</li>
<li>Sensor streaming updates for IoT devices</li>
<li>Stats for gaming applications</li>
</ol>
<h2>When to Use Signals Instead of Publish?</h2>
<p>If your application needs to send a stream of messages to instruct or inform your application, where the content of each message is not as important as the stream of data, then use Signals. Signals uses the core Pub/Sub features such as <a href="https://www.pubnub.com/developers/tech/key-concepts/stream-controller/channel-groups/" target="_blank" rel="noopener noreferrer">channels groups</a> and <a href="https://www.pubnub.com/docs/getting-started-guides/pubnub-access-manager" target="_blank" rel="noopener noreferrer">PubNub Access Manager</a>.</p>
<p>Unlike Publish, there are some limitations to using Signals:</p>
<ol>
<li>Messages sent with Signals are not replicated to all global data centers</li>
<li>Messages are not stored in <a href="https://www.pubnub.com/docs/getting-started-guides/pubnub-storage-and-playback" target="_blank" rel="noopener noreferrer">PubNub History</a> for later retrieval; only the most recent message can be fetched</li>
<li><a href="https://www.pubnub.com/developers/tech/push-notifications/" target="_blank" rel="noopener noreferrer">PubNub Push notifications</a> can&#8217;t be invoked</li>
<li>Access to <a href="https://www.pubnub.com/products/functions/" target="_blank" rel="noopener noreferrer">PubNub Functions</a> is disabled by default and can only be enabled by PubNub Support</li>
</ol>
<h2>Geolocation App with PubNub Signals</h2>
<p>To get a better understanding of what you can do with PubNub Signals, let&#8217;s go over a <a href="https://github.com/ocastroa/GeolocationWithSignals/tree/master/app" target="_blank" rel="noopener noreferrer">simple geolocation app</a> in Android. For this app, a marker will initially be placed in San Francisco. The user can move and place the marker anywhere they please, and the coordinates will be sent to a global channel using Signals. The marker will update for everyone connected to the channel.</p>
<a href="https://www.pubnub.com/wp-content/uploads/2019/08/geolocation_app_screenshot.png"><img class=" wp-image-45745 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/08/geolocation_app_screenshot.png" alt="Geolocation App Screenshot" width="452" height="385" /></a>
<p style="text-align: center;"><strong>Note</strong>: This app <strong>DOES NOT</strong> use your location!</p>
<h3>Get Your API Keys</h3>
<p>Sign up for your <strong>free PubNub API keys</strong>. You can send up to <strong>1 million free messages </strong>a month! Use the form below to get your keys:</p>
<p><iframe style="width: 100%; min-height: 400px;" title="SignUp Form" src="https://pubsub-quickstart-app.pubnub.com/signup"><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start">﻿</span>Your browser does not support iframes.</iframe></p>
<p>Once you have your keys, add them to <strong>initiPubNub()</strong> in <strong>MainActivity.java</strong>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java"> // Variables
 private GoogleMap mMap;
 private PubNub pubnub;
 private Marker marker;
 private Boolean isMarkerPlaced = false;

// Initialize PubNub and set up a listener
public void initPubNub(){
  PNConfiguration pnConfiguration = new PNConfiguration();
  pnConfiguration.setPublishKey("Your_Pub_Key_Here");
  pnConfiguration.setSubscribeKey("Your_Sub_Key_Here");
  pnConfiguration.setSecure(true);
  pubnub = new PubNub(pnConfiguration);
 ...
}
</pre>
<p>Besides the Pub/Sub keys, you also need to get a <a href="https://developers.google.com/maps/documentation/embed/get-api-key" target="_blank" rel="noopener noreferrer">Google Maps API key</a>. Once you have the key, go to the <strong>debug </strong>directory, under <strong>src</strong>, and add it to the file <strong>google_maps_api.xml</strong>.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="xml">&lt;resources&gt;
    &lt;string name="google_maps_key" templateMergeStrategy="preserve" translatable="false"&gt;YOUR_KEY_HERE&lt;/string&gt;
&lt;/resources&gt;</pre>
<p>Now that we have all the keys set up in the app, let&#8217;s go over the app.</p>
<h3>Set Up PubNub&#8217;s Event Listener</h3>
<p>After initializing PubNub, we set up an event listener to listen for messages that arrive on the channel. Inside the listener, we implement the method <strong>signal()</strong>.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">// Listen to messages that arrive in the channel
pubnub.addListener(new SubscribeCallback() {
  @Override
  public void status(PubNub pub, PNStatus status) {

  }

  @Override
  public void message(PubNub pub, final PNMessageResult message) {

  }

  @Override
  public void presence(PubNub pub, PNPresenceEventResult presence) {

  }

  @Override
  public void signal(PubNub pubnub, final PNMessageResult signal) {
    System.out.println("Message: " + signal.getMessage());

    runOnUiThread(new Runnable() {
      @Override
      public void run() {
        try {
          JsonArray payload = signal.getMessage().getAsJsonArray();
          placeMarker(payload);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
  }
});</pre>
<p>Since we are no longer publishing the GPS coordinates with PubNub Publish, the method <strong>message()</strong> is empty. Inside of the <strong>signal</strong><strong>() </strong>method, the message payload is received, converted into a JsonArray, and <strong>placeMarker()</strong> is called to update the current marker with the new coordinates in the map. We&#8217;ll come back to this method<strong> </strong>shortly.</p>
<p>Below <strong>addListener()</strong>, subscribe to the global channel <em>geolocation_channel </em>.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">// Subscribe to the global channel
pubnub.subscribe()
      .channels(Arrays.asList("geolocation_channel"))
      .execute();
</pre>
<p>Next, let&#8217;s set up the marker on the map and add a drag and drop event listener for the marker.</p>
<h3>Set Up Google Maps Event Listener</h3>
<p>As mentioned earlier, the marker is initially placed in San Francisco. To add the marker in the map, <strong>placeMarker()</strong> is called with the marker coordinates as the argument. Before we get to this method, let&#8217;s complete the method <strong>onMapReady()</strong> which is triggered when Google Maps is ready to use.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">public void onMapReady(GoogleMap googleMap) {
  mMap = googleMap;

  // Initial payload coordinates in S.F.<img src="https://s.w.org/images/core/emoji/12.0.0-1/72x72/2665.png" alt="♥" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎
  JsonArray payload = new JsonArray();
  payload.add(37.782486);
  payload.add(-122.395344);
  placeMarker(payload);
}</pre>
<p>We need to add an event listener that is triggered when the marker is dragged anywhere in the map. Add the following code to <strong>onMapReady()</strong>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">// Initial payload coordinates in S.F.<img src="https://s.w.org/images/core/emoji/12.0.0-1/72x72/2665.png" alt="♥" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎
...

// Listener for when marker is dragged to another location
mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() {
  @Override
  public void onMarkerDrag(Marker arg0) {
    Log.d("Marker", "Dragging");
  }

  @Override
  public void onMarkerDragEnd(Marker arg0) {
    Log.d("Marker", "Finished");
  }

  @Override
  public void onMarkerDragStart(Marker arg0) {
    Log.d("Marker", "Started");
  }
});</pre>
<p>Once the user has placed the marker in a new location, the Lat/Long coordinates are sent to the global channel to update the marker placement for everyone connected. To do so, we get the new position of the marker, add it to a JsonArray, and send the payload to the channel. Since we can only send <strong>30 bytes</strong>, we <a href="https://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html" target="_blank" rel="noopener noreferrer">format</a> the coordinate values up to 6 digits after the decimal point, which is the same format that Google Maps uses. We do all of this logic inside of <strong>onMarkerDragEnd()</strong>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">@Override
public void onMarkerDragEnd(Marker arg0) {
  Log.d("Marker", "Finished");

  // Get coordinate values up to 6 decimal numbers
  DecimalFormat decimalFormat = new DecimalFormat("0.######");
  JsonArray payload = new JsonArray();
  payload.add(decimalFormat.format(marker.getPosition().latitude)); // Get lat coord.
  payload.add(decimalFormat.format(marker.getPosition().longitude)); // Get long coord.

  // Message Payload size for PubNub Signals is limited to 30 bytes
  pubnub.signal()
        .channel("geolocation_channel")
        .message(payload)
        .async(new PNCallback&lt;PNPublishResult&gt;() {
          @Override
          public void onResponse(PNPublishResult result, PNStatus status) {
            // Error
            if(status.isError()) {
              System.out.println("Error- pub status code: " + status.getStatusCode());
            }
          }
        });
}</pre>
<p>If the payload is successfully sent and received on the channel, the marker is placed on the map.</p>
<h3>Place the Marker on the Map</h3>
<p>In the app, we call <strong>placeMarker() </strong>twice to add the marker in the initial location and to update the marker in a new location. In order for the method to know which of the two things to do, we use the boolean variable <strong>isMarkerPlaced</strong>. This variable is initialized to <em>false</em>. It is set to <em>true</em> once the maker has been placed.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">// Place marker on the map in the specified location
public void placeMarker(JsonArray loc){
  //LatLng only accepts arguments of type Double
  Double lat = loc.get(0).getAsDouble();
  Double lng = loc.get(1).getAsDouble();
  LatLng newLoc = new LatLng(lat,lng);

  if(isMarkerPlaced){
    // Change position of the marker
    marker.setPosition(newLoc);
    marker.setTitle(newLoc.toString());
  }
  else{
    // Add a marker to the map in the specified location
    marker = mMap.addMarker(new MarkerOptions().position(newLoc).title(newLoc.toString()).draggable(true));
    isMarkerPlaced = true;
  }

  // Move the camera to the location of the marker
  mMap.moveCamera(CameraUpdateFactory.newLatLng(newLoc));
}</pre>
<h3>Run the Geolocation App</h3>
<p>In Android Studio, run the app in two emulators to see the markers change location in realtime!</p>
<p><iframe title="Send GPS Coordinates with PubNub Signals" src="https://www.youtube.com/embed/x8m7PS2TUZo" width="850" height="450" frameborder="0" allowfullscreen="allowfullscreen"><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start">﻿</span><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start">﻿</span>﻿</span><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span></iframe></p>
<p>Now that you know how to send GPS coordinates using <strong>PubNub Signals</strong>, check out other ways to use Signals, such as implementing <a href="https://www.pubnub.com/blog/chat-typing-indicators-javascript-pubnub-signals/?preview_id=45657&amp;preview_nonce=a67a9e80fa&amp;post_format=standard&amp;_thumbnail_id=-1&amp;preview=true" target="_blank" rel="noopener noreferrer">Typing Indicators in a Chat App</a>.</p>
<p><strong>Have suggestions or questions about the content of this post? Reach out at <a href="mailto:devrel@pubnub.com" target="_blank" rel="noopener noreferrer" data-rawhref="mailto:devrel@pubnub.com">devrel@pubnub.com</a>.</strong></p><p>The post <a  href="https://www.pubnub.com/blog/send-a-stream-of-gps-coordinates-pubnub-signals/">Delivering Live Updating Streams of GPS Coordinates with PubNub Signals</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Build a Text-to-Speech Chat App with Amazon Polly and PubNub</title>
		<link>https://www.pubnub.com/blog/build-accessible-chat-app-text-to-speech-amazon-polly-pubnub/</link>
				<pubDate>Fri, 23 Aug 2019 17:52:04 +0000</pubDate>
		<dc:creator><![CDATA[Shyam Purkayastha]]></dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[BLOCKS]]></category>
		<category><![CDATA[Text-to-Speech]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Cognitive Services]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Amazon]]></category>
		<category><![CDATA[Amazon Polly]]></category>
		<description><![CDATA[<p>How to build a realtime chat app that turns chat messages into natural speech with Amazon Polly and PubNub.</p>
<p>The post <a  href="https://www.pubnub.com/blog/build-accessible-chat-app-text-to-speech-amazon-polly-pubnub/">Build a Text-to-Speech Chat App with Amazon Polly and PubNub</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Accessibility for computer applications is quite often an overlooked consideration during development. A user interface that works for one person might be completely constrained for a disabled person. Hence, as designers and developers, the onus is on us to empathize with one and all so that we can bring in inclusivity in all our creations.</p>
<p>In this blog post, we take a dig into this very aspect of how to make apps more accessible. Since <a href="https://www.pubnub.com/solutions/chat/">chat-based applications</a> <a href="https://www.pubnub.com/learn/ebooks/chat-is-more-than-hot-air/">continue to grow in adoption</a>, why not bring in the accessibility angle to it? Here at PubNub, we make chat easy for developers to build. Let’s see how we can quickly enable text-to-speech capabilities for chat apps built with PubNub, to assist a blind user.</p>
<p><iframe title="Demo: How to build a text-to-speech chat app with Amazon Polly" width="500" height="281" src="https://www.youtube.com/embed/Ulm0E4vVRtc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<h2>Technology That Assists Blind Users</h2>
<p>Due to visual impairment, a blind user is severely constrained in reading the incoming chat messages. To assist this user, the most obvious solution is to use a text-to-speech engine that synthesizes speech from the incoming chat messages.</p>
<p>The technology behind text-to-speech is already available. But instead of locally processing the text, it&#8217;s better to leverage the cloud so that the system can continuously learn and improve its speech rendering capabilities. <a href="https://aws.amazon.com/polly/">Amazon Polly</a> is one such service offered under the <a href="https://aws.amazon.com/machine-learning/">AWS Machine Learning</a> umbrella.</p>
<img class="aligncenter size-large wp-image-36911" src="https://www.pubnub.com/wp-content/uploads/2018/09/text-to-speech-1024x434.png" alt="" width="1024" height="434" />
<p>One of Amazon Polly&#8217;s most valuable capabilities is the ability to stream natural speech, which is a big plus for a realtime application like chat. We are going to leverage this feature to build a speech-enabled chat client on top of PubNub.</p>
<h2>PubNub and Text-To-Speech Chat Apps</h2>
<p>If you are familiar with PubNub, you probably know how easy it is to launch your own chat app. In order to connect to the globally distributed, auto-scaling PubNub Data-Stream-Network, create free Pub/Sub keys with the form below. API keys work instantly, and they allow up to 1 million messages per month for free.</p>
<p><iframe style="width: 100%; min-height: 450px;" src="https://pubsub-quickstart-app.pubnub.com/signup">Your browser does not support iframes.</iframe></p>
<p><strong>Be sure to enable Functions, Presence, and History for the key set in the <a href="https://dashboard.pubnub.com/">PubNub Admin Dashboard</a> before continuing!</strong></p>
<h3>Speech-enabled Chat App</h3>
<p>To enable speech prompts for incoming chat messages, we can think of an icon that activates this feature. Something like this.</p>
<img class="wp-image-45962 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/08/pubnub-chat-tts-aws-polly.png" alt="Amazon Polly Chat with PubNub" width="674" height="488" />
<p>Notice the icon at the top right area of the chat UI. With this icon, we can enable or disable this feature with a simple click.</p>
<p><em>Note: The clicking of an icon is also a constraint for a blind user. As an enhancement, the UX designers can think of a keyboard shortcut or some other means of making it more accessible.</em></p>
<h2>Tutorial Assets and Technology Overview</h2>
<p>The source code of this speech-enabled chat app is <a href="https://github.com/PubNubDevelopers/SpeechEnabledChatApp" target="_blank" rel="noopener noreferrer">available on GitHub</a>. Most of the code is from a demo chat app with jQuery and PubNub. <strong>With a few modifications, you can easily build the speech synthesis feature on top of the default chat app.</strong></p>
<p>You can clone the repository and follow along to get a sense of the code changes that are required.</p>
<p>Let’s look at the building blocks of this app by exploring the various technology components that work behind the scenes to deliver a functional chat experience. The <a href="https://github.com/PubNubDevelopers/SpeechEnabledChatApp/blob/master/README.md" target="_blank" rel="noopener noreferrer">README file</a> accompanying the repository contains the steps for setting up all the components.</p>
<h3>PubNub Functions</h3>
<p>PubNub’s serverless infrastructure called <a href="https://www.pubnub.com/products/functions/">Functions</a> can be used to spawn off the backend for this chat app. And since it is serverless, it can be brought to life within a few seconds.</p>
<p>We can quickly deploy an infinitely scalable, globally distributed REST API in a few minutes using PubNub Functions. Let&#8217;s clone the AWS Polly microservice using PubNub Functions. Go to the <a href="https://www.pubnub.com/docs/blocks-catalog/amazon-polly">PubNub AWS Polly Block page</a> and import the Function to your account. Click the <strong>Try It Now</strong> button, then follow the instructions.</p>
<img class="wp-image-45957 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/08/pubnub-function-aws-polly-block-import.png" alt="Import a PubNub Function screen" width="666" height="444" />
<p>If you have not already, you need to make an AWS account and create API keys to access the AWS Polly API. Follow these steps to set up your AWS account for accessing Amazon Polly service</p>
<p><strong>Step 1 :</strong> Setup an IAM user to access Amazon Polly service<br />
Follow these steps to <a href="https://docs.aws.amazon.com/polly/latest/dg/setting-up.html" target="_blank" rel="noopener noreferrer">create an IAM user for Amazon Polly</a>. Make sure that the IAM user has full permissions for accessing Amazon Polly service.</p>
<p><strong>Step 2 :</strong> Download the IAM user credentials<br />
Download the credentials file for the IAM user and save it. This file contains the AWS ACCESS KEY and AWS ACCESS SECRET KEY. Make a note of these two parameters.</p>
<img class="wp-image-45958 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/08/iam-aws-polly-setup-screen.png" alt="AWS Polly API Keys" width="744" height="419" />
<p>Now go to your PubNub Functions editor where you serverless JS event handler lives. Click on the MY SECRETS button on the left. Insert your AWS API keys here so the PubNub Functions server can use AWS Polly. The keys to insert in the PubNub Functions Vault are <strong>AWS_access_key</strong> and <strong>AWS_secret_key </strong>respectively.</p>
<img class="size-full wp-image-45959 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/08/aws-key-pubnub-functions-vault-screen-recording.gif" alt="PubNub Functions Vault Key Storage" width="508" height="448" />
<h3>PubNub Chat App Frontend</h3>
<p>Let&#8217;s go over the front end code for making a browser chat app with PubNub. The UI here is made with HTML, CSS, JS, and jQuery. All of the code can be cloned from this <a href="https://github.com/PubNubDevelopers/SpeechEnabledChatApp" target="_blank" rel="noopener noreferrer">GitHub Repository with the Text-To-Speech AWS Polly and PubNub chat app</a>.</p>
<h4>Chat UI</h4>
<p>Let&#8217;s make a button that enables the speech to be read aloud. It is a toggled button.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="html">&lt;div class="chat-header clearfix"&gt;
                &lt;img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/195612/chat_avatar_01_green.jpg" alt="avatar" /&gt;
                &lt;div class="chat-about"&gt;
                    &lt;div class="chat-with"&gt;PubNub with AWS Polly Demo Chat&lt;/div&gt;
                &lt;/div&gt;
                 &lt;div id="speechButton" class="speech-button"&gt;&lt;img src="./speech-icon.png"&gt;&lt;/div&gt;
            &lt;/div&gt;
</pre>
<p>And here is the CSS class to style this icon.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="css">.speech-button {

  float: right;
  margin-top: 6px;
  background-color: #d4e2dd;
  
}
</pre>
<h4>Speech Activation for Chat App</h4>
<p>HTML5 &lt;audio&gt; and &lt;video&gt; tags are the standard ways of embedding media controls on web apps. Since the app must be capable of playing the speech equivalent of chat messages, we have used the audio tag.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="html">&lt;audio id="player"&gt;
                
&lt;/audio&gt;
</pre>
<p>Now, let’s move to the JavaScript part of the chat app. We first need to check for the browser compatibility for supported audio media formats.</p>
<p>The default initialization is now subjected to another pre-condition that initializes the audio support for the browser. And finally, after the PubNub initialization, we can hook in the click event for the icon to activate/deactivate the speech feature.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">var AUDIO_FORMATS = {
    'ogg_vorbis': 'audio/ogg',
    'mp3': 'audio/mpeg',
    'pcm': 'audio/wave; codecs=1'
};

var supportedFormats;
var player;
var speechEnabled = false;

// this is our main function that starts our chat app
const init = () =&gt; {
    //First things first, check for the the browser's audio capabilities
    player = document.getElementById('player');
    supportedFormats = getSupportedAudioFormats(player);

    if (supportedFormats.length === 0) {
        submit.disabled = true;
        alert('The web browser in use does not support any of the' +
            ' available audio formats. Please try with a different' +
            ' one.');
    } else {

        pubnub.addListener({
            message: function(message) {
                renderMessage(message);
            },
            presence: function(presenceEvent) {
                let type = presenceEvent.action;

                if (type === 'join') {
                    let person = generatePerson(true);
                    person.uuid = presenceEvent.uuid;
                    $('#people-list ul').append(peopleTemplate(person));
                } else if (type === 'leave' || type === 'timeout') {
                    $('#people-list ul').find('#' + presenceEvent.uuid).remove();
                }
            }
        });

        pubnub.subscribe({
            channels: [chatChannel],
            withPresence: true
        });

        //get old messages from history
        pubnub.history({
                channel: chatChannel,
                count: 3,
                stringifiedTimeToken: true
            },
            function(status, response) {
                if (response.messages &amp;&amp; response.messages.length &gt; 0) {
                    response.messages.forEach((historicalMessage) =&gt; {
                        renderMessage(historicalMessage, true);
                    })
                }
            }
        );

        $("#speechButton").click(function() {

            if (speechEnabled) {
                speechEnabled = false;
                $("#speechButton").css("background-color", "#d4e2dd");

            } else {
                speechEnabled = true;
                $("#speechButton").css("background-color", "#4ceab1");
            }

        })

        $('#sendMessage').on('submit', sendMessage)
    }
};
</pre>
<h4>Speech Synthesis for Chat App</h4>
<p>The HTML5 audio tag has the ability to stream audio from a URL that returns a chunked HTTP response containing media content types.</p>
<p>Before rendering every chat message, the app will check for the speechEnabled flag. If it is enabled then it will make a request to the streaming server and play the speech received in response. Here is how the default renderMessage( ) function of the chat app looks like after speech enablement.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">// render messages in the list
const renderMessage = (message) =&gt; {

    // use the generic user template by default
    let template = userTemplate;

    // if I happened to send the message, use the special template for myself
    if (message.publisher === pubnub.getUUID()) {
        template = meTemplate;
    }

    let isHistory = false
    if (message &amp;&amp; !message.message) {
        console.log(message)
        message = { message: message.entry, timetoken: message.timetoken }
        isHistory = true;
    }

    var messageJsTime = new Date(parseInt(message.timetoken.substring(0, 13)));

    let el = template({
        messageOutput: message.message.text,
        tt: messageJsTime.getTime(),
        time: parseTime(messageJsTime),
        user: message.publisher
    });

    console.log(message);

    if (speechEnabled &amp;&amp; message.publisher != pubnub.getUUID()) {

        getPollyAudioForText(message.message.text).then((audio) =&gt; {
            player.src = audio
            player.play();
        })
    }

    chatHistoryUl.append(el);

    // chatHistoryUl.append(template(context));

    // Sort messages in chat log based on their timetoken (tt)
    chatHistoryUl
        .children()
        .sortDomElements(function(a, b) {
            akey = a.dataset.order;
            bkey = b.dataset.order;
            if (akey == bkey) return 0;
            if (akey &lt; bkey) return -1; if (akey &gt; bkey) return 1;
        })

    // scroll to the bottom of the chat
    scrollToBottom();

};
</pre>
<h3>Streaming Server for Test to Speech Conversion</h3>
<p>As mentioned earlier, we&#8217;re using Amazon Polly to enable text-to-speech conversion. The API is accessed via PubNub Functions. You need to copy the Function Endpoint URL using the functions editor. Click the copy URL button on the left side. This will be on the same screen that you used to insert your AWS API keys.</p>
<p>Paste the URL on the first line of <strong>chat.js</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">const pollyAudioPubNubFunction = 'YOUR_PUBNUB_FUNCTIONS_ENDPOINT_URL_HERE';</pre>
<p>Also insert your PubNub API keys, so the Chat Messaging functionality will work (also in the <strong>chat.js</strong> file).</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">let pubnub = new PubNub({
    publishKey: 'YOUR_FREE_PUBNUB_PUBLISH_KEY_HERE',
    subscribeKey: 'YOUR_FREE_PUBNUB_SUBSCRIBE_KEY_HERE',
    uuid: newPerson.uuid
});</pre>
<p>Every time the chat app sends a request to the PubNub Function, the client code is executed and a synthesized speech is generated on the fly and streamed back to the app. As awesome as it may seem, this is all we need, to enable speech synthesis capabilities to this chat app.</p>
<h2>Speech-enablement Beyond Accessibility</h2>
<p>Even beyond accessibility, this feature can also help in many use cases, that require voice prompts for background apps and specific events.</p>
<p>Other use cases for the <a href="https://www.pubnub.com/docs/blocks-catalog/amazon-polly">Amazon Polly Block</a> that invokes Amazon Polly service could be used to generate speech samples for specific text. This would be ideal for applications that require the generation of voice commands from a pre-defined list of text messages.</p><p>The post <a  href="https://www.pubnub.com/blog/build-accessible-chat-app-text-to-speech-amazon-polly-pubnub/">Build a Text-to-Speech Chat App with Amazon Polly and PubNub</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Using PubNub to Build Realtime Chat for Pirate Ducks</title>
		<link>https://www.pubnub.com/blog/building-a-basic-chat-pirate-ducks/</link>
				<pubDate>Thu, 22 Aug 2019 20:26:41 +0000</pubDate>
		<dc:creator><![CDATA[Mark Williams]]></dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Chat]]></category>
		<description><![CDATA[<p>Chat in realtime with the other pirate ducks on rafts distributed around the world.</p>
<p>The post <a  href="https://www.pubnub.com/blog/building-a-basic-chat-pirate-ducks/">Using PubNub to Build Realtime Chat for Pirate Ducks</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><strong>This is A&#8217;Quack.</strong></p>
<a href="https://www.pubnub.com/wp-content/uploads/2019/08/aquack.jpg"><img class="alignnone size-medium wp-image-45725" src="https://www.pubnub.com/wp-content/uploads/2019/08/aquack-300x281.jpg" alt="A'Quack, the pirate duck admiral" width="300" height="281" /></a>
<p>She is the Pirate Duck Admiral. She wants to chat with the other pirate ducks on rafts distributed around the world &#8211; in realtime. And she wants it now.</p>
<p>The head Pirate Duck software engineer knows they could build a chat server with Websockets or Socket.IO, but will it scale to the massive numbers of ducks based in all corners of the globe? How many engineers will they have to dedicate to building and maintaining the backend? Pirate Ducks do not invest in large IT teams so it seems better to use <a href="https://pubnub.com">PubNub</a>, with its <a href="https://www.pubnub.com/developers/tech/network-infrastructure/">globally distributed endpoints</a> and solid uptime.</p>
<h2>Requirements</h2>
<ul>
<li>Each session will be psuedo-anonymous, pirate ducks do not want to be identified.</li>
<li>Pirate ducks should, by default, only have 3 or 4 message buttons. Typing with palmate feet and bills is difficult.
<ul>
<li>Allow a separate text input area for those ducks that need it and are patient with their typing.</li>
</ul>
</li>
<li>Only the most recent message should display. Pirate ducks have good memories.</li>
</ul>
<h2>Prerequisites</h2>
<p>The only prerequisite knowledge for this workshop is a general familiarity with <strong>JavaScript, HTML and CSS</strong>. For tools, you will need a code editor, Git to clone the starter repository, and a reasonably modern web browser.</p>
<h2>Get the Base Code</h2>
<p>For this workshop, the HTML, CSS and non-PubNub specific JavaScript code are already in the repository. Clone the code from the <a href="https://github.com/mdfw/pubnubducks">GitHub repo</a> and checkout the <a href="https://github.com/mdfw/PubNubDucks/tree/workshop-basic-chat">workshop-basic-chat</a> branch.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">git clone git@github.com:mdfw/PubNubDucks.git
cd PubNubDucks/
git checkout workshop-basic-chat
</pre>
<p>If you&#8217;ve checked out the <code>workshop-basic-chat</code> branch, open <code>index.html</code> in your browser, you will see something resembling this:</p>
<a href="https://www.pubnub.com/wp-content/uploads/2019/08/basic-chat-no-code.png"><img class="alignnone size-medium wp-image-45724" src="https://www.pubnub.com/wp-content/uploads/2019/08/basic-chat-no-code-300x199.png" alt="Duck image but no chat options" width="300" height="199" /></a>
<p>&#8220;Your handle&#8221; should be different, but the general outline should be the same.</p>
<h2>A Quick Look at the HTML</h2>
<p>Opening the <code>index.html</code> file, you will find a few things:</p>
<ul>
<li>The duck image is an inline SVG. That will become important in a future workshop chapter.</li>
<li>The &#8216;chat&#8217; text buttons do not show by default. Once we wire up PubNub, they show up when a connection succeeds.</li>
<li>These <code>.js</code> files import:
<ul>
<li>The <a href="https://www.pubnub.com/docs/web-javascript/pubnub-javascript-sdk" target="_blank" rel="noopener noreferrer">PubNub JavaScript SDK</a></li>
<li><a href="https://jquery.com/" target="_blank" rel="noopener noreferrer">jQuery</a></li>
<li><code>randomduckdata.js</code> &#8211; a helper file that adds some randomness for sent messages, duck names and colors.</li>
<li><code>pubnub-keys.js</code> &#8211; holds the keys used in the application (see below)</li>
<li><code>index.js</code> &#8211; the main code.</li>
</ul>
</li>
</ul>
<h2>Signing up for PubNub and Setting API Keys</h2>
<p>To make our chat interactive, we will need <a href="https://www.pubnub.com/developers/tech/admin-dashboard/keys-object">PubNub API keys</a>. PubNub is <strong>free</strong> for up to 1 million messages a month and does not require a credit card at sign up.</p>
<p><iframe style="width: 100%; min-height: 450px;" src="https://pubsub-quickstart-app.pubnub.com/signup">Your browser does not support iframes.</iframe></p>
<p>Once you are signed up, get the subscribe and publish keys. Click the project created for you (probably called &#8220;Demo Project&#8221;) and then click the keyset (probably called &#8220;Demo Keyset&#8221;). Then you can copy the Publish and Subscribe keys.</p>
<a href="https://www.pubnub.com/wp-content/uploads/2019/08/demo-keyset.png"><img class="alignnone size-medium wp-image-45727" src="https://www.pubnub.com/wp-content/uploads/2019/08/demo-keyset-300x244.png" alt="" width="300" height="244" /></a>
<p>We won&#8217;t be using the Secret Key in this workshop. Use the Secret Key when adding authentication using the <a href="https://www.pubnub.com/developers/tech/security/access-manager/">PubNub Access Manager</a> on a secure server you control. Never use the Secret Key on a client.</p>
<p>Open <code>js/pubnub-keys.js</code> and make the following replacements:</p>
<ul>
<li>The <code>PUBNUB_PUBLISH_K</code> key &#8220;DEMO-PUBLISH-KEY&#8221; with your publish key</li>
<li>The <code>PUBNUB_SUBSCRIBE_K</code> key &#8220;DEMO-SUBSCRIBE-KEY&#8221; with your subscribe key.</li>
</ul>
<a href="https://www.pubnub.com/wp-content/uploads/2019/08/keys-inserted.png"><img class="alignnone size-medium wp-image-45728" src="https://www.pubnub.com/wp-content/uploads/2019/08/keys-inserted-300x38.png" alt="" width="300" height="38" /></a>
<p>Save and close. We will come back to the other keys in this file later.</p>
<h2>Create a PubNub Object</h2>
<p>Open <code>js/index.js</code>.</p>
<p>The code that updates the UI and reacts to clicks is included, but most of the PubNub specific code is not there. That&#8217;s what we&#8217;ll do below.</p>
<p>The first four lines of the <code>document.ready</code> function:</p>
<ul>
<li><code>setMessagesOnButtons()</code> &#8211; There is a large set of messages that are &#8220;authorized&#8221; by Pirate Duck IT. However, we only have two buttons to use (the third button always says &#8220;Woof!&#8221; &#8211; a mystery solved in a later workshop chapter). This function picks two messages and assigns them to the buttons.</li>
<li><code>randomName()</code> and <code>updateDuckMetaName()</code> &#8211; Since the pirate ducks want to be anonymous, we create semi-anonymous names for them on every load.</li>
<li><code>updateDuckStatus</code> updates the status area that we are loading.</li>
</ul>
<p>Let&#8217;s add our first PubNub functionality, the object that manages the connection to the PubNub service.</p>
<div style="margin: 20px 5px 20px 5%; border-left: 5px solid red; padding-left: 10px;">The code is also available in <code>js/workshop-code.js</code>.</div>
<p><em>Replace:</em></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">/**
 * Connect to PubNub
*/
</pre>
<p><em>with:</em></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">    /**
     * Sets up an object to manage the connection to the PubNub service. 
     * Get publish and subscribe keys by signing up for the PubNub service (http://pubnub.com)
     * ssl - defaults to true, but we'll be specific here.
     * uuid - This is the identifier used by presence and publish systems to identify this unit.
     *        For this demo, we will use our randomly generated duck name. However, PubNub best 
     *        practice is to use a UUID and separately manage user names through other means. 
     */
    pubnub = new PubNub({
        subscribeKey: PUBNUB_SUBSCRIBE_K,
        publishKey: PUBNUB_PUBLISH_K,
        ssl: true,
        uuid: generatedDuckName,
    })
</pre>
<p>I&#8217;ll restate this point: the way we use <code>UUID</code> here is not best practice. It works for the needs of this demo, but it should be unique for each client. Names should be managed separately. If you need ideas, see the <a href="https://www.pubnub.com/developers/chat-resource-center/docs/users/">chat resource center</a>.</p>
<p>The <code>PUBNUB_SUBSCRIBE_K</code> and <code>PUBNUB_PUBLISH_K</code> should be the same variable names as those we filled in at the &#8220;Signing up for PubNub and setting keys&#8221; step above.</p>
<p>If you reload the browser, nothing will have changed. We need to add a listener.</p>
<a href="https://www.pubnub.com/wp-content/uploads/2019/08/basic-chat-no-code.png"><img class="alignnone size-medium wp-image-45724" src="https://www.pubnub.com/wp-content/uploads/2019/08/basic-chat-no-code-300x199.png" alt="Duck image but no chat options" width="300" height="199" /></a>
<div style="margin: 20px 5px 20px 5%; border-left: 5px solid red; padding-left: 10px;">It is possible to publish a message to the PubNub Network for other subscribers to receive without setting up listeners or subscribing. Publishing and subscribing are <a href="https://www.pubnub.com/developers/tech/key-concepts/publish-subscribe/">separate activities</a> that are not necessarily intertwined. In fact, in a future chapter of our workshop, we will allow an IoT device to only subscribe to a channel and another device to only publish to a channel. However, for our chat demo, we want to have both. So, we do not show the publishing functions until we&#8217;ve connected to PubNub and subscribed to the right channel.</div>
<h2>Add a Listener</h2>
<p>When a duck in our pirate duck network sends a message to a channel we have subscribed to, PubNub will push that to us. We need to handle that message and any <a href="https://www.pubnub.com/docs/web-javascript/pubnub-network-lifecycle">network status events</a>. We will add a listener object to manage that for us.</p>
<p><em>Replace:</em></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">    /**
      * Add PubNub Listener
      */
</pre>
<p><em>with:</em></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">   /**
     * After setting up a connection, add a listener for any messages that PubNub sends.
     * There are 2 types of messages we will react to:
     *   * status: Network up/down, connection changes, etc. Listen for these to update UI.
     *   * message: Messages sent from PubNub, normally in response to a
     *        Publish event somewhere on the network.
     */
    pubnub.addListener({
        status: function(statusEvent) {
            processStatusEvent(statusEvent);
        },
        message: function(messageEvent) {
            processReceivedMessage(messageEvent);
        }
    })
</pre>
<p>This code allows us to listen for <code>status</code>-type messages and <code>message</code>-type messages. There is another message type, <code>presence</code> that we will handle in a later chapter.</p>
<p>Next we need to add the actual functions that will handle the status and message events.</p>
<div style="margin: 20px 5px 20px 5%; border-left: 5px solid red; padding-left: 10px;">If you see <code>Subscribe to channels</code> in the code after the <code>addListener</code> section, don&#8217;t worry, we will come back to subscribing in a minute.</div>
<h2>Handle Status Events</h2>
<p>Our listener calls <code>processStatusEvent()</code>, so we should add that.</p>
<p><em>Replace:</em></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">/**
 * Process status events
 */
</pre>
<p><em>with:</em></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js"> /**
 * Process status events.
 * This function does not handle the exhaustive list of status events. See documentation for others.
 *   This shows how an application may handle these events.
 *   If connection is offline, hide sending options, when it comes back, show the sending options (showChangeInterface())
 * @param {*} statusEvent 
 */
function processStatusEvent(statusEvent) {
    logReceivedMessage(statusEvent, "a status event");
    if (statusEvent.category === "PNDisconnectedCategory" || statusEvent.category === "PNTimeoutCategory" || statusEvent.category === "PNNetworkIssuesCategory" || statusEvent.category === "PNNetworkDownCategory") {
        hideChangeInterface();
        updateDuckStatus("<i>Internet connection is not available. The duck is sad.</i>");
    }
    if (statusEvent.category === "PNConnectedCategory" || statusEvent.category === "PNNetworkUpCategory") {
        showChangeInterface();
    }
}
</pre>
<p>As the documentation mentions, we do not handle all <a href="https://www.pubnub.com/docs/web-javascript/status-events">statusEvent types</a>, but many of the common ones. The core logic is:</p>
<ul>
<li>If we disconnect from PubNub, hide the buttons.</li>
<li>If we connect, show the buttons.</li>
</ul>
<h2>Handle Received Messages</h2>
<p>Our listener also calls processReceivedMessage(), but before we add that function, let&#8217;s talk about what we need to process. A received message from PubNub is wrapped into an envelope <a href="https://www.pubnub.com/learn/glossary/what-is-JSON/">JSON</a> object. That envelope will look like:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="json">{
  "channel": "ducks.talk",
  "timetoken": "15654132552683958",
  "publisher": "Dred Duck Jada",
  "message": {
    "text": "Messier 11 and strait on 'til morning.",
    "duckName": "Dred Duck Jada",
  },
  ...other fields...
}
</pre>
<p>Taking this line by line:</p>
<ul>
<li><code>"channel": "ducks.talk"</code>: This tells us that the message was received on the ducks.talk channel. Channels are developer created text strings that define where a message is published to and where a system can subscribe to. You can create as many <a href="https://support.pubnub.com/support/solutions/articles/14000043777-how-many-channels-can-i-use-]">channels as you need</a>.</li>
<li><code>"timetoken": "15654132552683958"</code>: <a href="https://support.pubnub.com/support/solutions/articles/14000043827-what-are-the-various-timetokens-used-in-pubnub-publish-subscribe-">Token</a> added to every message envelope that passes through the system.</li>
<li><code>"publisher": "Dred Duck Jada"</code>: Typically the UUID of the publisher of the message. Note: this may not be present.</li>
<li><code>"text": "Messier 11 and strait on 'til morning."</code>: The &#8220;message&#8221; object is the object that gets published by a publisher and wrapped by PubNub. The keys within the object are developer defined, not enforced by PubNub. In this case, the object includes the &#8220;text&#8221; field which matches to CHANNEL_KEY_TEXT from js/pubnub-keys.js.</li>
<li><code>"duckName": "Dred Duck Jada"</code>: The name of the duck that published this item. As you will see in a minute, we add that to the published message. <em>This is not best practice. How to attach names to content requires thought and is out of scope of this workshop.</em> Since our content is attached to psuedo-anonymous duck names that won&#8217;t change, we can attach the name to the message object. Maps to the <code>CHANNEL_KEY_DUCKNAME</code> in <code>js/pubnub-keys.js</code>.</li>
</ul>
<h3>Processing a Message</h3>
<p>Now that we know what a message might contain, we can write code to process it.</p>
<p><em>Replace:</em></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">/**
 * Process a received message.
 */
</pre>
<p><em>with:</em></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">/**
 * Process received messages. First, log the message, then send to proper UI handlers.
 * @param {*} envelope 
 */
function processReceivedMessage(envelope) {
    logReceivedMessage(envelope, "a message");
    updateDuckTalk(envelope.message[CHANNEL_KEY_TEXT], envelope.message[CHANNEL_KEY_DUCKNAME], envelope.timetoken);
}
</pre>
<p>This parses the envelope.message object for the <code>CHANNEL_KEY_TEXT</code> and <code>CHANNEL_KEY_DUCKNAME</code> parameters, along with the <code>timetoken</code>, and passes them all to updateDuckTalk. <code>updateDuckTalk</code> will update the interface.</p>
<h2>Subscribing</h2>
<p>Now that we have listeners with associated code to process received messages, we need to tell the PubNub service that we want to receive those messages. That&#8217;s called <a href="https://support.pubnub.com/support/solutions/articles/14000043859-subscribe-">subscribing</a>. A client can subscribe to multiple channels at one time. For now, we are just going to subscribe to the same channel that we will publishing messages to &#8211; the channel identified by the <code>CHANNEL_NAME_TALK</code> variable in the <code>js/pubnub-keys.js</code> file.</p>
<p><em>Replace:</em></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">    /**
     * Suscribe to channels
     */
</pre>
<p><em>with:</em></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">    /**
     * Subscribe to channels. Best practice is to bundle subscribe events when possible
     *   as it reduces network connections.
     */
    pubnub.subscribe({
        channels: [CHANNEL_NAME_TALK],
    });
</pre>
<p>This tells PubNub we want to receive any messages posted to the channel identified by <code>CHANNEL_NAME_TALK</code>. When that happens, the service sends it to the SDK which routes to our installed listener.</p>
<p>If you reload now, you should connect to the PubNub service and the send message buttons should show. If you click on the <code>Show PubNub message log</code> link at the bottom you can see the messages received from PubNub.</p>
<a href="https://www.pubnub.com/wp-content/uploads/2019/08/show-message-log.png"><img class="alignnone size-medium wp-image-45729" src="https://www.pubnub.com/wp-content/uploads/2019/08/show-message-log-300x66.png" alt="" width="300" height="66" /></a>
<p>At this point, if someone published a message using your publish and subscribe keys and on the channel defined by <code>CHANNEL_NAME_TALK</code>, it would replace &#8220;Hello from PubNub!&#8221;.</p>
<p>But, if you click on one of the buttons or tried to send a custom message, nothing will happen. We need to set up sending.</p>
<h2>Sending a Message Over the PubNub Network</h2>
<p>Receiving messages from others is interesting and Ducks want to participate. The buttons and custom field to send messages are there now because we&#8217;ve made a subscribe connection. They just do not do anything because we do not have a sending function.</p>
<p>In <code>index.js</code> there are two functions that send chat messages, <code>handleCustomTextMessageSend()</code> and <code>handleButtonClick()</code>. These gather the chat message and send it to a function called <code>sendMessageToPubNub()</code>. Let&#8217;s add that.</p>
<p><em>Replace:</em></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">/**
 * Send a message to PubNub
 */
</pre>
<p><em>with:</em></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">/**
 * Send a message to PubNub. Takes the channel, contentKey and content.
 * @param {*} channelName 
 * @param {*} contentKey 
 * @param {*} content 
 */
function sendMessageToPubNub (channelName, contentKey, content ) {
    let msgToSend = {
        channel: channelName,
        message: {
            [contentKey]: content,
            [CHANNEL_KEY_DUCKNAME]: generatedDuckName, 
        }
    };
    pubnub.publish(msgToSend, function (status, response) {
        if (status.error) {
            updateDuckStatus("There was an error sending your message.");
            setTimeout(function(){ updateDuckStatus(""); }, 5000);
        } else {
            logSentMessage(msgToSend, "a message to the '" + channelName + "' channel");
        }
    });
}
</pre>
<p>To send, we need a <code>channelName</code>, a <code>contentKey</code> and the <code>content</code> to send.</p>
<p>With those values, we build a message object with the channel and message content. We call in the <code>generatedDuckName</code> from earlier to send along with the message.</p>
<p>Next, we call <code>pubnub.publish</code> with the message object. If the <a href="https://www.pubnub.com/docs/web-javascript/api-reference-publish-and-subscribe#publish">publish</a> fails, we show a basic error message for a few seconds. If it succeeds, it adds to the message log. The message logs allows you to see what messages were sent and received. Nice for a demo, probably won&#8217;t be necessary for production.</p>
<h2>Demo</h2>
<a href="https://www.pubnub.com/wp-content/uploads/2019/08/workshop-complete.png"><img class="alignnone size-medium wp-image-45730" src="https://www.pubnub.com/wp-content/uploads/2019/08/workshop-complete-300x265.png" alt="" width="300" height="265" /></a>
<p>At this point, Pirate Duck IT should have an app that meets the requirements set out by the Admiral and scales to the millions of rafts around the world. With this much communication, we can all welcome our new Pirate Duck overlords.</p><p>The post <a  href="https://www.pubnub.com/blog/building-a-basic-chat-pirate-ducks/">Using PubNub to Build Realtime Chat for Pirate Ducks</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>We Won the Hacker Noon Noonie Award for Most Valuable Chatbot Platform!</title>
		<link>https://www.pubnub.com/blog/hacker-noon-noonie-most-valuable-chatbot-platform/</link>
				<pubDate>Tue, 20 Aug 2019 18:37:50 +0000</pubDate>
		<dc:creator><![CDATA[Joe Hanson]]></dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Chatbot]]></category>
		<category><![CDATA[Cognitive Services]]></category>
		<category><![CDATA[Machine Learning]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Chat]]></category>
		<description><![CDATA[<p>Chatbots are scaling customer service teams across the web. But how are they being built? And how close are they coming to actual human interaction?</p>
<p>The post <a  href="https://www.pubnub.com/blog/hacker-noon-noonie-most-valuable-chatbot-platform/">We Won the Hacker Noon Noonie Award for Most Valuable Chatbot Platform!</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>On the heels of being selected <a href="https://www.pubnub.com/company/press-releases/2019/pubnub-selected-as-winner-for-best-overall-bot-solution-in-the-2019-ai-breakthrough-awards/">Best Overall Bot Solution</a> in the 2019 AI Breakthrough Awards, we&#8217;re excited to announce we&#8217;ve won the <strong><a href="https://hackernoon.com/hacker-noon-awards-and-the-winners-of-the-2019-noonies-are-mg61306w">Hacker Noon Noonie for Most Valuable Chatbot Platform</a>!</strong> Dubbed &#8220;the tech industry&#8217;s greenest awards,&#8221; the Noonies recognized the best (and worst) &#8216;peoples and products of the Internets&#8217; for 2019 and beyond.</p>
<p>From simple rule-based auto responders, to sentient, intelligent chatbots at massive scale, PubNub provides a realtime platform for deploying flexible chatbots to suit your exact use case. Customer service and support, new user registration, eCommerce, and even <a href="https://www.pubnub.com/customers/numberai/">Main Street businesses</a> are utilizing chatbots to more effectively and efficiently engage and assist customers and prospects.</p>
<p>With PubNub Functions, and our Blocks Catalog which includes a number of best-in-class cognitive services (AWS, Microsoft Azure, and IBM Watson among them), you can <a href="https://www.pubnub.com/developers/chat-resource-center/docs/functions/chatbot-integration">quickly integrate and deploy chatbot capabilities into your chat application</a>.</p>
<h2>A Chatbot Example: NumberAI</h2>
<p>NumberAI is a realtime conversation platform for Main Street that brings AI-powered communication to the phone line, text-enabling businesses of all sizes in an easy and intuitive way. The product rescues missed callers–lost business–and uses Natural Language Processing (NLP) to automatically reply to common questions that a business receives, and completes common tasks (taking food orders, for example) that generate new revenue. When the AI cannot handle a customer, an employee is notified to ensure a rapid response.</p>
<p>NumberAI’s product, <a href="https://inbox.getnuma.com/" target="_blank" rel="noopener noreferrer">Numa</a>, allows businesses to communicate more quickly and conveniently with their customers. In order to deliver on the experience, several features (including message delivery!) must happen in realtime. NumberAI considered a variety of ways to deliver an enhanced realtime communication experience, from SMS to push notifications and beyond, but ultimately concluded that PubNub was the most effective and efficient. PubNub is used to power all realtime messaging and interactivity in the app between customers and the chatbot.</p>
<p>Read more about <a href="https://www.pubnub.com/customers/numberai/">NumberAI&#8217;s innovative chatbot implementation</a> here.</p>
<img class="aligncenter size-large wp-image-40109" src="https://www.pubnub.com/wp-content/uploads/2019/02/numa_inbox-1024x651.png" alt="" width="1024" height="651" />
<h2>Chatbot Resources</h2>
<ul>
<li><a href="https://www.pubnub.com/developers/chatbots-and-pubnub/">PubNub and Chatbots</a></li>
<li><strong>Developer Tutorial: </strong><a href="https://www.pubnub.com/developers/chat-resource-center/docs/functions/chatbot-integration">PubNub Chatbot Basics</a></li>
<li><strong>Developer Tutorial: </strong><a href="https://www.pubnub.com/blog/build-a-chatbot-with-pubnub-functions/">Create a Chatbot in 10 Minutes with PubNub Functions and Facebook Messenger</a></li>
<li><strong>Developer Tutorial: </strong><a href="https://www.pubnub.com/blog/build-an-80s-chatbot-with-an-npm-package/">Build an 80s Chatbot with an NPM Package</a></li>
<li><strong>eBook: </strong><a href="https://www.pubnub.com/learn/ebooks/building-apps-with-cognitive-services/">A World Transformed &#8211; Building Smarter, Next Generation Apps with Cognitive Services</a></li>
</ul>
<p>&nbsp;</p><p>The post <a  href="https://www.pubnub.com/blog/hacker-noon-noonie-most-valuable-chatbot-platform/">We Won the Hacker Noon Noonie Award for Most Valuable Chatbot Platform!</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Typing Indicators in Chat Powered by PubNub Signals</title>
		<link>https://www.pubnub.com/blog/chat-typing-indicators-javascript-pubnub-signals/</link>
				<pubDate>Wed, 14 Aug 2019 16:52:21 +0000</pubDate>
		<dc:creator><![CDATA[Adam Bavosa]]></dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Typing indicator]]></category>
		<category><![CDATA[Chat]]></category>
		<category><![CDATA[PubNub Signals]]></category>
		<description><![CDATA[<p>How to build typing indicators for a chat app using PubNub Signals, a feature allowing you to send a constant stream of small sized, non-critical messages.</p>
<p>The post <a  href="https://www.pubnub.com/blog/chat-typing-indicators-javascript-pubnub-signals/">Typing Indicators in Chat Powered by PubNub Signals</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Our customers have spoken, and we have responded with <strong>PubNub Signals</strong>. The new Signals feature is a part of <a href="https://www.pubnub.com/features/pub-sub-messaging/">PubNub&#8217;s Publish-Subscribe API</a> for sending realtime data between devices. Signals are very similar to Publishes with some intuitive trade-offs to <strong>save you money</strong>.</p>
<p>Let&#8217;s say you need to send a constant stream of small sized, non-critical messages. Something like a frequent <strong>temperature sensor update</strong> from an IoT device, or a <strong>GPS coordinate</strong> stream in a ride-share app, or a <strong>typing indicator</strong> signal in a chat app. This is the perfect opportunity to utilize PubNub Signals instead of PubNub Publishes.</p>
<h2>What is PubNub&#8217;s PubSub Messaging?</h2>
<p>Pub/Sub allows developers to send messages, with a payload of up to <strong>32KB</strong>, to any active subscribers. Publishers can be any device that knows TCP. Published messages are replicated to all PubNub global data centers. Published messages can be stored in <a href="https://www.pubnub.com/docs/getting-started-guides/pubnub-storage-and-playback">PubNub History</a>, or invoke a <a href="https://www.pubnub.com/features/functions/">PubNub Function</a>, or Push notification.</p>
<h2>What is a PubNub Signal?</h2>
<p>A Signal is the same as a PubNub Publish except it is small, with a payload of up to <strong>30 bytes</strong>. Signals are replicated to all global data centers like Publishes. However they are not stored in History for a later fetch; only the most recent Signal message can be fetched later.</p>
<p>They can&#8217;t invoke external Push notifications, although they may be eligible to use PubNub Functions (speak to Support or your Account rep to set this up). Signal pricing is, as a result, far lower, making signals ideal for high-volume streams of data.</p>
<h2>Why Use Signal Instead of Publish?</h2>
<p>PubNub Signals include the same reliability and latency as PubNub Publishes, but they are intended for data stream messaging, where the stream of data is more important than the exact content of each individual message. Examples would include chat app typing indicators, live GPS location update stream, and live sensor update streams from IoT devices.</p>
<h2>Chat App Typing Indicator Demo</h2>
<p>Open the <a href="https://ajb413.github.io/pubnub-signals-demo-typing-indicator/signals-typing-indicator-demo.html" target="_blank" rel="noopener noreferrer">HTML page of the simple chat demo</a>. The chat includes Typing Indicators powered by PubNub Signals. This will make invoking typing indicators inexpensive even when your chat app is being used at scale.</p>
<p>Using PubNub Publishes for Typing indicators may not be the best choice at scale: the extra overhead for things like global replication and history storage are not necessary for  simply displaying a typing indicator.</p>
<p>Be sure to get your own <strong>free PubNub API keys</strong> to put in this file. <a href="https://dashboard.pubnub.com/signup" target="_blank" rel="noopener noreferrer">Get your API keys now in the admin dashboard</a>.</p>
<p>The HTML File <strong>will not run</strong> unless you replace the <strong>YOUR_PUBNUB_PUBLISH_KEY / YOUR_PUBNUB_SUBSCRIBE_KEY</strong> with your free API key.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="html">&lt;!-- Chat in 10 lines of JavaScript code using PubNub JavaScript V4 SDK --&gt;
&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;

&lt;head&gt;
    &lt;meta charset="utf-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"&gt;
    &lt;meta name="description" content="Example of a JavaScript chat app using PubNub JavaScript V4 SDK."&gt;
    &lt;meta name="keywords" content="JavaScript,PubNub,Chat,chat-room,chatting,SDK,PubSub-sdk,tutorial"&gt;
    &lt;title&gt;JavaScript Chat | PubNub&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;h1&gt;Chat Example with Typing Indicators&lt;/h1&gt;
    &lt;h2&gt;Typing Indicators using PubNub Signals&lt;/h2&gt;
    &lt;p&gt;
        &lt;a href="https://www.pubnub.com/?devrel_pbpn=javascript-chat"&gt;
            &lt;img src="https://d2c805weuec6z7.cloudfront.net/Powered_By_PubNub.png" alt="Powered By PubNub" width="150"&gt;
        &lt;/a&gt;
        &lt;p&gt;
            &lt;p&gt;Enter chat and press enter.&lt;/p&gt;
            &lt;input id="input" placeholder="Your Message Here" /&gt;
            &lt;p id="typing-indicator" style="visibility:hidden;"&gt;Is Typing:&lt;span id="typing-user-id"&gt;&lt;/span&gt;&lt;/p&gt;
            &lt;p&gt;Chat Output:&lt;/p&gt;
            &lt;div id="box"&gt;&lt;/div&gt;
        &lt;/p&gt;
    &lt;/p&gt;
&lt;/body&gt;
&lt;script src="https://cdn.pubnub.com/sdk/javascript/pubnub.4.24.5.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
(function() {
    const pubnub = new PubNub({ publishKey: 'YOUR_PUBNUB_PUBLISH_KEY', subscribeKey: 'YOUR_PUBNUB_SUBSCRIBE_KEY' }); // Your PubNub keys here. Get them from https://dashboard.pubnub.com.

    let box = document.getElementById("box"),
        input = document.getElementById("input"),
        typingIndicator = document.getElementById("typing-indicator"),
        typingUserId = document.getElementById("typing-user-id");
        chatMessageChannel = 'chat-signals-example',
        timeoutCache = 0,
        isTyping = false,
        isTypingChannel = 'is-typing';

    let hideTypingIndicator = () =&gt; {
        isTyping = false;
        typingIndicator.style = "visibility:hidden;";
    };

    pubnub.subscribe({ channels: [chatMessageChannel, isTypingChannel] }); // Subscribe to a channel.

    pubnub.addListener({
        message: function(m) {
            clearTimeout(timeoutCache);
            hideTypingIndicator(); // When a message has been sent, hide the typing indicator
            box.innerHTML = ('' + m.message).replace(/[&lt;&gt;]/g, '') + '&lt;br&gt;' + box.innerHTML; // Add message to page.
        },
        signal: function(s) {
            clearTimeout(timeoutCache);
            typingIndicator.style = "";
            typingUserId.innerText = s.publisher; // the UUID of the user who is typing
            timeoutCache = setTimeout(hideTypingIndicator, 10000) // 10 seconds

            if (s.message === '0') {
                hideTypingIndicator();
            }
        }
    });

    input.addEventListener('keyup', function(e) {
        // Publish new PubNub message when return key is pressed.
        if ((e.keyCode || e.charCode) === 13 &amp;&amp; input.value.length &gt; 0) {
            pubnub.publish({
                channel: chatMessageChannel,
                message: input.value
            });

            input.value = '';
        }

        const inputHasText = input.value.length &gt; 0;

        // Publish new PubNub signal: Typing Indicator ON (1) or OFF (2)
        if ((inputHasText &amp;&amp; !isTyping) || (!inputHasText &amp;&amp; isTyping)) {
            isTyping = !isTyping;
            pubnub.signal({
                channel: isTypingChannel,
                message: inputHasText ? '1' : '0'
            });
        }
    });
})();
&lt;/script&gt;

&lt;/html&gt;</pre>
<p>&nbsp;</p>
<p>Here is what the demo looks like in 2 browser windows, one is <strong>incognito mode</strong> so there is a <strong>second user ID</strong> shown in in the typing indicator UI.</p>
<a href="https://ajb413.github.io/pubnub-signals-demo-typing-indicator/signals-typing-indicator-demo.html" target="_blank" rel="noopener noreferrer"><img class="size-full wp-image-45661 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/08/pubnub-chat-js-example-recording.gif" alt="Typing Indicator Demo with PubNub Signals" width="600" height="284" /></a>
<p><strong><a href="https://ajb413.github.io/pubnub-signals-demo-typing-indicator/signals-typing-indicator-demo.html" target="_blank" rel="noopener noreferrer">Live demo of Typing Indicators with PubNub Signals.</a></strong></p><p>The post <a  href="https://www.pubnub.com/blog/chat-typing-indicators-javascript-pubnub-signals/">Typing Indicators in Chat Powered by PubNub Signals</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Java WebSocket Programming with Android and Spring Boot</title>
		<link>https://www.pubnub.com/blog/java-websocket-programming-with-android-and-spring-boot/</link>
				<pubDate>Tue, 13 Aug 2019 21:01:31 +0000</pubDate>
		<dc:creator><![CDATA[Oscar Castro]]></dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[WebSockets]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Socket.IO]]></category>
		<description><![CDATA[<p>An overview and examples of Java WebSocket programming in Android and Spring Boot.</p>
<p>The post <a  href="https://www.pubnub.com/blog/java-websocket-programming-with-android-and-spring-boot/">Java WebSocket Programming with Android and Spring Boot</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>The <a href="https://www.pubnub.com/blog/websockets-vs-rest-api-understanding-the-difference/" target="_blank" rel="noopener noreferrer">WebSocket protocol</a> provides an always-on connection between a client and a server for bi-directional communication. This is great for applications that require a realtime connection, such as <a href="https://www.pubnub.com/blog/tag/multiplayer-gaming/" target="_blank" rel="noopener noreferrer">multiplayer games</a>, <a href="https://www.pubnub.com/blog/tag/internet-of-things/" target="_blank" rel="noopener noreferrer">IoT devices</a>, and <a href="https://www.pubnub.com/blog/tag/chat/" target="_blank" rel="noopener noreferrer">chat apps</a>. In this tutorial, we are going to set up a simple Android client that will connect to a WebSocket server using <a href="https://spring.io/projects/spring-boot" target="_blank" rel="noopener noreferrer">Spring Boot</a>.</p>
<a href="https://www.pubnub.com/blog/websockets-vs-rest-api-understanding-the-difference/"><img class="wp-image-8043 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2014/09/WebSockets-Diagram.png" alt="What is websocket?" width="345" height="311" /></a>
<h2>Android WebSocket Client</h2>
<p>For the Android client, we are going to make a simple demo app that contains four image buttons of cute animals. To get started, initialize a new project on <a href="https://developer.android.com/studio" target="_blank" rel="noopener noreferrer">Android Studio</a>, with a Basic Activity, called <strong>JavaWebSocketClient</strong>. We are going to use a lightweight WebSocket client library for the app, which can be found in this <a href="https://github.com/gusavila92/java-android-websocket-client" target="_blank" rel="noopener noreferrer">repo</a>. In order to use this library, we have to add it to the <strong>build.gradle</strong> file in the app directory. Add the following to the dependencies and sync the project:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">dependencies { 
    // Add this
    implementation 'tech.gusavila92:java-android-websocket-client:1.2.2'    
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    ...
}</pre>
<p>Make sure to include the internet access permission in the manifest file:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">&lt;uses-permission android:name="android.permission.INTERNET" /&gt;</pre>
<h3>Connect the Client to the Server</h3>
<p>Go to <strong>MainActivity.java</strong>, import the following packages and set up <strong>onCreate()</strong>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import java.net.URI;
import java.net.URISyntaxException;
import tech.gusavila92.websocketclient.WebSocketClient;

public class MainActivity extends AppCompatActivity {
  private WebSocketClient webSocketClient;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.animal_sounds);
    createWebSocketClient();
  }
}
</pre>
<p>Next, create a new method <strong>createWebSocketClient()</strong>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">  private void createWebSocketClient() {
    URI uri;
    try {
      // Connect to local host
      uri = new URI("ws://10.0.2.2:8080/websocket");
    }
    catch (URISyntaxException e) {
      e.printStackTrace();
      return;
    }

    webSocketClient = new WebSocketClient(uri) {
      @Override
      public void onOpen() {
        Log.i("WebSocket", "Session is starting");
        webSocketClient.send("Hello World!");
      }

      @Override
      public void onTextReceived(String s) {
        Log.i("WebSocket", "Message received");
        final String message = s;
        runOnUiThread(new Runnable() {
          @Override
          public void run() {
            try{
              TextView textView = findViewById(R.id.animalSound);
              textView.setText(message);
            } catch (Exception e){
                e.printStackTrace();
            }
          }
        });
      }

      @Override
      public void onBinaryReceived(byte[] data) {
      }

      @Override
      public void onPingReceived(byte[] data) {
      }

      @Override
      public void onPongReceived(byte[] data) {
      }

      @Override
      public void onException(Exception e) {
        System.out.println(e.getMessage());
      }

      @Override
      public void onCloseReceived() {
        Log.i("WebSocket", "Closed ");
        System.out.println("onCloseReceived");
      }
    };

    webSocketClient.setConnectTimeout(10000);
    webSocketClient.setReadTimeout(60000);
    webSocketClient.enableAutomaticReconnection(5000);
    webSocketClient.connect();
  }</pre>
<p>This may look like a lot, but really, we are doing four key things in this method:</p>
<ol>
<li>Starting a new connection to the localhost &#8220;ws://10.0.2.2:8080/websocket&#8221;.</li>
<li>Sending a message to the server once a connection is opened.</li>
<li>Displaying the messages sent from the server on the app.</li>
<li>Setting timeouts and automatic reconnection.</li>
</ol>
<p>Now that we connected the client to the server, let&#8217;s set up the method to send messages to the server.</p>
<h3>Send Messages to the Server</h3>
<p>In <strong>MainActivity.java</strong>, add the following to <strong>sendMessage()</strong>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">public void sendMessage(View view) {
   Log.i("WebSocket", "Button was clicked");

   // Send button id string to WebSocket Server
   switch(view.getId()){
     case(R.id.dogButton):
       webSocketClient.send("1");
       break;

     case(R.id.catButton):
       webSocketClient.send("2");
       break;

     case(R.id.pigButton):
       webSocketClient.send("3");
       break;

     case(R.id.foxButton):
       webSocketClient.send("4");
       break;
   }
 }</pre>
<p>When a button is pressed, the <em>button id </em>is sent to the server. This method is called from the file <strong>animal_sounds.xml</strong>, which you can get from my <a href="https://github.com/ocastroa/java-websocket-demo/blob/master/JavaWebSocketClient/app/src/main/res/layout/animal_sounds.xml" target="_blank" rel="noopener noreferrer">Java WebSocket Programming Repo</a>. Make sure to modify the file <a href="https://github.com/ocastroa/java-websocket-demo/blob/master/JavaWebSocketClient/app/src/main/res/values/strings.xml" target="_blank" rel="noopener noreferrer"><strong>strings.xml</strong></a> under the <strong>values</strong> directory so you won&#8217;t get any errors in the XML file.</p>
<p>The last thing to do on the client-side is to add the images for the animals in the <a href="https://github.com/ocastroa/java-websocket-demo/tree/master/JavaWebSocketClient/app/src/main/res/drawable" target="_blank" rel="noopener noreferrer"><strong>drawable</strong></a> directory. <em>The images are made by <a href="https://www.flaticon.com/authors/freepik" target="_blank" rel="noopener noreferrer">Freepik</a> from <a href="https://www.flaticon.com/" target="_blank" rel="noopener noreferrer">www.flaticon.com</a>.</em></p>
<p>Run the Android app in your emulator:</p>
<a href="https://www.pubnub.com/wp-content/uploads/2019/08/clicking_buttons_client.gif"><img class="size-full wp-image-45620 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/08/clicking_buttons_client.gif" alt="Clicking Client Buttons" width="235" height="415" /></a>
<p>Nothing happens right now because the server is not set up. Let&#8217;s do that right now!</p>
<h2>Spring Boot WebSocket Server</h2>
<p>For our server, we will use Spring Boot which makes it easy to create production-grade <a href="https://spring.io/projects/spring-framework" target="_blank" rel="noopener noreferrer">Spring</a> applications with minimum configurations. To quickly bootstrap our project, we will use <a href="https://start.spring.io/" target="_blank" rel="noopener noreferrer">Spring Initializr</a>. We will generate a <a href="https://gradle.org/" target="_blank" rel="noopener noreferrer">Gradle</a> project, but you can also generate a <a href="https://maven.apache.org/" target="_blank" rel="noopener noreferrer">Maven</a> project if you prefer. Configure the Initializr like the screenshot below and make sure to add WebSocket as a dependency:</p>
<a href="https://www.pubnub.com/wp-content/uploads/2019/08/spring_initializr-1.png"><img class="size-full wp-image-45626 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/08/spring_initializr-1.png" alt="Initialize Spring Boot" width="645" height="310" /></a>
<p>Generate the project to download a zip file. Once you unzip the file, go to the <strong>src</strong> directory and keep on clicking the subdirectories until you get to the <strong>JavaWebSocketServerApplication</strong><strong>.java</strong> file.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">package com.example.javawebsocketserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class JavaWebSocketServerApplication {
  public static void main(String[] args) {
    SpringApplication.run(JavawebsocketserverApplication.class, args);
  }
}</pre>
<p>Add two files to the directory: <strong>WebSocketHandler.java </strong>and <strong>WebSocketConfiguration.java</strong>.</p>
<h3>Handle the WebSocket Messages</h3>
<p>We have to handle the incoming messages that arrive in the server. To do so, in <strong>WebSocketHandler.java </strong>inherit the class <a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/socket/handler/AbstractWebSocketHandler.html" target="_blank" rel="noopener noreferrer"><strong>AbstractWebSocketHandler </strong></a>to implement the method <strong>handleTextMessage()</strong>. Add the following code to the file:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">package com.server.javawebsocketserver;

import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
import java.io.IOException;

public class WebSocketHandler extends AbstractWebSocketHandler {
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
        String msg = String.valueOf(message.getPayload());
        // Send back unique message depending on the id received from the client
        switch(msg){
            case("1"):
                System.out.println("Dog button was pressed");
                session.sendMessage(new TextMessage("Woooof"));
                break;

            case("2"):
                System.out.println("Cat button was pressed");
                session.sendMessage(new TextMessage("Meooow"));
                break;

            case("3"):
                System.out.println("Pig button was pressed");
                session.sendMessage(new TextMessage("Bork Bork"));
                break;

            case("4"):
                System.out.println("Fox button was pressed");
                session.sendMessage(new TextMessage("Fraka-kaka-kaka"));
                break;

            default:
                System.out.println("Connected to Client");
        }
    }
}</pre>
<p>Inside the method, we simply get the string value of the message payload and do a <strong>switch</strong> expression to check the value of the message with the value of each case. A unique message with the animal sound is sent to the client.</p>
<h3>Configure the WebSocket Request Handling</h3>
<p>In <strong>WebSocketConfiguration.java</strong>, implement the interface <a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/socket/config/annotation/WebSocketConfigurer.html" target="_blank" rel="noopener noreferrer"><strong>WebSocketConfigurer</strong></a> and add the following code to the file:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">package com.server.javawebsocketserver;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
// Add this annotation to an @Configuration class to configure processing WebSocket requests
public class WebSocketConfiguration implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new WebSocketHandler(), "/websocket");
    }
}</pre>
<p>We set up the method <strong>registerWebSocketHandlers</strong> to configure the <a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/socket/config/annotation/WebSocketHandlerRegistry.html#addHandler-org.springframework.web.socket.WebSocketHandler-java.lang.String...-" target="_blank" rel="noopener noreferrer">WebSocketHandler</a> to the path &#8220;<strong>/websocket</strong>&#8220;.</p>
<p>That is all for the server-side. Now that we have everything set up, let&#8217;s start the WebSocket server and run the app!</p>
<h2>Send Data between Server and Client</h2>
<p>In the terminal, go to the root directory of your Spring Boot project and run the following command to start the server:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">gradle bootRun</pre>
<p>Next, run the Android client in Android Studio and once the app loads, click any of the four buttons.</p>
<p><a href="https://www.pubnub.com/wp-content/uploads/2019/08/client_server_screenshot.png"><img class="size-full wp-image-45618 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/08/client_server_screenshot.png" alt="Client and Server Screenshot" width="645" height="310" /></a><br />
Play around with the Android app and see how messages are sent from client-to-server with WebSockets!</p>
<h2>Update the Android Client to Pub/Sub</h2>
<p>Sending data client-to-server or server-to-client is not difficult and can be done pretty fast. But what if you want to send data client-to-client? You can&#8217;t directly connect clients without implementing some routing and broker logic on the server.</p>
<p>There are several tools we can use to make this task less time-consuming. One such tool is <a href="https://www.pubnub.com/learn/glossary/what-is-socketio/" target="_blank" rel="noopener noreferrer">Socket.IO</a>, which sets up a real-time, bidirectional connection between clients. This is a great open-source tool to use, but we still need to set up a server and connect the client to the server. Is there an easier way to securely and reliably send data between clients without manually setting up a server? With PubNub, we can.</p>
<p><a href="https://www.pubnub.com/wp-content/uploads/2016/08/pubsub-1.gif"><img class="size-full wp-image-22707 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2016/08/pubsub-1.gif" alt="Pubsub" width="345" height="311" /></a>PubNub provides the realtime infrastructure to power any device that speaks TCP. We can stream data from client-to-client, client-to-server or server-to-client using <a href="https://www.pubnub.com/products/global-data-stream-network/" target="_blank" rel="noopener noreferrer">PubNub&#8217;s Global Data Stream Network</a> in under 100 ms! With PubNub, an always-on connection is made between the devices connected to the channel, similar to WebSockets. The best part is that you don&#8217;t have to worry about setting up a server and maintaining the server because PubNub is <a href="https://www.pubnub.com/blog/everything-you-wanted-to-know-about-serverless-but-were-afraid-to-ask/" target="_blank" rel="noopener noreferrer">serverless</a> and is infinitely scalable.</p>
<p>To see how PubNub simplifies the process of sending data from client-to-client, we will modify the Android app we built earlier. But first, sign up for a free PubNub account to get your<strong> free Pub/Sub API keys</strong>. Sign up and log in using the form below:<br />
<iframe style="width: 100%; min-height: 400px;" title="SignUp Form" src="https://pubsub-quickstart-app.pubnub.com/signup"><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start">﻿</span>Your browser does not support iframes.</iframe></p>
<h3>Modify the Android Client</h3>
<p>To differentiate the updated app from the old app, create a new Android project called <strong>PubNubJavaClient</strong>. In order to use <a href="https://www.pubnub.com/docs/android-java/pubnub-java-sdk" target="_blank" rel="noopener noreferrer">PubNub&#8217;s Android SDK</a>, add the following to the <strong>build.gradle</strong> file in the app directory and sync the project:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">dependencies {
    implementation group: 'com.pubnub', name: 'pubnub-gson', version: '4.25.0' // Add this
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    ...
}</pre>
<p>Include the following permissions to the manifest file:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">&lt;uses-permission android:name="android.permission.INTERNET" /&gt;
&lt;uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /&gt;
</pre>
<p>Everything else, except <strong>MainActivity.java</strong>, is the same. From the previous app, add the following files to the updated app:  <strong><a href="https://github.com/ocastroa/java-websocket-demo/blob/master/JavaWebSocketClient/app/src/main/res/layout/animal_sounds.xml" target="_blank" rel="noopener noreferrer">animal_sounds.xml</a></strong>, <a href="https://github.com/ocastroa/java-websocket-demo/blob/master/JavaWebSocketClient/app/src/main/res/values/strings.xml" target="_blank" rel="noopener noreferrer"><strong>strings.xml</strong></a> and the images from the <a href="https://github.com/ocastroa/java-websocket-demo/tree/master/JavaWebSocketClient/app/src/main/res/drawable" target="_blank" rel="noopener noreferrer"><strong>drawable</strong></a> directory. Once you finish this, go to <strong>MainActivity.java </strong>to add the new code. Import the following packages and set up <strong>onCreate()</strong>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import com.pubnub.api.PNConfiguration;
import com.pubnub.api.PubNub;
import com.pubnub.api.callbacks.PNCallback;
import com.pubnub.api.callbacks.SubscribeCallback;
import com.pubnub.api.models.consumer.PNPublishResult;
import com.pubnub.api.models.consumer.PNStatus;
import com.pubnub.api.models.consumer.pubsub.PNMessageResult;
import com.pubnub.api.models.consumer.pubsub.PNPresenceEventResult;
import java.util.Arrays;

public class MainActivity extends AppCompatActivity {
  PubNub pubnub;
  TextView textView;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.animal_sounds);

    initPubNub(); // Initialize PubNub
  }
</pre>
<p>Make a call to <strong>initPubNub()</strong> to initialize PubNub:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">public void initPubNub(){
  PNConfiguration pnConfiguration = new PNConfiguration();
  pnConfiguration.setPublishKey("ENTER_YOUR_PUB_KEY"); // REPLACE with your pub key
  pnConfiguration.setSubscribeKey("ENTER_YOUR_SUB_KEY"); // REPLACE with your sub key
  pnConfiguration.setSecure(true);
  pubnub = new PubNub(pnConfiguration);

  // Listen to messages that arrive on the channel
  pubnub.addListener(new SubscribeCallback() {
    @Override
    public void status(PubNub pub, PNStatus status) {
    }

    @Override
    public void message(PubNub pub, final PNMessageResult message) {
      // Replace double quotes with a blank space
      final String msg = message.getMessage().toString().replace("\"", ""); 
      textView = findViewById(R.id.animalSound);

      runOnUiThread(new Runnable() {
        @Override
        public void run() {
          try{
            // Display the message on the app
            textView.setText(msg);
          } catch (Exception e){
              System.out.println("Error");
              e.printStackTrace();
          }
        }
      });
    }

    @Override
    public void presence(PubNub pub, PNPresenceEventResult presence) {
    }
  });

  // Subscribe to the global channel
  pubnub.subscribe()
    .channels(Arrays.asList("global_channel"))
    .execute();
}</pre>
<p>We do three key things in this method:</p>
<ol>
<li>Initialize the PubNub client API. Make sure to replace &#8220;ENTER_YOUR_PUB_KEY&#8221; and &#8220;ENTER_YOUR_SUB_KEY&#8221; with your Pub/Sub keys.</li>
<li>Set up a listener to get notified of messages that arrive on the channel. As we did earlier, display the message on the app for the client to see.</li>
<li>Subscribe to the global channel where messages will be published.</li>
</ol>
<p>When the user presses a button, the method <strong>sendMessage()</strong> is called:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">// This method is called when a button is pressed
public void sendMessage(View view) {
  // Get button ID
  switch(view.getId()){
    case(R.id.dogButton):
      publishMessage("Woooof");
      break;

    case(R.id.catButton):
      publishMessage("Meooow");
      break;

    case(R.id.pigButton):
      publishMessage("Bork Bork");
      break;

    case(R.id.foxButton):
      publishMessage("Fraka-kaka-kaka");
      break;
  }
}</pre>
<p>This method is similar to what we did earlier, except now we publish the actual message, the animal sound, to the global channel and not the server. We use <strong>publishMessage()</strong> as a helper function to publish the message.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="java">public void publishMessage(String animal_sound){
  // Publish message to the global chanel
  pubnub.publish()
    .message(animal_sound)
    .channel("global_channel")
    .async(new PNCallback&lt;PNPublishResult&gt;() {
      @Override
      public void onResponse(PNPublishResult result, PNStatus status) {
        // status.isError() to see if error happened and print status code if error
        if(status.isError()) {
          System.out.println("pub status code: " + status.getStatusCode());
        }
      }
    });
}</pre>
<p>That is all we need to get the app up-and-running!</p>
<h2>Send Data Between Clients</h2>
<p>Run the Android app in two emulators to see messages appear in realtime.</p>
<a href="https://www.pubnub.com/wp-content/uploads/2019/08/client_to_client.gif"><img class=" wp-image-45622 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/08/client_to_client.gif" alt="Client-to-client demo" width="452" height="385" /></a>
<p>Now that you know how to send data with WebSockets in Java, make sure to check out the other tutorials in <a href="https://www.pubnub.com/blog/socket-programming-in-python-client-server-p2p/" target="_blank" rel="noopener noreferrer">Socket Programming in Python</a> and <a href="https://www.pubnub.com/blog/nodejs-websocket-programming-examples/" target="_blank" rel="noopener noreferrer">WebSocket Programming in Node.js</a>.</p>
<p><strong>Have suggestions or questions about the content of this post? Reach out at <a href="mailto:devrel@pubnub.com" target="_blank" rel="noopener noreferrer" data-rawhref="mailto:devrel@pubnub.com">devrel@pubnub.com</a>.</strong></p><p>The post <a  href="https://www.pubnub.com/blog/java-websocket-programming-with-android-and-spring-boot/">Java WebSocket Programming with Android and Spring Boot</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>How to Manipulate, Augment, and Filter Realtime Data Streams using PubNub Functions</title>
		<link>https://www.pubnub.com/blog/how-to-manipulate-augment-filter-realtime-data-streams-pubnub-functions/</link>
				<pubDate>Tue, 13 Aug 2019 20:10:49 +0000</pubDate>
		<dc:creator><![CDATA[Chandler Mayo]]></dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[PubNub Functions]]></category>
		<description><![CDATA[<p>A guide to shaping data and messages in any PubNub app.</p>
<p>The post <a  href="https://www.pubnub.com/blog/how-to-manipulate-augment-filter-realtime-data-streams-pubnub-functions/">How to Manipulate, Augment, and Filter Realtime Data Streams using PubNub Functions</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><a href="https://www.pubnub.com/products/functions/" target="_blank" rel="noopener noreferrer">PubNub Functions</a> makes it easy to route, filter, transform, augment, or aggregate realtime messages that are transmitted over the <a href="https://www.pubnub.com/products/global-data-stream-network/" target="_blank" rel="noopener noreferrer">PubNub Data Stream Network</a>. With PubNub Functions, you can take precise control over your messages without routing messages to your own server or making your application more complex.</p>
<p>In this tutorial, we&#8217;ll be using PubNub Functions to prevent multiple push notifications being triggered from a <a href="https://www.pubnub.com/blog/build-a-smart-doorbell-with-arduino-react-native-push-notifications/" target="_blank" rel="noopener noreferrer">Smart Doorbell app built in React Native</a> and a <a href="https://www.pubnub.com/blog/build-iot-smart-button-arduino-react-native-push-notifications" target="_blank" rel="noopener noreferrer">PubNub-powered IoT smart button</a>. <strong>You can use this tutorial as a guide to shape data and messages in any PubNub app.</strong></p>
<a href="https://www.pubnub.com/products/mobile-push-notifications/" target="_blank" rel="noopener noreferrer"><img class="wp-image-22675 alignright" src="https://www.pubnub.com/wp-content/uploads/2016/08/mobile-push.gif" alt="Mobile Push Notifications" width="117" height="133" /></a>
<p>In our <a href="https://www.pubnub.com/blog/build-a-smart-doorbell-with-arduino-react-native-push-notifications/" target="_blank" rel="noopener noreferrer">Smart Doorbell app</a>, a user can press a smart button to trigger a <a href="https://www.pubnub.com/products/mobile-push-notifications/">remote push notification</a>, but nothing stops a user from pressing the button repeatedly. Using PubNub Functions we will implement logic within the PubNub Network to remove the push notification keys from the message for messages sent less than 30 seconds from the last push notification. This kind of functionality is commonly known as debouncing. Debounces are often used in programming to ensure that tasks do not fire so often. Since we&#8217;re using PubNub Functions to manipulate the data, we won&#8217;t need to make any changes to our <a href="https://www.pubnub.com/blog/build-iot-smart-button-arduino-react-native-push-notifications" target="_blank" rel="noopener noreferrer">PubNub powered IoT smart button</a> or the <a href="https://www.pubnub.com/blog/build-a-smart-doorbell-with-arduino-react-native-push-notifications/" target="_blank" rel="noopener noreferrer">Smart Doorbell app</a>.</p>
<h2>What are PubNub Functions?</h2>
<p><a href="https://www.pubnub.com/products/functions/" target="_blank" rel="noopener noreferrer">PubNub Functions</a> is a serverless environment for executing functions on the edge, transforming, enriching, and ﬁltering messages as they route through the PubNub network. PubNub Functions are JavaScript event handlers that can be executed on in-transit PubNub messages or <a href="https://www.pubnub.com/blog/build-a-rest-api-in-5-minutes-with-pubnub/" target="_blank" rel="noopener noreferrer">in the request/response style of a RESTful API over HTTPS</a>.</p>
<p>If you&#8217;ve used <a href="https://nodejs.org/en/" target="_blank" rel="noopener noreferrer">Node.js</a> and <a href="https://expressjs.com/" target="_blank" rel="noopener noreferrer">Express</a>, the &#8220;On Request&#8221; event handler development will be second nature.</p>
<p>Here are some of the things you could use PubNub Functions to do:<a href="https://www.pubnub.com/products/functions/" target="_blank" rel="noopener noreferrer"><img class="lazy wp-image-37972 alignright lazy-loaded" src="https://www.pubnub.com/wp-content/uploads/2018/10/functions-header-logo.svg" alt="Functions Logo" width="140" height="229" data-lazy-type="image" data-lazy-src="https://www.pubnub.com/wp-content/uploads/2018/10/functions-header-logo.svg" /></a></p>
<ul>
<li><strong>Secure API Calls</strong> – <a href="https://www.pubnub.com/solutions/realtime-updates/" target="_blank" rel="noopener noreferrer">Trigger an alert</a> when a secure message meets certain criteria – email, text message, tweet, mobile push, etc.</li>
<li><strong>Decrease Time to Market: </strong>Focus on building your product and not managing the infrastructure to support it.</li>
<li><b><a href="https://www.pubnub.com/blog/what-is-latency-and-why-does-it-matter/" target="_blank" rel="noopener noreferrer">Reduce Latency</a>: </b>Your users are global. Your product should be global. PubNub operates points of presence across the globe.</li>
<li><strong>Translation</strong> – Send a message in English and receive it in Spanish with a 3rd part translation API.</li>
<li><strong>Network Logic</strong> – Reliably <a href="https://www.pubnub.com/blog/build-your-own-hq-trivia-app-for-android/" target="_blank" rel="noopener noreferrer">count up <strong>millions of votes</strong></a> during realtime audience interaction.</li>
<li><strong>Serve Data</strong> – Build a globally replicated, low latency, production REST API <a href="https://www.pubnub.com/blog/build-a-rest-api-in-5-minutes-with-pubnub/" target="_blank" rel="noopener noreferrer">in 5 minutes.</a></li>
<li><strong>Reduced Cost:</strong> Pay for usage and not idle servers.</li>
</ul>
<h2>Getting Started</h2>
<p>You&#8217;ll need a free <a href="https://dashboard.pubnub.com/signup/" target="_blank" rel="noopener noreferrer">PubNub account</a> and a React Native app.</p>
<p>Your app does not have to be the <a href="https://www.pubnub.com/blog/build-a-smart-doorbell-with-arduino-react-native-push-notifications/" target="_blank" rel="noopener noreferrer">Smart Doorbell app</a> we&#8217;re using in this tutorial. You can use your own PubNub application or you can build the <a href="https://www.pubnub.com/blog/build-a-smart-doorbell-with-arduino-react-native-push-notifications/" target="_blank" rel="noopener noreferrer">Smart Doorbell app</a>.</p>
<p>Here&#8217;s what you need for the Smart Doorbell app:</p>
<img class="wp-image-44085 alignright" src="https://www.pubnub.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-23-at-6.03.23-PM.png" alt="Smart Doorbell Events" width="145" height="289" />
<h3>IoT Smart Button</h3>
<img class=" wp-image-43851 alignright" src="https://www.pubnub.com/wp-content/uploads/2019/07/IMG-3929.jpg" alt="IoT Smart Button" width="146" height="163" />
<p>You’ll need to <a href="https://www.pubnub.com/blog/build-iot-smart-button-arduino-react-native-push-notifications/" target="_blank" rel="noopener noreferrer">build your own</a> PubNub powered IoT smart button to use with the Smart Doorbell app. I’ve put together <a href="https://www.pubnub.com/blog/build-iot-smart-button-arduino-react-native-push-notifications/" target="_blank" rel="noopener noreferrer">a guide to build your own IoT smart button</a>.</p>
<p>You only need two hardware components:</p>
<ul>
<li>A push button.</li>
<li>A <a href="https://store.arduino.cc/usa/arduino-mkr1000-with-headers-mounted" target="_blank" rel="noopener noreferrer">MKR1000 development board</a>.</li>
</ul>
<p>Build your button by <a href="https://www.pubnub.com/blog/build-iot-smart-button-arduino-react-native-push-notifications/" target="_blank" rel="noopener noreferrer">following the guide</a>.</p>
<h3>Smart Button React Native App</h3>
<p>Next, you’ll need to <a href="https://www.pubnub.com/blog/build-a-smart-doorbell-with-arduino-react-native-push-notifications/" target="_blank" rel="noopener noreferrer">complete the tutorial</a> for <a href="https://www.pubnub.com/blog/build-a-smart-doorbell-with-arduino-react-native-push-notifications/" target="_blank" rel="noopener noreferrer">building a Smart Doorbell app</a> in React Native that tracks the history of the smart button press events. The app works on both iOS and Android.</p>
<p>Build the Smart Doorbell app by <a href="https://www.pubnub.com/blog/build-a-smart-doorbell-with-arduino-react-native-push-notifications/" target="_blank" rel="noopener noreferrer">following the tutorial</a>.</p>
<h3>Push Notifications</h3>
<p>Last, you&#8217;ll need to enable push notifications in the app by completing the tutorial for <a href="https://www.pubnub.com/blog/instant-ios-android-push-notifications-with-react-native-smart-button-part-three/" target="_blank" rel="noopener noreferrer">Instant Push Notifications for iOS and Android from a React Native App</a>.</p>
<h2>Creating a Function to Alter Messages</h2>
<p>Go to your <a href="https://admin.pubnub.com/" target="_blank" rel="noopener noreferrer">PubNub Admin Dashboard</a> and select your app. Then click on the keyset that was created for that app.</p>
<p>Next, click “Functions” in the sidebar and then create a new module named “PushFilter.” Select the module you just created.</p>
<p>Create a Function with the name “Push-Filter.”</p>
<p>Set the event type to “Before Publish or Fire”, and set the channel name to “smart_buttons”.</p>
<p>Delete any code in the editor and replace it with a function to send an altered message if messages are sent less than 30 seconds apart:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">const store = require('kvstore');

export default (request) =&gt; {
    // Limit push notifications.
    const duration = 30;  

    // Get the time and compare to the last time a notification was sent. 
    const currentTime = Math.round(Date.now() / 1000);

    return store.get('anti_spam').then((value) =&gt; {
        // Get the last time a message was sent with push notifications.
        const lastMessageTime = value.last_message_time;
        
        // Edit message if duplicate.
        if ((currentTime - lastMessageTime) &lt; duration) {
            // Modify the message to remove push keys.
            console.log("Duplicate push notification removed.");
            request.message = { "event": { "button": "pressed" }};
        } else {
            // Allow full message and record time.
            store.set('anti_spam', {
                last_message_time: currentTime
            });
        }

        return request.ok();
    })
    .catch((e) =&gt; {
        console.error(e);
        return request.abort(); 
    });
}</pre>
<p>Click &#8220;Save&#8221; and then &#8220;Restart module.&#8221;</p>
<h2>Test Message Debounce with IoT Smart Button</h2>
<p>Press your <a href="https://www.pubnub.com/blog/build-iot-smart-button-arduino-react-native-push-notifications" target="_blank" rel="noopener noreferrer">PubNub powered IoT smart button</a> and you&#8217;ll see in the console that an unaltered message is allowed only once every 30 seconds. No more push notification spam!</p>
<a href="https://github.com/chandler767/Smart-Doorbell/blob/master/functions/push_notification_spam.js" target="_blank" rel="noopener noreferrer"><img class="aligncenter wp-image-44162" src="https://www.pubnub.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-25-at-11.56.46-AM.png" alt="Push Notification Spam Filter" width="592" height="181" /></a>
<h2>Test Message Debounce with Debug Console</h2>
<p>You can also test by sending messages to the &#8220;smart_buttons&#8221; channel from the PubNub Debug Console. Go to your <a href="https://admin.pubnub.com/" target="_blank" rel="noopener noreferrer">PubNub Admin Dashboard</a>, select the keys you created for this project, and create a client in the Debug Console. Set the “Default Channel” to “smart_buttons” and leave the other fields blank. Click “ADD CLIENT”.</p>
<p>Send a test message to the channel and you&#8217;ll see that an unaltered message is allowed only once every 30 seconds.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="json">{
  "event": {
    "button": "pressed"
  },
  "pn_apns": {
    "aps": {
      "alert": "Someone is at the door."
    }
  },
  "pn_gcm": {
    "notification": {
      "body": "Someone is at the door."
    }
  }
}</pre>
<h2>What&#8217;s next?</h2>
<ul>
<li><a href="https://www.pubnub.com/blog/heres-how-to-build-your-own-smart-home-in-an-afternoon/" target="_blank" rel="noopener noreferrer">Build a Smart Home</a> powered by PubNub Functions.</li>
<li>Link your <a href="https://www.pubnub.com/blog/build-iot-smart-button-arduino-react-native-push-notifications" target="_blank" rel="noopener noreferrer">PubNub-powered IoT smart button</a> with an <a href="https://ifttt.com/" target="_blank" rel="noopener noreferrer">IFTTT recipe</a>.</li>
<li>Use <a href="https://www.pubnub.com/docs/web-javascript/mobile-gateway" target="_blank" rel="noopener noreferrer">push notifications</a> to alert users of a delivery driver&#8217;s location.</li>
</ul>
<p><strong>Have suggestions or questions about the content of this post? Reach out at <a href="mailto:devrel@pubnub.com" target="_blank" rel="noopener noreferrer" data-rawhref="mailto:devrel@pubnub.com">devrel@pubnub.com</a>.</strong></p><p>The post <a  href="https://www.pubnub.com/blog/how-to-manipulate-augment-filter-realtime-data-streams-pubnub-functions/">How to Manipulate, Augment, and Filter Realtime Data Streams using PubNub Functions</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Rustacean Terminal Chat App in Rust</title>
		<link>https://www.pubnub.com/blog/build-realtime-rust-chat-app-cursive-tui/</link>
				<pubDate>Fri, 09 Aug 2019 17:31:52 +0000</pubDate>
		<dc:creator><![CDATA[Samba Diallo]]></dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[Chat]]></category>
		<category><![CDATA[Rust]]></category>
		<description><![CDATA[<p>Build a basic chat app with the Rust Programming Language.</p>
<p>The post <a  href="https://www.pubnub.com/blog/build-realtime-rust-chat-app-cursive-tui/">Rustacean Terminal Chat App in Rust</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><span style="font-weight: 400;">The coding world is rich with new languages and frameworks, and one growing in popularity is <a href="https://www.rust-lang.org/">Rust</a>. You’ve probably heard about it, somewhere between </span><span style="font-weight: 400;">Stack Overflow</span><span style="font-weight: 400;"> and programming-focused Twitter accounts.</span></p>
<p><span style="font-weight: 400;">I won&#8217;t put you through a sales pitch on Rust itself, after all,</span> <a href="https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages"><span style="font-weight: 400;">this Stack Overflow poll</span></a><span style="font-weight: 400;"> speaks for itself. However, I do want to show how to integrate Pub/Sub messaging into your Rust project by creating a Rust chat app.</span></p>
<a href="https://www.pubnub.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-07-at-10.55.26-AM.png"><img class="wp-image-45575 size-full" src="https://www.pubnub.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-07-at-10.55.26-AM-e1565201261509.png" alt="stack overflow most loved" width="1440" height="770" /></a>
<h2>What is Publish-Subscribe?</h2>
<p><span style="font-weight: 400;"><a href="https://www.pubnub.com/features/pub-sub-messaging/">Publish-Subscribe</a>, or Pub/Sub is a way for services and clients to communicate with each other in realtime. One common use case of Pub/Sub in Rust is to connect multiple devices or servers and reflect any changes or updates across them simultaneously. One can use these payloads to update systems, send <a href="https://www.pubnub.com/solutions/chat/">chat app messages</a>, <a href="https://www.pubnub.com/blog/javascript-mapping-javascript-tracking/">live geolocation tracking</a> and more. Another use is networking in <a href="https://webassembly.org/">Web Assembly</a>, a pre-compiled binary format that will replace JavaScript in the browser. This will enable developers to make website front ends with another language besides JavaScript. Instead of having to interpret JavaScript at runtime, it compiles other programming languages to binary before the page loads.</span></p>
<p><span style="font-weight: 400;">There are a few Pub/Sub API’s out there; I’m going to use <a href="https://www.pubnub.com/">PubNub</a>. The reason why I use it with Rust is that it has a simple REST API that I can leverage. While also providing pre-written, open-source API integrations, it provides a solid infrastructure for my use case.</span></p>
<h2><span style="font-weight: 400;">Sign Up for PubNub</span></h2>
<p><span style="font-weight: 400;">It’s time to take the first step in creating our project, let&#8217;s get our </span><b>free</b><span style="font-weight: 400;"> PubNub API keys. There are two ways to obtain them, either through </span><a href="https://dashboard.pubnub.com/signup"><span style="font-weight: 400;">signing up in the PubNub Admin Dashboard</span></a><span style="font-weight: 400;"> or using the form below.</span></p>
<p><iframe style="width: 100%; min-height: 450px;" src="https://pubsub-quickstart-app.pubnub.com/signup" data-mce-fragment="1">Your browser does not support iframes.</iframe></p>
<h2><span style="font-weight: 400;">Setting Up a Rust Environment</span></h2>
<p>When starting to develop with Rust, I found the compiler to be extremely helpful. Aside from running your code, it tells you where and what you’re doing wrong, and it will tell you why if you ask it! Let’s get it installed by typing <code class="EnlighterJSRAW" data-enlighter-language="null">curl https://sh.rustup.rs -sSf | sh</code> into your terminal.</p>
<p><span style="font-weight: 400;">Once that finishes, navigate to where you want your new Rust project to live and type <code class="EnlighterJSRAW" data-enlighter-language="null">cargo new rustychat</code></span></p>
<p><span style="font-weight: 400;">Now navigate into your project and use <code class="EnlighterJSRAW" data-enlighter-language="null">cargo run</code> </span><span style="font-weight: 400;">to run your project!</span></p>
<a href="https://www.pubnub.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-30-at-11.39.16-AM-1.png"><img class="wp-image-44408 size-full" src="https://www.pubnub.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-30-at-11.39.16-AM-1.png" alt="hello world" width="1130" height="113" /></a>
<p><span style="font-weight: 400;">Now that you have a project set up, let&#8217;s go over some of the files inside of your project.</span></p>
<p><span style="font-weight: 400;">The file “Cargo.toml” is similar to a package.json from Node.js. This is where you’ll put all your crates (libraries), and when you build your project, they’ll be installed. If you’ve installed iOS frameworks with Cocoapods, listing these dependencies will feel similar. </span></p>
<p><span style="font-weight: 400;">Inside here, under dependencies, you should include the six crates that our app uses. The libraries will allow us to: </span></p>
<ul>
<li style="font-weight: 400;"><span style="font-weight: 400;">Send GET requests </span></li>
<li style="font-weight: 400;"><span style="font-weight: 400;">Define custom error types more easily</span></li>
<li style="font-weight: 400;"><span style="font-weight: 400;">Construct and destruct JSON objects</span></li>
<li style="font-weight: 400;"><span style="font-weight: 400;">Derive custom structs from JSON</span></li>
<li style="font-weight: 400;"><span style="font-weight: 400;">Create a custom Terminal UI </span></li>
<li style="font-weight: 400;"><span style="font-weight: 400;">URL encode our requests</span></li>
</ul>
<pre class="EnlighterJSRAW" data-enlighter-language="null">[dependencies]
reqwest = "0.9.18"
custom_error = "1.6.0"
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
cursive = { version = "0.12.0", default-features = false, features = ["pancurses-backend"] }
percent-encoding = "1.0.1"</pre>
<p><span style="font-weight: 400;">Your Cargo.toml should now have all of the crates we plan on using. When we build our project, Rust will automatically install these dependencies. </span></p>
<p><span style="font-weight: 400;">The next file is src -&gt; main.rs, your main Rust code file. Here is where your main function is, in addition to “imports” of crates and the defining of structs. </span></p>
<p><span style="font-weight: 400;">Above your main function, insert these lines to gain access to the crates you just listed as dependencies. Include some crates that come standard in Rust.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">extern crate reqwest;
use percent_encoding::{percent_encode, PATH_SEGMENT_ENCODE_SET};
use serde::{Deserialize, Serialize};
use std::sync::mpsc::{channel, Sender};
use std::thread;
use cursive::align::HAlign;
use cursive::traits::*;
use cursive::Cursive;
use cursive::view::ScrollStrategy;
use cursive::views::{BoxView, Dialog, DummyView, EditView, LinearLayout, ScrollView, TextView};
use custom_error::custom_error;</pre>
<p><span style="font-weight: 400;">If you run your code again, it should build all the crates, and then output “Hello World.”</span></p>
<h2><span style="font-weight: 400;">Create a Custom Error</span></h2>
<p><span style="font-weight: 400;">When taking risky actions in code, you should write error handlers to gracefully marshall code execution gone awry. This is why I used </span><a href="https://docs.rs/custom_error/1.6.0/custom_error/macro.custom_error.html"><span style="font-weight: 400;">custom_error</span></a><span style="font-weight: 400;">, a crate that reduces the boilerplate needed in normal Rust for creating errors. We define the type, and for each type of error we expect, we can return a description. </span></p>
<p><span style="font-weight: 400;">In our code, we’ll be turning an object into a JSON string (and vice-versa), making a GET request to a URL, and accessing what comes back as a response. All three of these are risky and might fail, but we can recover. Once we detect an error, create a description to output in the terminal.</span></p>
<p><span style="font-weight: 400;">Look below for an example of the errors that I cover and how I define them. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">custom_error! {ChatError
    JSONError{source: serde_json::error::Error} = @{
        source.to_string()
    },
    ReqwestError{source: reqwest::Error } = @{
        source.to_string().split(": ").collect::&lt;Vec&lt;&amp;str&gt;&gt;()[1]
    },
    Unknown = "unknown error"
}</pre>
<h2><span style="font-weight: 400;">Define Structs for Rust JSON Response</span></h2>
<p><span style="font-weight: 400;">In this section, we will define a few structs that represent a JSON response that we get from PubNub. We’ll have four structs that each represent one layer of the response object we receive. </span></p>
<p><span style="font-weight: 400;">Response holds a Time and a vector of MessageResp. </span><span style="font-weight: 400;">Time holds a time token string, MessageResp holds a Message, which has a UUID string field and a text string field. Each of these fields needs to be deserializable. This allows us to throw the JSON response into a Response struct, and it’ll take care of organizing the data. Message also needs to be serializable to turn it into JSON data. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">#[derive(Deserialize)]
struct Response {
    t: Time,
    m: Vec&lt;MessageResp&gt;,
}

#[derive(Deserialize)]
struct MessageResp {
    d: Message,
}

#[derive(Deserialize)]
struct Time {
    t: String,
}

//Message is a sub object of MessageResp
#[derive(Serialize, Deserialize)]
struct Message {
    uuid: String,
    text: String,
}</pre>
<h2><span style="font-weight: 400;">Asynchronous Rust: How to Multithread</span></h2>
<p><span style="font-weight: 400;">Our main function in this project will create two threads: a thread that searches for new messages arriving and a thread for our UI. Let’s start with making our program use multithreading. Making our program run on multiple threads allows for us to block one thread waiting for messages while the user can still type new messages in the chat input.</span></p>
<p><span style="font-weight: 400;">The app runs on one thread, going line by line, by default. We can create a second thread that runs the subscribe loop at the same time. Before we create this second thread, how would we access its data on the main thread? </span></p>
<p><span style="font-weight: 400;">That’s where the </span><a href="https://doc.rust-lang.org/std/sync/mpsc/fn.channel.html"><span style="font-weight: 400;">channel</span></a><span style="font-weight: 400;"> comes in. It creates a sender and a receiver, also known as a producer and consumer. The sender can be cloned but the receiver cannot, allowing the receiver to access messages in the order they were sent. </span></p>
<p><span style="font-weight: 400;">Create two separate channels, one is to send a channel from the UI to the subscribe thread, and the other is to send messages from the subscribe thread to the UI.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">fn main() {

    //We create two channels, one to pass the channel name to the subscribe function 
    //Another to send new messages from the subscribe function to the UI 
    let (channel_sender, channel_receiver) = channel();
    let (mut msg_sender, msg_receiver) = channel();
    
    //... 
    //REST OF THE MAIN FUNCTION 
}
</pre>
<p><span style="font-weight: 400;">Now create a thread using </span><a href="https://doc.rust-lang.org/std/thread/fn.spawn.html"><span style="font-weight: 400;">spawn</span></a><span style="font-weight: 400;">, which is the simplest way to create new threads in Rust. We put the keyword “move“ before the callback to take ownership of the channel receiver and message sender. Inside the new thread, create an empty string that we’ll use for our initial time token. To subscribe, we need a channel from our UI. Our UI will send a channel once the user submits one, but until then, we should halt our thread. </span></p>
<p><span style="font-weight: 400;">The great thing about using channels is that we have the option of waiting for information to be sent. Let’s use the “`recv()“` function on our receiver, which waits for a single value to be passed through the channel. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//... 
//INSIDE MAIN
//Create a seperate thread, this allows us to have a subscribe loop that wont stop the UI from updating
let _handle1 = thread::spawn(move || {
  let mut time_token = "".to_string();
    //We wait for the UI to send us the channel name
    let test_channel = channel_receiver.recv();
    //...
    //REST OF THREAD
}
//...
//REST OF MAIN
</pre>
<p><span style="font-weight: 400;">When we receive a variable from another thread, we don’t know if it is an error or not. If the value is “Ok,” unwrap it into a string. Let’s create our subscribe loop! Use the “loop“ keyword to create an infinite loop. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//...
//INSIDE THREAD
if test_channel.is_ok() {

    let channel_name: String = test_channel.unwrap();
    loop {
        //...
        //REST OF LOOP
    }
}
</pre>
<p><span style="font-weight: 400;">The next step will be to call our subscribe function. It’ll return a Result enum of String, and ChatError. Results contain values wrapped in either an “Ok” or an “Err.” If the action went well, then an “Ok” will return, but “Err” will return if there was an error. You can check if the result is an error or a success, and additionally see what the value is by unwrapping it. The subscribe function will borrow the time token, a mutable version of the message sender, and the channel name.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//...
//Loop
let result: Result&lt;String, ChatError&gt; = subscribe(&amp;time_token, &amp;mut msg_sender, &amp;channel_name);</pre>
<p><span style="font-weight: 400;">We haven’t created this function yet, but I’ll walk you through it soon. All that we need to know right now is that the function might return an error. Let’s handle both cases. </span></p>
<p><span style="font-weight: 400;">If our subscribe Result went smoothly, “`result.is_ok()“` should return true. If so, unwrap it and assign your time token to its value. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">if result.is_ok() {
    //We update the time_token var to get all messages that happened after that specific time.
    time_token = result.ok().unwrap();
}
</pre>
<p><span style="font-weight: 400;">If it did not go well, don’t start worrying about alerting the user yet; it might be a ‘timed out’ error. This is expected every so often if there were no new messages. </span></p>
<p><span style="font-weight: 400;">Because PubNub’s REST API uses </span><a href="https://www.pubnub.com/blog/http-long-polling/"><span style="font-weight: 400;">HTTP Long Polling</span></a><span style="font-weight: 400;">, time outs mean that nothing new happened. If it was not a time out, then we should print the error and then break out of the loop. This cancels our program. That’s the end of our loop, if we receive a time token or a timeout error from our subscribe function then we start the loop over. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">else if result.is_err() {
    let err = result.unwrap_err();
    //If the request times out, thats okay, we just restart it with that same time token, looking for new messages.
    if err.to_string() != "timed out" {
        println!(
            "Error: {:?} \nPlease restart application to try again.",
            err.to_string()
        );
        break;
    }
}
//...
//END LOOP
//END IF
//END THREAD
</pre>
<p><span style="font-weight: 400;">It’s time to pause on the main function now that we finished our subscribe loop. It’s time to delve deeper into subscribing by actually creating the function. </span></p>
<h2><span style="font-weight: 400;">PubNub REST API</span></h2>
<p><span style="font-weight: 400;">Since we already obtained our keys, let’s learn how we’ll use PubNub in Rust. </span></p>
<p><span style="font-weight: 400;">PubNub has a REST API, which allows us to access Pub/Sub and more with just HTTP GET requests. Check out the </span><a href="https://www.pubnub.com/http-rest-push-api/"><span style="font-weight: 400;">REST API with HTTP GET</span></a><span style="font-weight: 400;"> docs for more information.</span></p>
<p><span style="font-weight: 400;">The PubNub REST API allows developers to publish messages and to subscribe to channels using HTTP requests. Having low-level control over requests lets you decide how often to make the subscribe calls and whether calls will be asynchronous or not. For this chat app, we’ll be making subscribe calls as soon as our previous one ends so users can still interact with other parts of our app. </span></p>
<p><span style="font-weight: 400;">Check out the diagram below to understand the flow of information in our app. </span></p>
<a href="https://www.pubnub.com/wp-content/uploads/2019/07/rustydiagram.png"><img class="size-full wp-image-44445" src="https://www.pubnub.com/wp-content/uploads/2019/07/rustydiagram.png" alt="rust pubnub diagram" width="1814" height="1352" /></a>
<p><span style="font-weight: 400;">We’ll be using the Publish and Subscribe URLs in our app, each in its function. I’ll first give instructions on subscribing, then we can use some of the similar concepts to publish.</span></p>
<h2><span style="font-weight: 400;">Subscribing to a Channel in Rust with a REST API</span></h2>
<p><span style="font-weight: 400;">This section will be a guide for creating a request to PubNub for Pub/Sub Subscribe. Through this, we’ll have a better understanding of how PubNub works with Rust. We’ll learn how to message data from this thread to the UI. </span></p>
<h3><span style="font-weight: 400;">Function Definition</span></h3>
<p><span style="font-weight: 400;">As we saw earlier, our function borrows a time, a sender to a channel, and a channel name. It returns a Result that either contains a String or a ChatError, which we defined at the beginning of our project. This allows us to define what might go wrong in our code, and what to do in each situation</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">fn subscribe(time: &amp;str, msg_sender: &amp;mut Sender&lt;String&gt;, channel: &amp;str ) -&gt; Result&lt;String, ChatError&gt; {
    //...
    //Subscribe Function
}</pre>
<h3><span style="font-weight: 400;">Create the URL String</span></h3>
<p><span style="font-weight: 400;">The first step in these functions will be to create the URL string. To do this, we use the macro function format and the crate percent-encoding. Using “format” makes it easier to create URLs with variables. The percent-encoding package lets us convert our objects into URL encoded strings. </span></p>
<p><span style="font-weight: 400;">In each request, there is a spot to put your subscribe key and channel name. We include a time parameter at the end, even though we won’t always have one. We don’t always pass one to the subscribe function. We always receive one in a successful response from PubNub. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//...
//In subscribe
//Format the URL
let url = format!(
    "https://{host}/v2/subscribe/{subkey}/{channel}/0/{time}",
    host = "ps.pndsn.com",
    subkey = "INSERT_SUB_KEY_HERE",
    channel = percent_encode(channel.as_bytes(), PATH_SEGMENT_ENCODE_SET),
    time = percent_encode(time.as_bytes(), PATH_SEGMENT_ENCODE_SET),
);
</pre>
<h3><span style="font-weight: 400;">Call the reqwest::get function</span></h3>
<p><span style="font-weight: 400;">Once we have the URL we want to request messages from, we call it using “Reqwest.” Reqwest is an abstraction over Hyper: a lower level Rust crate for making network requests. This function may return the information we want, but it also may give an error. This is where our functions’ Result return type plays a role. If something goes wrong, it’ll return an error.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">let mut resp = reqwest::get(&amp;url)?;</pre>
<p><span style="font-weight: 400;">When using reqwest::get, we leave a question mark at the end. This means that if this call fails, the subscribe function will return an &#8220;Err&#8221; value. Instead of having to tell our functions to return an &#8220;Err&#8221; with custom error information on the inside, they will do it automatically. </span></p>
<h3><span style="font-weight: 400;">Successful Response – JSON to Object</span></h3>
<p><span style="font-weight: 400;">If the status of the response is successful, we can dive into what we received. We defined a few structs at the beginning of the file that will help us access the information inside! One of the crates we packed makes this deserialization process painless. We use serde_json to turn our response’s text into a nice object, that’s easy to access the information. This process also might fail, but we already have that error handled with ChatError. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">if resp.status().is_success() {
    let deserialized: Response = serde_json::from_str( &amp; resp.text()?).unwrap();
    //...
    //Rest of If 
}
</pre>
<p><span style="font-weight: 400;">We sometimes won’t receive one message in the response, so let’s iterate through the Vector inside of it. For each of the messages, we’ll use our Sender to pass each message’s information. I create a string from the two values we get from each, a UUID and text. Be sure to unwrap the statement afterward. After iterating through the messages we can return the new time we received in an &#8220;Ok&#8221;.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//...
//In if statement
for m in deserialized.m {
    //Send the new message to the UI above.
    msg_sender
        .send(format!("{} : {}", m.d.uuid, m.d.text))
        .unwrap();
}
return Ok(deserialized.t.t);
//End of if</pre>
<p>If the response did not succeed, <span style="font-weight: 400;">put an “Ok” Result at the end of the subscribe function.  Give it the original time that was passed in, which is converted to a string. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">Ok(time.to_string())
//End of subscribe</pre>
<h3><span style="font-weight: 400;">Errors </span></h3>
<p><span style="font-weight: 400;">Did you notice that we didn’t include any Err statements? All our errors are handled by ChatError. We do include some filled “Ok” statements, which allow us to pass some information back to the calling function and say “Hey, things went fine!”</span></p>
<h2><span style="font-weight: 400;">Publishing Messages in Rust</span></h2>
<p><span style="font-weight: 400;">After creating our subscribe function, let’s create another function to publish to PubNub. This function will follow most of the same format as the last one, but there are a few small changes. </span></p>
<h3><span style="font-weight: 400;">Function Definition</span></h3>
<p><span style="font-weight: 400;">This function will accept 3 strings as parameters. They are the text we want to send, the UUID of the sender, and the channel name. Just like the previous function, we return a Result, but this time it’s an empty “Ok”, or a ChatError Err.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">fn publish(text: String, uuid: String, channel: String) -&gt; Result&lt;(), ChatError&gt; {
  //...
    //PUBLISH FUNCTION
}</pre>
<h3><span style="font-weight: 400;">Object to JSON</span></h3>
<p><span style="font-weight: 400;">At the beginning of this function, let’s create a Message with a couple of the parameters provided. We’re going to do the opposite of the subscribe function, but this time we’ll turn our object into a JSON string. This might return an error, so leave a question mark at the end and our ChatError will take care of it.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//...
//In publish
let message = Message { uuid, text };
let m_json = serde_json::to_string(&amp;message)?;</pre>
<h3><span style="font-weight: 400;">Create URL String</span></h3>
<p><span style="font-weight: 400;">This will be quite similar to the subscribe function, just adding and swapping some parameters. Replace ‘subscribe’ with ‘publish’, include your publish key, and replace time with a message. Both the channel and the message need to be URL encoded as well. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">let url = format!(
    "https://{host}/publish/{pubkey}/{subkey}/0/{channel}/0/{message}",
    host = "ps.pndsn.com",
    pubkey = "INSERT_PUB_KEY_HERE",
    subkey = "INSERT_SUB_KEY_HERE",
    channel = percent_encode(channel.as_bytes(), PATH_SEGMENT_ENCODE_SET),
    message = percent_encode(m_json.as_bytes(), PATH_SEGMENT_ENCODE_SET),
);
</pre>
<h3><span style="font-weight: 400;">Create GET Request</span></h3>
<p><span style="font-weight: 400;">Make a GET request and put a question mark after the call. Put an “Ok” Result on the next line. Once these are complete, we’ve finished our publish function!</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">let _resp = reqwest::get(&amp;url)?;
Ok(())
//End of publish</pre>
<h2><span style="font-weight: 400;">Create a Terminal UI using Cursive</span></h2>
<h3><span style="font-weight: 400;">What is a TUI?</span></h3>
<p><span style="font-weight: 400;">We’ve learned how to use PubNub’s REST API and we also created a separate thread to long poll PubNub for new messages. So far, we look for messages on a channel and we send those new messages somewhere. We haven’t defined where we get the channel from and where the new messages go. Both of these have much to do with the user interface. </span></p>
<p><span style="font-weight: 400;">While it is possible to create a command-line based chat, using a Terminal User Interface makes the experience much more clean and smooth. I used Cursive, a simple and feature-rich TUI that lets us separate the input from the output. </span></p>
<h3><span style="font-weight: 400;">Channel and Username Input</span></h3>
<p><span style="font-weight: 400;">To initiate Cursive, you need to create a mutable instance of its default function.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//Below end of _handle1 thread
let mut siv = Cursive::default();</pre>
<p><span style="font-weight: 400;">Cursive uses a format that is reminiscent of other methods of UI creation, namely using Views. Views can hold other views and have different uses. Views at the very base are contained by layers. These are the windows that can be added or popped.</span></p>
<p><span style="font-weight: 400;">Create a layer, and pass it a Dialog. A Dialog is a type of window that can hold another view. It should be around a LinearLayout view, which we can set to a vertical orientation. LinearLayouts are great for organizing child views into stacks or rows. You can add children to it with the “`child“` function, and it can be chained any number of times. You can also use “`with“` to dynamically add in children. We’ll use that later, but for now, let’s design our connection layer inside the LinearLayout. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">siv.add_layer(
    Dialog::around(
        LinearLayout::vertical()
        //...
        //LinearLayout's children
    )

    //...
    //Title and buttons of Dialog
);</pre>
<p><span style="font-weight: 400;">We are going to use a few different views to create this layer. We use TextViews for short lines of text, like a label. EditViews let users enter information, which we can later access with a specific ID. DummyViews are useful to space out our other views. You can design these how you want in your space, but I center the TextViews and set the EditViews width to 20. In addition to setting the styles, make sure you set an ID to each EditView AFTER “`new()“`, but before “`fixed_wifth(20)“`. If the ID is not in that spot, then we will not be able to reference that value later on. The Dummy Views are useful to space out items. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//...
//LinearLayout's children
.child(DummyView.fixed_height(1))
.child(TextView::new("Enter Username").h_align(HAlign::Center))
.child(EditView::new().with_id("username").fixed_width(20))
.child(DummyView.fixed_height(1))
.child(TextView::new("Enter Channel").h_align(HAlign::Center))
.child(EditView::new().with_id("channel").fixed_width(20))
</pre>
<p><span style="font-weight: 400;">After the LinearLayout is complete, finish up creating the Dialog. Add a title to the Dialog, create an “Okay” button with a callback, and a quit button. Finally, align it in the center. We’ll go into the “Okay” button’s callback next. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//...
//Attacched to Dialog
.title("PubNub Chat")
.button("Okay", CALLBACK )
.button("Quit", | s | s.quit())
.h_align(HAlign::Center),
</pre>
<h3><span style="font-weight: 400;">Connect to a Channel</span></h3>
<p><span style="font-weight: 400;">Inside of the “Okay” button, we have the option to provide a callback. This runs when the user either clicks or presses enter on the button. We want to use the “`move“` keyword again to allow this callback ownership of all the variables it needs. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">.button("Okay", move | s | {
    //... 
    //Okay callback
}</pre>
<p><span style="font-weight: 400;">Let’s grab the values that the user entered into the EditViews earlier.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//Inside Okay
let channel = s
    .call_on_id("channel", |view: &amp;mut EditView| view.get_content())
    .unwrap();
let username = s
    .call_on_id("username", |view: &amp;mut EditView| view.get_content())
    .unwrap();
</pre>
<p><span style="font-weight: 400;">Check if the username is empty, and if so, create a layer telling the user to enter a username. If it does not, then check if the channel name was empty. If it was, set it to “global” as a default.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//Checking if username input is empty.
if username.is_empty() {
    s.add_layer(Dialog::info("Please enter a username!".to_string()));
} else {
    let new_channel =
        if channel.is_empty() {
        "global".to_string()
        } else {
            channel.to_string()
        };

    //...
    //The rest of connecting to PubNub
}
</pre>
<p><span style="font-weight: 400;">Continuing in that same else statement, let’s send the channel that we have (either “global” or a user-defined channel) to the subscribe loop. Once we do this, our loop will be able to proceed, and request messages from PubNub. Before we load the next screen, pop the initial layer.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">channel_sender.send(new_channel).unwrap();
s.pop_layer();
</pre>
<h3><span style="font-weight: 400;">Create the Chat Layer</span></h3>
<p><span style="font-weight: 400;">Create another layer now, this will be a BoxView with a fixed size of 40, 20. Inside of that box will be a Dialog with a title. It has a content field. It’ll be aligned in the center, with a send and a quit button. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//...
//Still in else statement
s.add_layer(BoxView::with_fixed_size((40, 20),
    Dialog::new()
    .title("PubNub Chat")
    .content(
        //...
        //Chat view: Includes list of messages and EditView
    )
    .h_align(HAlign::Center)
    .button("Send", CALLBACK)
    .button("Quit", | s | s.quit()),
))
//End of UI design</pre>
<p><span style="font-weight: 400;">I&#8217;ll first show how to design the content, then I&#8217;ll show how to send a message. Inside the content function of the Dialog, insert a LinearLayout. This is to stack a Scrollview and an EditView on top of each other. Inside of the ScrollView, we insert another LinearLayout. This extra LinearLayout is so we can remove extra lines if we’d like. Some other views do not provide this functionality. Make the ScrollView stick to the bottom when new messages are received, using &#8220;`scroll_strategy&#8220;`. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//Inside Content
LinearLayout::vertical()
    .child(
        ScrollView::new(
            LinearLayout::vertical()
            //Children of the LinearLayout
        )
        .scroll_strategy(ScrollStrategy::StickToBottom),
    )
    //Next Child</pre>
<p><span style="font-weight: 400;">Inside of this second LinearLayout, we have DummyViews on the top and bottom, with the “`with“` child between. It provides a reference to the LinearLayout and we can add children dynamically. Add some DummyViews, I chose 13, a number that works well with our layers height. We add these empty lines so that when new messages come in, they appear at the bottom first. Set the LinearLayouts ID to “messages” or whatever you want. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//Children of inner LinearLayout
.child(DummyView.fixed_height(1))
//Add in a certain amount of dummy views, to make the new messages appear at the bottom
.with( | messages | {
    for _ in 0. .13 {
   		messages.add_child(DummyView.fixed_height(1));
    }
})
.child(DummyView.fixed_height(1))
.with_id("messages"),
</pre>
<p><span style="font-weight: 400;">At the end of the first LinearLayout add an EditView child with the ID of “message.” </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//Child of first LinearLayout
.child(EditView::new().with_id("message")),
//End of content</pre>
<h3><span style="font-weight: 400;">Publishing a Message</span></h3>
<p><span style="font-weight: 400;">Now that we’ve designed our chat view, let’s work on sending some messages! Just like our “Okay” button from the previous layer, we want a callback and to move all the required variables into it.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">.button("Send", move |s| {
  //...
    //Rest of the callback
}</pre>
<p><span style="font-weight: 400;">Take the message from the EditView, as we did before, and check if it’s empty. If it is, then alert the user and tell them to type a message. If it is not empty, then we check if the channel that they entered is empty or filled, like we did above. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//Inside callback
let message = s
    .call_on_id("message", |view: &amp;mut EditView| view.get_content())
    .unwrap();
if message.is_empty() {
    s.add_layer(Dialog::info("Please enter a message!".to_string()))
} else {
    let new_channel_2 = if channel.is_empty() {
    	"global".to_string()
    } else {
    	channel.to_string()
    };
    
    //...
    //Will handlee publishing messages
}
//End of callback</pre>
<p><span style="font-weight: 400;">Call our publish function with the message, the username, and the channel names that the user entered. If the result was an error, then we tell the user that we encountered an error while publishing. If it went well, then we clear the text from the EditView. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//In the else statement
let result = publish(message.to_string(), username.to_string(), new_channel_2 );
if result.is_err() {
    //If there was an error then we say that there is one, and don't do anything.
    s.add_layer(Dialog::info("Error Publishing".to_string()));
} else {
    //Clear out the EditView.
    s.call_on_id("message", |view: &amp;mut EditView| {
        view.set_content("")
  }).unwrap();
}
//End of else + callback</pre>
<h2><span style="font-weight: 400;">Inserting New Messages Into UI</span></h2>
<p><span style="font-weight: 400;">Usually, we would use the command “`siv.run()“` to have the UI start, but since we want to control when the UI changes we use “`siv.refresh()“` instead. Create a new variable to count how many messages we receive, and refresh the UI after it updates.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//...
//After creating the UI design/layers
let mut message_count = 0;
siv.refresh();</pre>
<p><span style="font-weight: 400;">Create a loop that first calls “step” to increment through the UI event loop. Check if cursive is running at that point, and if it’s not, break out of the loop. Create a variable to track whether there needs to be a UI refresh and set it to false. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">loop {
    siv.step();
    if !siv.is_running() {
        break;
    }

    let mut needs_refresh = false;

    //...
    //Handle new messages
}
</pre>
<p><span style="font-weight: 400;">Now for the final requirement, we need to check if any messages are waiting for us in the channel queue. We can use a non-blocking method on the “`msg_receiver“` to see if anything is waiting. If there are messages, it will return an iterator. We can use a Rust for loop to iterate through the messages. </span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">for m in msg_receiver.try_iter() {
    //...
    //Adding each message "m" in
}
</pre>
<p><span style="font-weight: 400;">Inside of this for loop, we access the LinearLayout with the ID “messages”. We can then set our refresh boolean to true, add one to the message count, and add the message as a child to the LinearLayout. In that loop, you can also remove the first child. This is to avoid a scroll bar from appearing until the messages go past the screen! Be sure to check if the message count is less than or equal to your DummyView count plus one.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">//Inside of for loop
siv.call_on_id("messages", |messages: &amp;mut LinearLayout| {
  needs_refresh = true;
    message_count += 1;
    messages.add_child(TextView::new(m));
    if message_count &lt;= 14 {
        messages.remove_child(0);
    }
});</pre>
<p><span style="font-weight: 400;">If our refresh boolean is true at the end of the loop, then we can refresh the UI and show the changes.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="rust">if needs_refresh {
    siv.refresh();
}
//End of loop
//End of Main</pre>
<p>After completing the main function, the chat app finished. If you enter <code class="EnlighterJSRAW" data-enlighter-language="null">cargo run</code> into your terminal, A UI will pop up asking for a username and channel name. Entering at least a username will allow you to connect to either the channel you entered or &#8220;global&#8221; as a default. If you enter a message and click &#8220;Send&#8221;, the message will appear on your screen. Open up multiple command lines and chat in between them, or chat with others if they have access to the same keys as you.</p>
<div id="attachment_45503" style="width: 810px" class="wp-caption alignnone"><a href="https://www.pubnub.com/wp-content/uploads/2019/08/rustychat.gif"><img aria-describedby="caption-attachment-45503" class="size-full wp-image-45503" src="https://www.pubnub.com/wp-content/uploads/2019/08/rustychat.gif" alt="rust chat gif" width="800" height="323" /></a><p id="caption-attachment-45503" class="wp-caption-text">Our final chat app with a Cursive Terminal UI.</p></div>
<h2>Next Steps</h2>
<p><span style="font-weight: 400;">In this tutorial, we created a terminal chat app in Rust. It uses PubNub’s Pub/Sub to send and receive messages through a Cursive Terminal UI. This is only an example of what is possible with Rust and PubNub.  If you’re using Rust to compute an algorithm, or run a game, and you need some I/O around the world, PubNub can help.</span></p>
<p><span style="font-weight: 400;">Want to try this in another language? PubNub has over <a href="https://www.pubnub.com/docs">75+ SDKs</a> and hundreds of <a href="https://www.pubnub.com/blog/">tutorials</a>.</span></p><p>The post <a  href="https://www.pubnub.com/blog/build-realtime-rust-chat-app-cursive-tui/">Rustacean Terminal Chat App in Rust</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>FaceTracking Desktop Security System with OpenCV, React Native, Cloudinary, ClickSend, SendGrid and PubNub</title>
		<link>https://www.pubnub.com/blog/facetracking-desktop-security-system-with-opencv-cloudinary-react-native-clicksend-sendgrid-and-pubnub/</link>
				<pubDate>Wed, 07 Aug 2019 17:20:35 +0000</pubDate>
		<dc:creator><![CDATA[Cameron Akhavan]]></dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[React Native]]></category>
		<category><![CDATA[Cognitive Services]]></category>
		<category><![CDATA[Machine Learning]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Machine Vision]]></category>
		<category><![CDATA[Firebase Cloud Messaging (FCM)]]></category>
		<description><![CDATA[<p>A step-by-step guide to building your own desktop security system with a facial recognition machine learning algorithm.</p>
<p>The post <a  href="https://www.pubnub.com/blog/facetracking-desktop-security-system-with-opencv-cloudinary-react-native-clicksend-sendgrid-and-pubnub/">FaceTracking Desktop Security System with OpenCV, React Native, Cloudinary, ClickSend, SendGrid and PubNub</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><span style="font-weight: 400;">In this tutorial, we are going to explore one of the most cutting edge technologies in machine learning AI&#8230;<strong>computer vision!</strong> To showcase its capabilities, this step-by-step article will walk you through building your very own desktop security system with a facial recognition machine learning algorithm.</span></p>
<p><span style="font-weight: 400;">With a simple webcam, your program will be able to recognize the faces of people you choose to allow into the system. It will trigger a text, email, and snapshot image alert system, if any unrecognized faces appear in front of your webcam. We&#8217;ll also use Cloudinary and PubNub to build a React Native application that can receive a snapshot image of an &#8220;intruder&#8217;s&#8221; face. It will also allow a user to be added to the system if you desire.</span></p>
<a href="https://www.pubnub.com/wp-content/uploads/2019/08/facetrackeroptimized.gif"><img class="wp-image-45568 size-full aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/08/facetrackeroptimized.gif" alt="" width="600" height="338" /></a>
<h2>What is Computer Vision?</h2>
<p>Computer Vision is a specific field in artificial intelligence that deals with training machine learning models to understand and interpret the visual world. By learning from images and frames from cameras and videos, a computer vision AI can accurately classify the objects it sees and subsequently perform reactionary tasks just like we humans do.</p>
<div id="attachment_44655" style="width: 610px" class="wp-caption aligncenter"><a href="https://www.pubnub.com/wp-content/uploads/2019/07/computervision.gif"><img aria-describedby="caption-attachment-44655" class="wp-image-44655 size-full" src="https://www.pubnub.com/wp-content/uploads/2019/07/computervision.gif" alt="" width="600" height="338" /></a><p id="caption-attachment-44655" class="wp-caption-text"><a href="https://towardsdatascience.com/how-to-do-everything-in-computer-vision-2b442c469928" target="_blank" rel="noopener noreferrer">Source</a> Accessed 7/31/19</p></div>
<p>But enough talk&#8230;It&#8217;s time to code!</p>
<h2>Python Code for Your FaceTracking Alert System</h2>
<p>Before jumping into the code, be sure you <a href="https://dashboard.pubnub.com/signup" target="_blank" rel="noopener noreferrer">sign up for a free PubNub account</a> so we don’t run into any issues later.</p>
<p><span style="font-weight: 400;">To start building the project from scratch, create your project&#8217;s directory using your computer’s command line app:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">mkdir faceTrackingApp
cd faceTrackingApp</pre>
<p>Then create a new Python file called <strong>facetracker.py</strong>.</p>
<h2>Libraries and Dependencies for Computer Vision</h2>
<h3>OpenCV and face_recognition</h3>
<p>First, let&#8217;s import some machine learning libraries for our app&#8217;s face tracking capabilities. The main libraries we are going to use are OpenCV and face_recognition.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">import face_recognition # Machine Learning Library for Face Recognition
import cv2 # OpenCV
import numpy as np # Handling data
import time
import os,sys</pre>
<p><a href="https://opencv.org/" target="_blank" rel="noopener noreferrer">OpenCV</a> is the most popular machine learning library for realtime Computer Vision. <span style="font-weight: 400;">The library has useful tools such as webcam control as well as models to train a face tracking app from scratch.</span></p>
<p>However, our project will primarily use <a href="https://github.com/ageitgey/face_recognition" target="_blank" rel="noopener noreferrer">ageitgey&#8217;s face_recognition python library</a> as it already comes with a face recognition model out of the box, making it extremely quick and easy to use.</p>
<h3>PubNub</h3>
<p>Next, we&#8217;re going to setup PubNub as our Data Stream Network to handle all of the data between our Python script and mobile application.</p>
<p>After you&#8217;ve retrieved your free <a href="https://dashboard.pubnub.com/signup" target="_blank" rel="noopener noreferrer">PubNub API keys</a>, install the <a href="https://www.pubnub.com/docs/python/pubnub-python-sdk" target="_blank" rel="noopener noreferrer">PubNub Python SDK</a>.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">pip install 'pubnub&gt;=4.1.4'</pre>
<p>Then, import the library in your python file,</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">from pubnub.callbacks import SubscribeCallback
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
from pubnub.enums import PNOperationType, PNStatusCategory</pre>
<p>and configure a PubNub instance with your API keys.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null"># PubNub Config
pnconfig = PNConfiguration()
pnconfig.subscribe_key = "YOUR_SUBSCRIBE_KEY"
pnconfig.publish_key = "YOUR_PUBLISH_KEY"
pnconfig.ssl = False
pubnub = PubNub(pnconfig)</pre>
<h3>Cloudinary</h3>
<p>Lastly, we will setup <a href="https://cloudinary.com/" target="_blank" rel="noopener noreferrer">Cloudinary</a> as our Content Delivery Network to store images of intruders&#8217; faces. This will work beautifully with PubNub as our python script can upload the image to Cloudinary, get the URL from the response, then PubNub will send that URL to our Client app to render.</p>
<a href="https://www.pubnub.com/wp-content/uploads/2019/08/pnubcloudinary.png"><img class="aligncenter wp-image-45291 size-full" src="https://www.pubnub.com/wp-content/uploads/2019/08/pnubcloudinary.png" alt="" width="851" height="491" /></a>
<p>First, <a href="https://cloudinary.com/users/register/free" target="_blank" rel="noopener noreferrer">sign up for a free Cloudinary account</a> and then install the Cloudinary Python SDK with:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">pip install cloudinary</pre>
<p>Setup the <code>CLOUDINARY_URL</code> environment variable by copying it from the <a href="https://cloudinary.com/console" >Management Console</a>.</p>
<p>Using zsh/bash/sh:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">export CLOUDINARY_URL=cloudinary://API-Key:API-Secret@Cloud-name</pre>
<p>Import the library in your Python script,</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">from cloudinary.api import delete_resources_by_tag, resources_by_tag
from cloudinary.uploader import upload
from cloudinary.utils import cloudinary_url</pre>
<p>and configure a Cloudinary instance.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null"># Cloudinary Config
os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '.'))
if os.path.exists('settings.py'):
    exec(open('settings.py').read())
DEFAULT_TAG = "python_sample_basic"</pre>
<h2>Machine Learning Face Tracking Algorithm</h2>
<p>Before we begin building our face recognition machine learning model, we&#8217;ll need to declare some global variables:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null"># Setup some Global Variables
video_capture = cv2.VideoCapture(0) # Webcam instance
known_face_names = [] # Names of faces
known_face_encodings = [] # Encodings of Faces
count = 0 # Counter for Number of Unknown Users
flag = 0 # Flag for Setting/Unsetting "Intruder Mode"</pre>
<p>NOTE: We create a count variable for the unknown users because we are going to dynamically save the user&#8217;s snapshot image in a file path. We&#8217;re  going to append the count to the file name like an ID tag. In order to find this snapshot image later, we need to pull up that user&#8217;s count variable, so we can find the image in the file path.</p>
<p><span style="font-weight: 400;">To start training our face recognizer model, we’ll begin with two sample images of faces. You will need two images of two different people&#8217;s faces in your project directory.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="null"># Load a sample picture and learn how to recognize it.
sample_face_1 = face_recognition.load_image_file("sample_1.jpeg")
sample_face_1_encoding = face_recognition.face_encodings(sample_face_1)[0]

# Load a second sample picture and learn how to recognize it.
sample_face_2 = face_recognition.load_image_file("17.png")
sample_face_2_encoding = face_recognition.face_encodings(sample_face_2)[0]

# Create arrays of known face encodings and their names
known_face_encodings = [
    sample_face_1_encoding,
    sample_face_2_encoding
]

# Create Names for Sample Face encodings
known_face_names = [
    "sample_1",
    "sample_2"
]

# Initialize some variables
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True</pre>
<p>Next, we will declare a while loop that will run continuously for the duration of the app. The loop will be responsible for the main functions of our app:</p>
<ul>
<li>Turning on and displaying the webcam feed</li>
<li>Tracking faces that appear in front of the webcam and drawing a red box around the face in realtime</li>
<li>Displaying a name below a known user&#8217;s face and &#8220;Unknown&#8221; for a face that has not been added to the database</li>
<li>Calling a series of Alerts and Functions to handle when an &#8220;Unknown&#8221; face appears on screen</li>
</ul>
<pre class="EnlighterJSRAW">while(True):
    
    video_capture = cv2.VideoCapture(0)
    # Grab a single frame of video
    ret, frame = video_capture.read()

    # Resize frame of video to 1/4 size for faster face recognition processing
    small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)

    # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
    rgb_small_frame = small_frame[:, :, ::-1]

    # Only process every other frame of video to save time
    if process_this_frame:
        # Find all the faces and face encodings in the current frame of video
        face_locations = face_recognition.face_locations(rgb_small_frame)
        face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)

        face_names = []
        for face_encoding in face_encodings:
            # See if the face is a match for the known face(s)
            matches = face_recognition.compare_faces(known_face_encodings, face_encoding)
            name = "Unknown"

            # # If a match was found in known_face_encodings, just use the first one.
            # if True in matches:
            #     first_match_index = matches.index(True)
            #     name = known_face_names[first_match_index]

            # Or instead, use the known face with the smallest distance to the new face
            face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
            best_match_index = np.argmin(face_distances)
            if matches[best_match_index]:
                name = known_face_names[best_match_index]

            face_names.append(name)

            #---------------------See next section for this code block's explanation---------------------#

            ## Set Unknown User Flag and Send Alerts
            #global flag
            #if(name=='Unknown' and flag==0):
            #    flag = 1
            #    Alert()
            #
            #--------------------------------------------------------------------------------------------#

    process_this_frame = not process_this_frame

    # Display the results
    for (top, right, bottom, left), name in zip(face_locations, face_names):
        # Scale back up face locations since the frame we detected in was scaled to 1/4 size
        top *= 4
        right *= 4
        bottom *= 4
        left *= 4

        # Draw a box around the face
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)

        # Draw a label with a name below the face
        cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
        font = cv2.FONT_HERSHEY_DUPLEX
        cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)

    # Display the resulting image
    cv2.imshow('Video', frame)

    # Hit 'q' on the keyboard to quit!
    if cv2.waitKey(10) &amp; 0xFF == ord('q'):
        break

# Release handle to the webcam
video_capture.release()
cv2.destroyAllWindows()</pre>
<h2>Sending Alerts</h2>
<p>We shall take care of the case when an unregistered face appears in front of our webcam. We want our program to trigger an alert system the moment it sees an &#8220;Unknown&#8221; face. Luckily, all we need to do is add a few lines of code to our main while loop at the end of the <strong><em>for face_encoding in face_encodings:</em></strong> loop.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null"># Set Unknown User Flag and Send Alerts
global flag
if(name=='Unknown' and flag==0):
    flag = 1 # Stop repeated calls of Alerts until after the Unknown User is dealt with
    Alert() # Trigger Alert System</pre>
<p>When the alert is triggered, we can then define a function to take a snapshot of the unknown user&#8217;s face, call a function to upload the snapshot to Cloudinary, and finally call our Text/Email alert function.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">def Alert():
    global count
    video_capture = cv2.VideoCapture(0) # Create Open CV Webcam Instance
    path = './' # Specify where you want the snapshot to be stored
    name = 'Unknown_User' + str(count) # Append User ID to File Path

    # Wait for 3 seconds
    print('Taking picture in 3')
    time.sleep(1)
    print('Taking picture in 2')
    time.sleep(1)
    print('Taking picture in 1')
    time.sleep(1)

    # Take Picture
    ret, frame = video_capture.read()

    # Grayscale Image to save memory space
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # Save Image in File Path
    status = cv2.imwrite('% s/% s.jpg' % (path, name),gray)
    print('Unknown User Saved to Database', status)

    # Upload Snapshot to Cloudinary 
    upload_files('% s/% s.jpg' % (path,name))
    
    # Send Out Email and Text Alerts
    sendAlerts()</pre>
<p>NOTE: We grayscale the image because the face recognizer doesn&#8217;t need color to determine facial features. We also store the snapshot image locally so we can add the face to the recognizer if the client wants to add the user later.</p>
<p>When defining our <strong>upload_files()</strong> function, we&#8217;re passing in the snapshot&#8217;s file path so Cloudinary knows where to upload the file from. We then get the response URL of where the image lives in the cloud. We send this url along with a user ID (count of Unknown user) over PubNub to our client application. The client application can then render the image of the snapshot from the Cloudinary URL.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">def upload_files(msg):
    global count # Make global changes to count
    response = upload(msg, tags=DEFAULT_TAG) # Upload Image to Cloudinary
    url, options = cloudinary_url( 
        response['public_id'],
        format=response['format'],
        width=200,
        height=150,
        crop="fill"
    )
    dictionary = {"url": url, "ID": count}
    pubnub.publish().channel('global').message(dictionary).pn_async(publish_callback)
    count+=1 # Increment Unknown User Count</pre>
<p><span style="font-weight: 400;">In order to publish with PubNub, we need to define a publish callback.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">def publish_callback(result, status):
    pass
    # Handle PNPublishResult and PNStatus</pre>
<p>&nbsp;</p>
<p>To setup your Text and Email alerts, you&#8217;ll need to sign up for a <a href="https://www.clicksend.com/us/" target="_blank" rel="noopener noreferrer">free ClickSend account</a> as well as a <a href="https://sendgrid.com/marketing/sendgrid-services-cro/?extProvId=5&amp;extPu=49397-gaw&amp;extLi=115523142&amp;sem_adg=8368110942&amp;extCr=8368110942-299384208935&amp;extSi=&amp;extTg=&amp;keyword=sendgrid&amp;extAP=1t1&amp;extMT=e&amp;gclid=EAIaIQobChMIrtuHkIjg4wIVeSCtBh0q6A7hEAAYASAAEgKArvD_BwE" target="_blank" rel="noopener noreferrer">free SendGrid account</a> to get your API keys.</p>
<p>Now you get to see the power and beauty behind <a href="https://www.pubnub.com/products/functions/" target="_blank" rel="noopener noreferrer">PubNub Functions</a> with our <a href="https://www.pubnub.com/docs/blocks-catalog" target="_blank" rel="noopener noreferrer">Partnered Blocks</a>. Go ahead and visit both our <a href="https://www.pubnub.com/docs/blocks-catalog/clicksend-sms" target="_blank" rel="noopener noreferrer">ClickSend Block</a> as well as our <a href="https://www.pubnub.com/docs/blocks-catalog/sendgrid" target="_blank" rel="noopener noreferrer">SendGrid Block</a>. Through those links, PubNub will automatically generate a customizable PubNub Function.</p>
<p><span style="font-weight: 400;">The serverless, open-source code will completely handle the APIs for you. All you need to do is put in your API keys and you&#8217;re good to go!</span></p>
<p><span style="font-weight: 400;">Once you&#8217;ve set up your PubNub Functions, you can define a </span><b>sendAlerts()</b><span style="font-weight: 400;"> function to publish a message, implementing your Text and Email alerts:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">def sendAlerts():
    dictionary = {
    "to" : 'RECEIVING PHONE NUMBER',
    "body": "There is an unregistered user at your desk!"
    }
    pubnub.publish().channel('clicksend-text').message(dictionary).pn_async(publish_callback)

    dictionary = {
    "to": "EMAIL RECEIVER",
    "toname": "EMAIL SENDER",
    "subject": "INTRUDER ALERT",
    "text": "THERE IS AN UNREGISTERED USER AT YOUR DESK"
    }   
    pubnub.publish().channel('email-sendgrid-channel').message(dictionary).pn_async(publish_callback)</pre>
<p>NOTE: In order to properly use a PubNub block, you need to publish over the same channel specified in your block (you can check this in your blocks Functions dashboard) as well as formatting the message payload properly (according to the block&#8217;s documentation).</p>
<h2>Adding Users to Our Facetracker</h2>
<p><span style="font-weight: 400;">When an Unregistered face is detected on our webcam, our Python script sends an email/text alert as well as a snapshot image to our client application.</span></p>
<p><span style="font-weight: 400;">We now want to add the ability to add a user&#8217;s face to our app&#8217;s &#8220;</span><b>known_faces</b><span style="font-weight: 400;">&#8221; database, so the user will no longer trigger our alert system. To do this, the client application must publish a message over PubNub.</span></p>
<p><span style="font-weight: 400;">To receive this message in our python application, we must subscribe to the channel the client is publishing from, and create a </span><b>Subscriber Callback</b><span style="font-weight: 400;"> to handle the incoming message.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">class MySubscribeCallback(SubscribeCallback):
    def status(self, pubnub, status):
        pass
        # The status object returned is always related to subscribe but could contain
        # information about subscribe, heartbeat, or errors
        # use the operationType to switch on different options
        if status.operation == PNOperationType.PNSubscribeOperation \
                or status.operation == PNOperationType.PNUnsubscribeOperation:
            if status.category == PNStatusCategory.PNConnectedCategory:
                pass
                # This is expected for a subscribe, this means there is no error or issue whatsoever
            elif status.category == PNStatusCategory.PNReconnectedCategory:
                pass
                # This usually occurs if subscribe temporarily fails but reconnects. This means
                # there was an error but there is no longer any issue
            elif status.category == PNStatusCategory.PNDisconnectedCategory:
                pass
                # This is the expected category for an unsubscribe. This means here
                # was no error in unsubscribing from everything
            elif status.category == PNStatusCategory.PNUnexpectedDisconnectCategory:
                pass
                # This is usually an issue with the internet connection, this is an error, handle
                # appropriately retry will be called automatically
            elif status.category == PNStatusCategory.PNAccessDeniedCategory:
                pass
                # This means that PAM does not allow this client to subscribe to this
                # channel and channel group configuration. This is another explicit error
            else:
                pass
                # This is usually an issue with the internet connection, this is an error, handle appropriately
                # retry will be called automatically
        elif status.operation == PNOperationType.PNSubscribeOperation:
            # Heartbeat operations can in fact have errors, so it is important to check first for an error.
            # For more information on how to configure heartbeat notifications through the status
            if status.is_error():
                pass
                # There was an error with the heartbeat operation, handle here
            else:
                pass
                # Heartbeat operation was successful
        else:
            pass
            # Encountered unknown status type
 
    def presence(self, pubnub, presence):
        pass  # handle incoming presence data
    def message(self, pubnub, message):
        addUser(message.message["ID"], message.message["name"])
 
 
pubnub.add_listener(MySubscribeCallback())
pubnub.subscribe().channels('ch1').execute()</pre>
<p><span style="font-weight: 400;">NOTE: Above we assume the client is publishing the ID of the unknown user (for image file path) as well as the name of the user (to display below the user&#8217;s face). </span></p>
<p>With the parameters in hand, we can add the new user to our database.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">def addUser(ID, name):
    global known_face_encodings, known_face_names, flag
    path = './Unknown_User' + str(ID) # Append User ID to File Path
    # Load User's picture and learn how to recognize it.
    user_image = face_recognition.load_image_file('% s.jpg' % (path)) # Load Image
    user_face_encoding = face_recognition.face_encodings(user_image)[0] # Encode Image
    known_face_encodings.append(user_face_encoding) # Add Encoded Image to 'Known Faces' Array
    known_face_names.append(name) # Append New User's Name to Database
    flag = 0 # Reset Unknown User Flag</pre>
<h2>React Native Code for Our Client Application</h2>
<h2>Setting Up Our Realtime React Native Environment</h2>
<p>Install <a href="https://apps.apple.com/us/app/xcode/id497799835?mt=12" target="_blank" rel="noopener noreferrer">Xcode</a> so we can build and simulate our app for IOS <span style="font-weight: 400;">and </span><a href="https://developer.android.com/studio?gclid=EAIaIQobChMI1LzfwrDi4wIVAspkCh3lNwvsEAAYASAAEgLXGvD_BwE"><span style="font-weight: 400;">Android Studio</span></a><span style="font-weight: 400;"> for Android.</span></p>
<p>Then install <a href="https://nodejs.org/en/" target="_blank" rel="noopener noreferrer">Node.js</a> and watchman using <a href="https://brew.sh/" target="_blank" rel="noopener noreferrer">Homebrew</a>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">brew install node
brew install watchman</pre>
<p>Install the React Native CLI with NPM:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">npm install -g react-native-cli</pre>
<p>To create a React Native App template, enter the React Native CLI command in your project&#8217;s directory:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">react-native init client
cd client</pre>
<p>Since we&#8217;re going to be using PubNub in our Client app to send and receive messages, we&#8217;ll need to install the PubNub React SDK,</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">npm install --save pubnub pubnub-react</pre>
<p>and then link the library like so:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">react-native link pubnub-react</pre>
<h2>Setting Up Realtime Pub/Sub Messaging</h2>
<p>To start sending and receiving messages in realtime in our app, first import the <a href="https://www.pubnub.com/docs/react-native-javascript/pubnub-javascript-sdk" target="_blank" rel="noopener noreferrer">PubNub React SDK</a>.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">import PubNubReact from 'pubnub-react';</pre>
<p>Then import the <strong>TouchableOpacity</strong> and <strong>Image</strong> components from React Native,</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">import {
  StyleSheet,
  View,
  Text,
  TextInput,
  TouchableOpacity,
  Image,
} from 'react-native';
</pre>
<p><span style="font-weight: 400;">Now we add a constructor at the top of our App Component. The constructor will be responsible for setting up a PubNub instance with our Publish/Subscribe keys as well as initialize the following state variables:</span></p>
<ul>
<li style="font-weight: 400;"><b>image</b><span style="font-weight: 400;"> &#8211; Snapshot image from an unknown user alert (we initialize it with a placeholder image until a Snapshot alert arrives).</span></li>
<li style="font-weight: 400;"><b>message</b><span style="font-weight: 400;"> &#8211; Incoming alert message from the face tracking app.</span></li>
<li style="font-weight: 400;"><b>text</b><span style="font-weight: 400;"> &#8211; Client user&#8217;s input for typing in the name of a user.</span></li>
<li><b>count</b><span style="font-weight: 400;"> &#8211;  To keep track of which unknown user we are getting an alert from.</span></li>
</ul>
<pre class="EnlighterJSRAW" data-enlighter-language="null">export default class App extends React.Component {

  constructor(props) {
    super(props)

    this.pubnub = new PubNubReact({
      publishKey: "YOUR PUBLISH KEY",
      subscribeKey: "YOUR SUBSCRIBE KEY"
    })

    //Base State
    this.state = {
      image: require('./assets/PLACEHOLDER_IMAGE.jpg'),
      message: '',
      text: '',
      count: 0,
    }

    this.pubnub.init(this);
  }

/// .......VVV REST OF THE CODE VVV.......///</pre>
<p><span style="font-weight: 400;">When our client app first fires up, we declare an asynchronous function that will subscribe to our face tracking alert channel and handle message events. In this case, we receive the ID (count of unknown user) as well as the snapshot image URL (from Cloudinary) of the unknown user.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">async componentDidMount() {
  this.setUpApp()    
}

async setUpApp(){
  this.pubnub.getMessage("global", msg =&gt; {
    this.setState({count: msg.message.ID})
    this.setState({image: msg.message.url})
  })

  this.pubnub.subscribe({
    channels: ["global"],
    withPresence: false
  });
}</pre>
<p><span style="font-weight: 400;">Once that image is received by the mobile app, the client user should then be able to add the unknown user to the face tracker&#8217;s &#8220;</span><b>known_faces</b><span style="font-weight: 400;">&#8221; database. We can define a function to set the state of the client user&#8217;s input for the unknown user&#8217;s name.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="null"> handleText = (name) =&gt; {
   this.setState({ text: name })
}
</pre>
<p><span style="font-weight: 400;">We can also write a function to publish the added user&#8217;s name along with the added user&#8217;s ID.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="null"> publishName = (text) =&gt; {
  this.pubnub.publish({
    message: {
      ID: this.state.count,
      name: text,
    },
    channel: "ch1"
  });
}
</pre>
<h2>Creating and Rendering App Components</h2>
<p>At the top of our screen we&#8217;ll render the snapshot image from an incoming &#8220;Unknown User&#8221; Alert. The source of this image will be a URI we grabbed from the alert message that we saved to state.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">&lt;Image
  source={{uri: this.state.image}}
  style={{width: 250, height: 250}}
/&gt;</pre>
<p>Below that, we can display a suitable caption.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">&lt;Text&gt;{'Do You Know This Person?'}&lt;/Text&gt;</pre>
<p>We then create a Text Input component to store the name of the User to be added to the face tracker, if the client decides to do so.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">&lt;TextInput style = {styles.input}
         underlineColorAndroid = "transparent"
         placeholder = "Name"
         placeholderTextColor = "#9a73ef"
         autoCapitalize = "none"
         onChangeText = {this.handleText}/&gt;</pre>
<p>Lastly, we create a submit button with TouchableOpacity to publish the added user&#8217;s name for our Face Tracker to add to the system:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">&lt;TouchableOpacity
    style = {styles.submitButton}
    onPress = {
      () =&gt; this.publishName(this.state.text)
    }&gt;
      &lt;Text&gt;"SUBMIT"&lt;/Text&gt;
&lt;/TouchableOpacity&gt;</pre>
<p><span style="font-weight: 400;">Wrap all those components in a </span><b>&lt;View&gt; &lt;/View&gt;</b><span style="font-weight: 400;"> and you’re good to go!</span></p>
<h2>Running the Program</h2>
<p><span style="font-weight: 400;">First, start up the React Native client application on Android or iOS by opening a terminal in the client app&#8217;s directory.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">react-native run-ios

or

react-native run-android</pre>
<p>Then, in another terminal window, run the Python face tracker.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">python facetracker.py</pre>
<h2>If You&#8217;re Still Hungry For More&#8230;</h2>
<p>Feel free to send us any of your questions, concerns, or comments at devrel@pubnub.com.</p>
<p>If you’re still hungry for more PubNub Machine Learning content, here are some other articles that you may be interested in:</p>
<ul>
<li><a href="https://www.pubnub.com/blog/realtime-machine-learning-online-learning-with-pubnub/" target="_blank" rel="noopener noreferrer">Realtime Machine Learning: Online Learning with PubNub</a></li>
<li><a href="https://www.pubnub.com/blog/pubnub-and-machine-learning-algorithm/" target="_blank" rel="noopener noreferrer">How PubNub Can Turbocharge Your Machine Learning Algorithm</a></li>
<li><a href="https://www.pubnub.com/blog/cognitive-era-big-data-realtime-edge-computing/">The Cognitive Era: Big Data, Realtime, and the Edge (Computing)</a></li>
</ul><p>The post <a  href="https://www.pubnub.com/blog/facetracking-desktop-security-system-with-opencv-cloudinary-react-native-clicksend-sendgrid-and-pubnub/">FaceTracking Desktop Security System with OpenCV, React Native, Cloudinary, ClickSend, SendGrid and PubNub</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Node.js WebSocket Programming Examples</title>
		<link>https://www.pubnub.com/blog/nodejs-websocket-programming-examples/</link>
				<pubDate>Tue, 06 Aug 2019 18:37:26 +0000</pubDate>
		<dc:creator><![CDATA[Adam Bavosa]]></dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[WebSockets]]></category>
		<category><![CDATA[Node.js]]></category>
		<description><![CDATA[<p>An overview and examples of basic socket and WebSocket programming with Node.js.</p>
<p>The post <a  href="https://www.pubnub.com/blog/nodejs-websocket-programming-examples/">Node.js WebSocket Programming Examples</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>WebSockets are an excellent technology selection when you are designing your realtime app. Imagine an app user interface where you see <a href="https://www.pubnub.com/developers/tutorials/golang/realtime-stock-ticker/" target="_blank" rel="noopener noreferrer">realtime stock prices</a>. The faster a user learns about a stock price&#8217;s change, the faster they can react, and execute a buy or sell order. Money is on the line.</p>
<img class="size-full wp-image-45205 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2017/06/pubnub-stock-ticker-example-animation.gif" alt="Stock Ticker with PubNub and Golang" width="425" height="320" />
<p>&nbsp;</p>
<h2>What is a WebSocket?</h2>
<p><a href="https://www.pubnub.com/learn/glossary/what-is-websocket/" target="_blank" rel="noopener noreferrer">WebSocket</a> is its own layer 7 protocol, similar to HTTP. WebSockets create a full-duplex connection for sending messages from client to server, or server to client at any instant. This pattern is far superior to HTTP request-response when an application requires systems to get the latest data ASAP.</p>
<h2>When Should I Write WebSocket Code?</h2>
<p>Besides a <a href="https://www.pubnub.com/blog/build-a-cryptocurrency-price-tracker-in-5-minutes/">realtime stock or cryptocurrency tracker app</a>, other common realtime use cases for WebSockets are:</p>
<ul>
<li><a href="https://www.pubnub.com/solutions/chat/">Chat apps</a></li>
<li><a href="https://www.pubnub.com/solutions/geolocation-maps-geofencing/">Live geolocation tracking on a map</a></li>
<li>Live audience interaction</li>
<li>Online auctions bid submission</li>
<li>IoT device updates</li>
<li><a href="https://www.pubnub.com/blog/integrating-video-calling-in-chat-with-webrtc-and-pubnub/">WebRTC call orchestration</a></li>
</ul>
<p>WebSockets create a <a href="https://en.wikipedia.org/wiki/Network_socket" target="_blank" rel="noopener noreferrer">TCP socket connection</a> between multiple devices or processes. Similar functionality can be implemented using <a href="https://www.pubnub.com/blog/http-long-polling/">HTTP Long Polling</a> or using a service like PubNub. Let&#8217;s go over some basic socket and WebSocket programming with Node.js.</p>
<h2>Node.js Socket Example</h2>
<p>Let&#8217;s say you need to write a server application, and you chose Node.js as your programming language. Your users can be any type of client, like a web browser, mobile app, IoT device, Node.js client, or anything that knows TCP.</p>
<p>You need to serve assets to your users over HTTP, but you also need to provide them with streams for bi-directional messaging. We can accomplish this in a single Node.js server app!</p>
<p><iframe title="Node.js WebSocket Programming Tutorial with JavaScript" width="500" height="281" src="https://www.youtube.com/embed/YaJbc7s1ROg?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<p>The code from the video, and also this article is available in my <a href="https://github.com/ajb413/nodejs-websocket-examples" target="_blank" rel="noopener noreferrer">Node.js WebSocket Examples GitHub Repository</a>.</p>
<p>First we&#8217;ll go over some plain socket code, followed by WebSocket code. If you already serve assets with something like <a href="https://expressjs.com/" target="_blank" rel="noopener noreferrer">Express.js</a>, <a href="https://hapijs.com/" target="_blank" rel="noopener noreferrer">Hapi</a>, or the <a href="https://nodejs.org/api/http.html" target="_blank" rel="noopener noreferrer">native Node.js HTTP library</a>, we can jump into the socket code.</p>
<h3>Socket Server JavaScript Code</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="js">// Node.js socket server script
const net = require('net');

// Create a server object
const server = net.createServer((socket) =&gt; {
  socket.on('data', (data) =&gt; {
    console.log(data.toString());
  });

  socket.write('SERVER: Hello! This is server speaking.\n');
  socket.end('SERVER: Closing connection now.\n');
}).on('error', (err) =&gt; {
  console.error(err);
});

// Open server on port 9898
server.listen(9898, () =&gt; {
  console.log('opened server on', server.address().port);
});
</pre>
<p>This script runs a Node.js socket server on port 9898. Whenever a client connects to this server app (IP_ADDRESS:9898) the server sends the client a string over the open socket. It says &#8220;SERVER: Hello! This is server speaking.&#8221; Whenever the client sends some data to the server, the Node.js script logs the contents in the &#8216;data&#8217; event handler.</p>
<h3>Socket Client JavaScript Code</h3>
<p>Here we have our Node.js socket client script, which can connect to the Node.js socket server above.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">// Node.js socket client script
const net = require('net');

// Connect to a server @ port 9898
const client = net.createConnection({ port: 9898 }, () =&gt; {
  console.log('CLIENT: I connected to the server.');
  client.write('CLIENT: Hello this is client!');
});

client.on('data', (data) =&gt; {
  console.log(data.toString());
  client.end();
});

client.on('end', () =&gt; {
  console.log('CLIENT: I disconnected from the server.');
});
</pre>
<p>The client script attempts to connect to localhost:9898. If the connection succeeds, then the client sends a string to the server over the open socket. It says &#8220;CLIENT: Hello this is client!&#8221; Whenever the server sends some data to the client, the client logs it in the &#8216;data&#8217; event handler.</p>
<p>This is what the output looks like for client and server Node.js socket scripts running on the command line.</p>
<img class=" wp-image-45294 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/08/nodejs-socket-client-server-scripts-command-line.png" alt="Node.js Socket Server and Client Interaction on the Command Line" width="783" height="305" />
<h2>Node.js WebSocket Example</h2>
<p>Writing socket code is fun, but when you&#8217;re trying to implement it in a web browser, it&#8217;s kind of complicated. This issue has been addressed by all major browsers in their action to support the <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" target="_blank" rel="noopener noreferrer">WebSocket</a> protocol out of the box! This way, web pages that use sockets can load really fast because the front end libraries for handling the protocol are already in the browser applications. No need to fetch big JS libraries whenever a user visits your realtime app web page.</p>
<h3>Node.js WebSocket Server</h3>
<p>Let&#8217;s swap out our Node.js socket server code for WebSocket server code! This way, we will be able to easily serve our web browser users. We&#8217;ll go over some vanilla JS for WebSockets that can be implemented in something like a React.js application.</p>
<p>This code uses the Node.js native &#8220;http&#8221; library and a 3rd party <a href="https://www.npmjs.com/package/websocket" target="_blank" rel="noopener noreferrer">WebSocket NPM package</a> to create a WebSocket server. It has the same functionality as the socket script we wrote earlier. This time, we are using the official WebSocket protocol to bi-directionally send our data between client and server.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">// Node.js WebSocket server script
const http = require('http');
const WebSocketServer = require('websocket').server;

const server = http.createServer();
server.listen(9898);

const wsServer = new WebSocketServer({
    httpServer: server
});

wsServer.on('request', function(request) {
    const connection = request.accept(null, request.origin);

    connection.on('message', function(message) {
      console.log('Received Message:', message.utf8Data);
      connection.sendUTF('Hi this is WebSocket server!');
    });
    connection.on('close', function(reasonCode, description) {
        console.log('Client has disconnected.');
    });
});
</pre>
<h3>Node.js WebSocket Browser Client</h3>
<p>Next, we have our HTML file that loads up in client web browsers. Notice that the WebSocket class in the browser JS has no declaration. This is because modern browsers give developers automatic access to this class in their front-end JavaScript!</p>
<pre class="EnlighterJSRAW" data-enlighter-language="html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;WebSocket Playground&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;/body&gt;
&lt;script&gt;

const ws = new WebSocket('ws://localhost:9898/');

ws.onopen = function() {
    console.log('WebSocket Client Connected');
    ws.send('Hi this is web client.');
};

ws.onmessage = function(e) {
  console.log("Received: '" + e.data + "'");
};

&lt;/script&gt;
&lt;/html&gt;
</pre>
<p>We can get our fun client-server handshake example going fast! Here&#8217;s what the output for the server script and the web browser JS console look like:</p>
<img class="wp-image-45296 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/08/nodejs-socket-programming-client-server-example.png" alt="Node.js WebSocket Full Stack App" width="644" height="385" />
<h2>Peer-to-Peer Message Passing</h2>
<p>The above samples are intuitive code implementations for realtime application development. What if we want to stream data from user to user? What if we want to do this without implementing the complicated routing logic on our server to connect two or more users? We can accomplish all of this cheaply, securely, and without having to spin-up expensive infrastructure.</p>
<p>We have access to awesome, hosted, realtime infrastructure with PubNub. We can infinitely scale to any user volume. PubNub offers low cost, transaction-based pricing with easy to use messaging APIs. Let&#8217;s take a look at an example for peer-to-peer messaging. By the way, this can also be implemented to stream data from client to server, or server to client, in addition to peer-to-peer.</p>
<p><strong>Before you try the following scripts</strong> you must get your free <strong>PubNub API keys</strong>. They work for up to 1 million free transactions per month, forever. Use this form to get <strong>free</strong> API keys right now.</p>
<p><iframe style="width: 100%; min-height: 450px;" src="https://pubsub-quickstart-app.pubnub.com/signup">Your browser does not support iframes.</iframe></p>
<h3>PubNub Data Streaming</h3>
<p>We can bi-directionally send data between services, clients, or server apps using the PubNub global data stream network. There is an SDK for every popular language and device. Here is the basic browser JS or Node.js code for utilizing the Pub/Sub network. This publishes a message whenever the user hits the <strong>return key</strong>.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">const PubNub = require('pubnub'); // or in browser: &lt;script src="https://cdn.pubnub.com/sdk/javascript/pubnub.4.24.4.js"&gt;&lt;/script&gt;

const pubnub = new PubNub({
    publishKey: 'your_pubnub_publish_api_key_here',
    subscribeKey: 'your_pubnub_subscribe_api_key_here'
});

pubnub.subscribe({
    channels: ['my_channel']
});

pubnub.addListener({
    message: (pubnubMessage) =&gt; {
        console.log('New Message:', pubnubMessage.message);
    }
});

// Use Control + C to end the program
process.stdin.on('data', (key) =&gt; {
    // When the user presses the return key
    if (key.toString() === '\n') {
        pubnub.publish({
            message: 'Hello from client 1!',
            channel: 'my_channel'
        });
    }
});
</pre>
<p>Note that the &#8220;process&#8221; object <strong>cannot be accessed in web browser JS</strong>, but a similar key press event handler can accomplish the same functionality.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">object.addEventListener('keypress',(event) =&gt; {});</pre>
<h3>PubNub Node.js SDK</h3>
<p>Here is the <a href="https://www.pubnub.com/docs/web-javascript/pubnub-javascript-sdk">documentation for the PubNub JavaScript SDK</a>.</p>
<p>When we execute the above script in <strong>2 terminal windows</strong>, we can see <a href="https://www.pubnub.com/features/pub-sub-messaging/">realtime Pub/Sub</a> in action. I made a second script with the same code, except the published message indicates that it comes from client number &#8220;2.&#8221; Be sure to install the PubNub Node.js SDK before you try executing the scripts on your command line.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">npm install pubnub</pre>
<img class="wp-image-45305 aligncenter" src="https://www.pubnub.com/wp-content/uploads/2019/08/pubnub-pub-sub-messaging-example-nodejs-javascript.png" alt="PubNub Node.js Pub/Sub API Example Screenshot" width="682" height="366" />
<p>That&#8217;s all there is to it. I hope you were able to glean some valuable insights from this peer-to-peer, client-to-server, and server-to-client WebSocket data streaming tutorial. Please reach out to us at <a href="mailto:devrel@pubnub.com">devrel@pubnub.com</a> if you need assistance or have some questions about building a realtime application. We love hearing your ideas!</p>
<p>For more on implementing JavaScript with PubNub, take a look at our React Native blog post tutorials for <a href="https://www.pubnub.com/blog/realtime-geo-tracking-app-react-native/">realtime geolocation tracking</a>, a <a href="https://www.pubnub.com/blog/building-a-chat-app-with-react-native-and-pubnub-part-one-messaging/">realtime chat app</a>, and more! There is also a blog post about <a href="https://www.pubnub.com/blog/socket-programming-in-python-client-server-p2p/">socket programming in Python</a>. Thanks for reading! If you liked this post, subscribe to our newsletter!</p><p>The post <a  href="https://www.pubnub.com/blog/nodejs-websocket-programming-examples/">Node.js WebSocket Programming Examples</a> appeared first on <a  href="https://www.pubnub.com">PubNub</a>.</p>
]]></content:encoded>
			</item>
	</channel>
</rss>
