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