| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 {{+bindTo:partials.standard_nacl_article}} | 
|  | 2 | 
|  | 3 <section id="messaging-system"> | 
|  | 4 <span id="message-system"></span><h1 id="messaging-system"><span id="message-sys
     tem"></span>Messaging System</h1> | 
|  | 5 <div class="contents local topic" id="contents"> | 
|  | 6 <ul class="small-gap"> | 
|  | 7 <li><a class="reference internal" href="#reference-information" id="id2">Referen
     ce information</a></li> | 
|  | 8 <li><p class="first"><a class="reference internal" href="#introduction-to-the-me
     ssaging-system" id="id3">Introduction to the messaging system</a></p> | 
|  | 9 <ul class="small-gap"> | 
|  | 10 <li><a class="reference internal" href="#design-of-the-messaging-system" id="id4
     ">Design of the messaging system</a></li> | 
|  | 11 </ul> | 
|  | 12 </li> | 
|  | 13 <li><p class="first"><a class="reference internal" href="#communication-tasks-in
     -the-hello-world-example" id="id5">Communication tasks in the “Hello, Worl
     d” example</a></p> | 
|  | 14 <ul class="small-gap"> | 
|  | 15 <li><a class="reference internal" href="#javascript-code" id="id6">JavaScript co
     de</a></li> | 
|  | 16 <li><a class="reference internal" href="#native-client-module" id="id7">Native C
     lient module</a></li> | 
|  | 17 </ul> | 
|  | 18 </li> | 
|  | 19 <li><p class="first"><a class="reference internal" href="#messaging-in-javascrip
     t-code-more-details" id="id8">Messaging in JavaScript code: More details.</a></p
     > | 
|  | 20 <ul class="small-gap"> | 
|  | 21 <li><a class="reference internal" href="#setting-up-an-event-listener-and-handle
     r" id="id9">Setting up an event listener and handler</a></li> | 
|  | 22 </ul> | 
|  | 23 </li> | 
|  | 24 <li><p class="first"><a class="reference internal" href="#messaging-in-the-nativ
     e-client-module-more-details" id="id10">Messaging in the Native Client module: M
     ore details.</a></p> | 
|  | 25 <ul class="small-gap"> | 
|  | 26 <li><a class="reference internal" href="#implementing-handlemessage" id="id11">I
     mplementing HandleMessage()</a></li> | 
|  | 27 <li><a class="reference internal" href="#implementing-application-specific-funct
     ions" id="id12">Implementing application-specific functions</a></li> | 
|  | 28 <li><a class="reference internal" href="#sending-messages-back-to-the-javascript
     -code" id="id13">Sending messages back to the JavaScript code</a></li> | 
|  | 29 <li><a class="reference internal" href="#sending-and-receiving-other-pp-var-type
     s" id="id14">Sending and receiving other <code>pp::Var</code> types</a></li> | 
|  | 30 </ul> | 
|  | 31 </li> | 
|  | 32 </ul> | 
|  | 33 </div> | 
|  | 34 <p>This chapter describes the messaging system used to communicate between the | 
|  | 35 JavaScript code and the Native Client module’s C or C++ code in a | 
|  | 36 Native Client application. It introduces the concept of asynchronous | 
|  | 37 programming and the basic steps required to set up a Native Client module | 
|  | 38 that sends messages to and receive messages from JavaScript. This chapter | 
|  | 39 assumes you are familiar with the material presented in the | 
|  | 40 <a class="reference internal" href="/native-client/devguide/coding/application-s
     tructure.html"><em>Application Structure</em></a> chapter.</p> | 
|  | 41 <aside class="note"> | 
|  | 42 The “Hello, World” example for getting started with NaCl is used her
     e to | 
|  | 43 illustrate basic programming techniques. You can find this code in | 
|  | 44 the <code>/getting_started/part2</code> directory in the Native Client SDK downl
     oad. | 
|  | 45 </aside> | 
|  | 46 <section id="reference-information"> | 
|  | 47 <h2 id="reference-information">Reference information</h2> | 
|  | 48 <p>For reference information related to the Pepper messaging API, see the | 
|  | 49 following documentation:</p> | 
|  | 50 <ul class="small-gap"> | 
|  | 51 <li><a class="reference external" href="https://developers.google.com/native-cli
     ent/peppercpp/classpp_1_1_instance">pp::Instance class</a> HandleMessage(), Post
     Message())</li> | 
|  | 52 <li><a class="reference external" href="https://developers.google.com/native-cli
     ent/peppercpp/classpp_1_1_module">pp::Module class</a></li> | 
|  | 53 <li><a class="reference external" href="https://developers.google.com/native-cli
     ent/peppercpp/classpp_1_1_var">pp::Var class</a></li> | 
|  | 54 </ul> | 
|  | 55 </section><section id="introduction-to-the-messaging-system"> | 
|  | 56 <h2 id="introduction-to-the-messaging-system">Introduction to the messaging syst
     em</h2> | 
|  | 57 <p>Native Client modules and JavaScript communicate by sending messages | 
|  | 58 to each other. The most basic form of a message is a string.  Messages | 
|  | 59 support many JavaScript types, including ints, arrays, array buffers, | 
|  | 60 and dictionaries (see <a class="reference external" href="https://developers.goo
     gle.com/native-client/peppercpp/classpp_1_1_var">pp::Var</a>, | 
|  | 61 <a class="reference external" href="https://developers.google.com/native-client/
     peppercpp/classpp_1_1_var_array_buffer">pp:VarArrayBuffer</a>, | 
|  | 62 and the general <a class="reference external" href="https://developers.google.co
     m/native-client/pepperc/struct_p_p_b___messaging__1__0">messaging system documen
     tation</a>). | 
|  | 63 It’s up to you to decide on the type of message and define how to | 
|  | 64 process the messages on both the JavaScript and Native Client | 
|  | 65 side. For the “Hello, World” example, we will work with string-typed | 
|  | 66 messages only.</p> | 
|  | 67 <p>When JavaScript posts a message to the Native Client module, the | 
|  | 68 Pepper <code>HandleMessage()</code> function is invoked on the module | 
|  | 69 side. Similarly, the Native Client module can post a message to | 
|  | 70 JavaScript, and this message triggers a JavaScript event listener for | 
|  | 71 <code>message</code> events in the DOM. (See the W3C specification on | 
|  | 72 <a class="reference external" href="http://www.w3.org/TR/DOM-Level-2-Events/even
     ts.html">Document Object Model Events</a> for more | 
|  | 73 information.) In the “Hello, World” example, the JavaScript function
     s for | 
|  | 74 posting and handling messages are named <code>postMessage()</code> and | 
|  | 75 <code>handleMessage()</code> (but any names could be used). On the Native Client | 
|  | 76 C++ side, the Pepper Library functions for posting and handling | 
|  | 77 messages are:</p> | 
|  | 78 <ul class="small-gap"> | 
|  | 79 <li><code>void pp::Instance::PostMessage(const Var &message)</code></li> | 
|  | 80 <li><code>virtual void pp::Instance::HandleMessage(const Var &message)</code
     ></li> | 
|  | 81 </ul> | 
|  | 82 <p>If you want to receive messages from JavaScript, you need to implement the | 
|  | 83 <code>pp::Instance::HandleMessage()</code> function in your Native Client module
     .</p> | 
|  | 84 <section id="design-of-the-messaging-system"> | 
|  | 85 <h3 id="design-of-the-messaging-system">Design of the messaging system</h3> | 
|  | 86 <p>The Native Client messaging system is analogous to the system used by | 
|  | 87 the browser to allow web workers to communicate (see the <a class="reference ext
     ernal" href="http://www.w3.org/TR/workers">W3 web | 
|  | 88 worker specification</a>).  The Native | 
|  | 89 Client messaging system is designed to keep the web page responsive while the | 
|  | 90 Native Client module is performing potentially heavy processing in the | 
|  | 91 background. When JavaScript sends a message to the Native Client | 
|  | 92 module, the <code>postMessage()</code> call returns as soon as it sends its mess
     age | 
|  | 93 to the Native Client module. The JavaScript does not wait for a reply | 
|  | 94 from Native Client, thus avoiding bogging down the main JavaScript | 
|  | 95 thread. On the JavaScript side, you set up an event listener to | 
|  | 96 respond to the message sent by the Native Client module when it has | 
|  | 97 finished the requested processing and returns a message.</p> | 
|  | 98 <p>This asynchronous processing model keeps the main thread free while | 
|  | 99 avoiding the following problems:</p> | 
|  | 100 <ul class="small-gap"> | 
|  | 101 <li>The JavaScript engine hangs while waiting for a synchronous call to return.<
     /li> | 
|  | 102 <li>The browser pops up a dialog when a JavaScript entry point takes longer | 
|  | 103 than a few moments.</li> | 
|  | 104 <li>The application hangs while waiting for an unresponsive Native Client module
     .</li> | 
|  | 105 </ul> | 
|  | 106 </section></section><section id="communication-tasks-in-the-hello-world-example"
     > | 
|  | 107 <h2 id="communication-tasks-in-the-hello-world-example">Communication tasks in t
     he “Hello, World” example</h2> | 
|  | 108 <p>The following sections describe how the “Hello, World” example po
     sts | 
|  | 109 and handles messages on both the JavaScript side and the Native Client | 
|  | 110 side of the application.</p> | 
|  | 111 <section id="javascript-code"> | 
|  | 112 <h3 id="javascript-code">JavaScript code</h3> | 
|  | 113 <p>The JavaScript code and HTML in the “Hello, World” example can be | 
|  | 114 found in the <code>example.js</code>, <code>common.js</code>, and <code>index.ht
     ml</code> files. | 
|  | 115 The important steps are:</p> | 
|  | 116 <ol class="arabic simple"> | 
|  | 117 <li>Sets up an event listener to listen for <code>message</code> events from the | 
|  | 118 Native Client module.</li> | 
|  | 119 <li>Implements an event handler that the event listener invokes to handle | 
|  | 120 incoming <code>message</code> events.</li> | 
|  | 121 <li>Calls <code>postMessage()</code> to communicate with the NaCl module, | 
|  | 122 after the page loads.</li> | 
|  | 123 </ol> | 
|  | 124 <section id="step-1-from-common-js"> | 
|  | 125 <h4 id="step-1-from-common-js">Step 1: From common.js</h4> | 
|  | 126 <pre class="prettyprint"> | 
|  | 127 function attachDefaultListeners() { | 
|  | 128   // The NaCl module embed is created within the listenerDiv | 
|  | 129   var listenerDiv = document.getElementById('listener'); | 
|  | 130   // ... | 
|  | 131 | 
|  | 132   // register the handleMessage function as the message event handler. | 
|  | 133   listenerDiv.addEventListener('message', handleMessage, true); | 
|  | 134   // ... | 
|  | 135 } | 
|  | 136 </pre> | 
|  | 137 </section><section id="step-2-from-example-js"> | 
|  | 138 <h4 id="step-2-from-example-js">Step 2: From example.js</h4> | 
|  | 139 <pre class="prettyprint"> | 
|  | 140 // This function is called by common.js when a message is received from the | 
|  | 141 // NaCl module. | 
|  | 142 function handleMessage(message) { | 
|  | 143   // In the example, we simply log the data that's received in the message. | 
|  | 144   var logEl = document.getElementById('log'); | 
|  | 145   logEl.textContent += message.data; | 
|  | 146 } | 
|  | 147 | 
|  | 148 // In the index.html we have set up the appropriate divs: | 
|  | 149 <body {attrs}> | 
|  | 150   <!-- ... --> | 
|  | 151   <div id="listener"></div> | 
|  | 152   <div id="log"></div> | 
|  | 153 </body> | 
|  | 154 </pre> | 
|  | 155 </section><section id="step-3-from-example-js"> | 
|  | 156 <h4 id="step-3-from-example-js">Step 3: From example.js</h4> | 
|  | 157 <pre class="prettyprint"> | 
|  | 158 // From example.js, Step 3: | 
|  | 159 function moduleDidLoad() { | 
|  | 160   // After the NaCl module has loaded, common.naclModule is a reference to the | 
|  | 161   // NaCl module's <embed> element. | 
|  | 162   // | 
|  | 163   // postMessage sends a message to it. | 
|  | 164   common.naclModule.postMessage('hello'); | 
|  | 165 } | 
|  | 166 </pre> | 
|  | 167 </section></section><section id="native-client-module"> | 
|  | 168 <h3 id="native-client-module">Native Client module</h3> | 
|  | 169 <p>The C++ code in the Native Client module of the “Hello, World” ex
     ample:</p> | 
|  | 170 <ol class="arabic simple"> | 
|  | 171 <li>Implements <code>pp::Instance::HandleMessage()</code> to handle messages sen
     t | 
|  | 172 by the JavaScript.</li> | 
|  | 173 <li>Processes incoming messages. This example simply checks that JavaScript | 
|  | 174 has sent a “hello” message and not some other message.</li> | 
|  | 175 <li>Calls <code>PostMessage()</code> to send an acknowledgement back to the | 
|  | 176 JavaScript code.  The acknowledgement is a string in the form of a <code>Var</co
     de> | 
|  | 177 that the JavaScript code can process.  In general, a <code>pp::Var</code> can be | 
|  | 178 several JavaScript types, see the | 
|  | 179 <a class="reference external" href="https://developers.google.com/native-client/
     pepperc/struct_p_p_b___messaging__1__0">messaging system documentation</a>.</li> | 
|  | 180 </ol> | 
|  | 181 <pre class="prettyprint"> | 
|  | 182 class HelloTutorialInstance : public pp::Instance { | 
|  | 183  public: | 
|  | 184   // ... | 
|  | 185 | 
|  | 186   // === Step 1: Implement the HandleMessage function. === | 
|  | 187   virtual void HandleMessage(const pp::Var& var_message) { | 
|  | 188 | 
|  | 189     // === Step 2: Process the incoming message. === | 
|  | 190     // Ignore the message if it is not a string. | 
|  | 191     if (!var_message.is_string()) | 
|  | 192       return; | 
|  | 193 | 
|  | 194     // Get the string message and compare it to "hello". | 
|  | 195     std::string message = var_message.AsString(); | 
|  | 196     if (message == kHelloString) { | 
|  | 197       // === Step 3: Send the reply. === | 
|  | 198       // If it matches, send our response back to JavaScript. | 
|  | 199       pp::Var var_reply(kReplyString); | 
|  | 200       PostMessage(var_reply); | 
|  | 201     } | 
|  | 202   } | 
|  | 203 }; | 
|  | 204 </pre> | 
|  | 205 </section></section><section id="messaging-in-javascript-code-more-details"> | 
|  | 206 <h2 id="messaging-in-javascript-code-more-details">Messaging in JavaScript code:
      More details.</h2> | 
|  | 207 <p>This section describes in more detail the messaging system code in the | 
|  | 208 JavaScript portion of the “Hello, World” example.</p> | 
|  | 209 <section id="setting-up-an-event-listener-and-handler"> | 
|  | 210 <h3 id="setting-up-an-event-listener-and-handler">Setting up an event listener a
     nd handler</h3> | 
|  | 211 <p>The following JavaScript code sets up an event listener for messages | 
|  | 212 posted by the Native Client module. It then defines a message handler | 
|  | 213 that simply logs the content of messages received from the module.</p> | 
|  | 214 <section id="setting-up-the-message-handler-on-load"> | 
|  | 215 <h4 id="setting-up-the-message-handler-on-load">Setting up the ‘message
     217; handler on load</h4> | 
|  | 216 <pre class="prettyprint"> | 
|  | 217 // From common.js | 
|  | 218 | 
|  | 219 // Listen for the DOM content to be loaded. This event is fired when | 
|  | 220 // parsing of the page's document has finished. | 
|  | 221 document.addEventListener('DOMContentLoaded', function() { | 
|  | 222   var body = document.body; | 
|  | 223   // ... | 
|  | 224   var loadFunction = common.domContentLoaded; | 
|  | 225   // ... set up parameters ... | 
|  | 226   loadFunction(...); | 
|  | 227 } | 
|  | 228 | 
|  | 229 // This function is exported as common.domContentLoaded. | 
|  | 230 function domContentLoaded(...) { | 
|  | 231   // ... | 
|  | 232   if (common.naclModule == null) { | 
|  | 233     // ... | 
|  | 234     attachDefaultListeners(); | 
|  | 235     // initialize common.naclModule ... | 
|  | 236   } else { | 
|  | 237     // ... | 
|  | 238   } | 
|  | 239 } | 
|  | 240 | 
|  | 241 function attachDefaultListeners() { | 
|  | 242   var listenerDiv = document.getElementById('listener'); | 
|  | 243   // ... | 
|  | 244   listenerDiv.addEventListener('message', handleMessage, true); | 
|  | 245   // ... | 
|  | 246 } | 
|  | 247 </pre> | 
|  | 248 </section><section id="implementing-the-handler"> | 
|  | 249 <h4 id="implementing-the-handler">Implementing the handler</h4> | 
|  | 250 <pre class="prettyprint"> | 
|  | 251 // From example.js | 
|  | 252 function handleMessage(message) { | 
|  | 253   var logEl = document.getElementById('log'); | 
|  | 254   logEl.textContent += message.data; | 
|  | 255 } | 
|  | 256 </pre> | 
|  | 257 <p>Note that the <code>handleMessage()</code> function is handed a message_event | 
|  | 258 containing <code>data</code> that you can display or manipulate in JavaScript. T
     he | 
|  | 259 “Hello, World” application simply logs this data to the <code>log</c
     ode> div.</p> | 
|  | 260 </section></section></section><section id="messaging-in-the-native-client-module
     -more-details"> | 
|  | 261 <h2 id="messaging-in-the-native-client-module-more-details">Messaging in the Nat
     ive Client module: More details.</h2> | 
|  | 262 <p>This section describes in more detail the messaging system code in | 
|  | 263 the Native Client module portion of the “Hello, World” example.</p> | 
|  | 264 <section id="implementing-handlemessage"> | 
|  | 265 <h3 id="implementing-handlemessage">Implementing HandleMessage()</h3> | 
|  | 266 <p>If you want the Native Client module to receive and handle messages | 
|  | 267 from JavaScript, you need to implement a <code>HandleMessage()</code> function | 
|  | 268 for your module’s <code>pp::Instance</code> class. The | 
|  | 269 <code>HelloWorldInstance::HandleMessage()</code> function examines the message | 
|  | 270 posted from JavaScript. First it examines that the type of the | 
|  | 271 <code>pp::Var</code> is indeed a string (not a double, etc.). It then | 
|  | 272 interprets the data as a string with <code>var_message.AsString()</code>, and | 
|  | 273 checks that the string matches <code>kHelloString</code>. After examining the | 
|  | 274 message received from JavaScript, the code calls <code>PostMessage()</code> to | 
|  | 275 send a reply message back to the JavaScript side.</p> | 
|  | 276 <pre class="prettyprint"> | 
|  | 277 namespace { | 
|  | 278 | 
|  | 279 // The expected string sent by the JavaScript. | 
|  | 280 const char* const kHelloString = "hello"; | 
|  | 281 // The string sent back to the JavaScript code upon receipt of a message | 
|  | 282 // containing "hello". | 
|  | 283 const char* const kReplyString = "hello from NaCl"; | 
|  | 284 | 
|  | 285 }  // namespace | 
|  | 286 | 
|  | 287 class HelloTutorialInstance : public pp::Instance { | 
|  | 288  public: | 
|  | 289   // ... | 
|  | 290   virtual void HandleMessage(const pp::Var& var_message) { | 
|  | 291     // Ignore the message if it is not a string. | 
|  | 292     if (!var_message.is_string()) | 
|  | 293       return; | 
|  | 294 | 
|  | 295     // Get the string message and compare it to "hello". | 
|  | 296     std::string message = var_message.AsString(); | 
|  | 297     if (message == kHelloString) { | 
|  | 298       // If it matches, send our response back to JavaScript. | 
|  | 299       pp::Var var_reply(kReplyString); | 
|  | 300       PostMessage(var_reply); | 
|  | 301     } | 
|  | 302   } | 
|  | 303 }; | 
|  | 304 </pre> | 
|  | 305 </section><section id="implementing-application-specific-functions"> | 
|  | 306 <h3 id="implementing-application-specific-functions">Implementing application-sp
     ecific functions</h3> | 
|  | 307 <p>While the “Hello, World” example is very simple, your Native Clie
     nt | 
|  | 308 module will likely include application-specific functions to perform | 
|  | 309 custom tasks in response to messages. For example the application | 
|  | 310 could be a compression and decompression service (two functions | 
|  | 311 exported).  The application could set up an application-specific | 
|  | 312 convention that messages coming from JavaScript are colon-separated | 
|  | 313 pairs of the form <code><command>:<data></code>.  The Native Client 
     module | 
|  | 314 message handler can then split the incoming string along the <code>:</code> | 
|  | 315 character to determine which command to execute.  If the command is | 
|  | 316 “compress”, then data to process is an uncompressed string.  If the | 
|  | 317 command is “uncompress”, then data to process is an already-compress
     ed | 
|  | 318 string. After processing the data asynchronously, the application then | 
|  | 319 returns the result to JavaScript.</p> | 
|  | 320 </section><section id="sending-messages-back-to-the-javascript-code"> | 
|  | 321 <h3 id="sending-messages-back-to-the-javascript-code">Sending messages back to t
     he JavaScript code</h3> | 
|  | 322 <p>The Native Client module sends messages back to the JavaScript code | 
|  | 323 using <code>PostMessage()</code>. The Native Client module always returns | 
|  | 324 its values in the form of a <code>pp::Var</code> that can be processed by the | 
|  | 325 browser’s JavaScript. In this example, the message is posted at the | 
|  | 326 end of the Native Client module’s <code>HandleMessage()</code> function:</
     p> | 
|  | 327 <pre class="prettyprint"> | 
|  | 328 PostMessage(var_reply); | 
|  | 329 </pre> | 
|  | 330 </section><section id="sending-and-receiving-other-pp-var-types"> | 
|  | 331 <h3 id="sending-and-receiving-other-pp-var-types">Sending and receiving other <c
     ode>pp::Var</code> types</h3> | 
|  | 332 <p>Besides strings, <code>pp::Var</code> can represent other types of JavaScript | 
|  | 333 objects. For example, messages can be JavaScript objects. These | 
|  | 334 richer types can make it easier to implement an application’s | 
|  | 335 messaging protocol.</p> | 
|  | 336 <p>To send a dictionary from the NaCl module to JavaScript simply create | 
|  | 337 a <code>pp::VarDictionary</code> and then call <code>PostMessage</code> with the | 
|  | 338 dictionary.</p> | 
|  | 339 <pre class="prettyprint"> | 
|  | 340 pp::VarDictionary dictionary; | 
|  | 341 dictionary.Set(pp::Var("command"), pp::Var(next_command)); | 
|  | 342 dictionary.Set(pp::Var("param_int"), pp::Var(123)); | 
|  | 343 pp::VarArray an_array; | 
|  | 344 an_array.Set(0, pp::Var("string0")); | 
|  | 345 an_array.Set(1, pp::Var("string1")) | 
|  | 346 dictionary.Set(pp::Var("param_array"), an_array); | 
|  | 347 PostMessage(dictionary); | 
|  | 348 </pre> | 
|  | 349 <p>Here is how to create a similar object in JavaScript and send it to | 
|  | 350 the NaCl module:</p> | 
|  | 351 <pre class="prettyprint"> | 
|  | 352 var dictionary = { | 
|  | 353   command: next_command, | 
|  | 354   param_int: 123, | 
|  | 355   param_array: ['string0', 'string1'] | 
|  | 356 } | 
|  | 357 nacl_module.postMessage(dictionary); | 
|  | 358 </pre> | 
|  | 359 <p>To receive a dictionary-typed message in the NaCl module, test that | 
|  | 360 the message is truly a dictionary type, then convert the message | 
|  | 361 with the <code>pp::VarDictionary</code> class.</p> | 
|  | 362 <pre class="prettyprint"> | 
|  | 363 virtual void HandleMessage(const pp::Var& var) { | 
|  | 364   if (var.is_dictionary()) { | 
|  | 365     pp::VarDictionary dictionary(var); | 
|  | 366     // Use the dictionary | 
|  | 367     pp::VarArray keys = dictionary.GetKeys(); | 
|  | 368     // ... | 
|  | 369   } else { | 
|  | 370     // ... | 
|  | 371   } | 
|  | 372 } | 
|  | 373 </pre> | 
|  | 374 </section></section></section> | 
|  | 375 | 
|  | 376 {{/partials.standard_nacl_article}} | 
| OLD | NEW | 
|---|