QiMessaging JavaScript 1.0¶
Warning
Version 1.0 of the library is now deprecated. Please see How to migrate from version 1.0 to 2.
Introduction¶
QiMessaging provides JavaScript bindings to use QiMessaging services (modules) in a web browser. It allows you to build HTML5 applications for your robot.
The library was designed to be asynchronous. Most function calls return a Deferred object, as specified by jQuery, but reimplemented to avoid shipping the whole library. Socket.IO is used to provide bidirectional communication between the robot and the browser. You may want to get more familiar with these libraries before going further.
Getting started¶
The client page requires the inclusion of QiMessaging which is hosted on the robot.
<script src="/libs/qimessaging/1.0/qimessaging.js"></script>
QiSession¶
The bindings provide only one class: QiSession
. This object connects to the
robot and gets proxies to services.
If the page is hosted on the robot, the constructor does not need any argument.
If the page is not served by the robot, you may pass the hostname or IP of
the robot you want to connect to (e.g. "192.168.0.5"
, "nao.local"
,
etc.).
var session = new QiSession();
Once the connection is established, two methods are available: socket()
and
service()
.
socket()¶
This function will return the underlying Socket.Io object. It is used to deal with low-level socket events.
session.socket().on('connect', function () {
console.log('QiSession connected!');
// now you can start using your QiSession
}).on('disconnect', function () {
console.log('QiSession disconnected!');
});
service()¶
You can call this function to get a JavaScript proxy to any service, also known as modules. Services are JavaScript bound objects providing corresponding NAOqi APIs through Calls and Signals.
In case of success, this method calls the done()
callback with an
object corresponding to the requested service. Otherwise, the fail()
callback is triggered.
session.service("ALTextToSpeech").done(function (tts) {
// tts is a proxy to the ALTextToSpeech service
}).fail(function (error) {
console.log("An error occurred:", error);
});
Using services¶
Services are JavaScript object exposing methods and signals.
Calls¶
Service calls are only JavaScript function calls returning Deferred
promises. They are entirely
asynchronous. As previously explained, done()
and fail()
callbacks
will be triggered upon successful completion or not.
tts.getLanguage().done(function (lang) {
console.log("I speak " + lang);
}).fail(function (error) {
console.log("An error occurred: " + error);
});
Signals¶
Signals are JavaScript objects inside a service, that provide two methods,
connect()
and disconnect()
, respectively to subscribe and unsubscribe.
The first one will return an id that must be used by the second one for
unregistration.
The example below connects to a signal, and once fired, disconnects.
var signalLink;
var serviceDirectory;
function onServiceAdded(serviceId, serviceName)
{
console.log("New service", serviceId, serviceName);
serviceDirectory.serviceAdded.disconnect(signalLink);
}
session.service("ServiceDirectory").done(function (sd) {
serviceDirectory = sd;
serviceDirectory.serviceAdded.connect(onServiceAdded).done(function (link) {
signalLink = link;
}).fail(function (error) {
console.log("An error occurred: " + error);
});
});
Compatibility between Signals and ALMemory¶
ALMemory events cannot be directly used as QiMessaging signals. An extra step
is needed, where ALMemory events are converted to signals using
ALMemory::subscriber
.
session.service("ALMemory").done(function (ALMemory) {
ALMemory.subscriber("FrontTactilTouched").done(function (subscriber) {
// subscriber.signal is a signal associated to "FrontTactilTouched"
subscriber.signal.connect(function (state) {
console.log(state == 1 ? "You just touched my head!" : "Bye bye!");
});
});
});
How to migrate from version 1.0 to 2¶
JavaScript SDK is now available. The former 1.0 version is now deprecated and no longer maintained. You are strongly encouraged to port your code to the new library. This quick guide will help you transition.
Library inclusion¶
You must first change the qimessaging.js
inclusion.
<!-- QiMessaging 1.0 -->
<script src="/libs/qimessaging/1.0/qimessaging.js"></script>
<!-- QiMessaging 2 -->
<script src="/libs/qimessaging/2/qimessaging.js"></script>
QiSession creation¶
Considering a QiSession
connected to host
with the connected
and
disconnected
callbacks registered,
var host = "192.168.0.1";
function connected() {
console.log("connected");
}
function disconnected() {
console.log("disconnected");
}
here is the session creation in 1.0 and how it translates into version 2:
// QiMessaging 1.0
var session = new QiSession(host);
session.socket().on("connect", connected);
session.socket().on("disconnect", disconnected);
// QiMessaging 2
QiSession(function(session) {
connected();
}, disconnected, host);
The first callback will be fired once the QiSession
is connected, and the
second one upon its disconnection.
Please note the created QiSession
is not returned anymore, but given to the
first callback instead. This prevents using the session before it is actually
connected.
As in 1.0, the host
parameter still defaults to window.location.host
if
not given. It cannot accept any protocol, ie. 192.168.0.1
and not
http://192.168.0.1
.
Removal of socket()¶
The socket()
method of QiSession
was removed, so as to ease backward
compatibility maintenance.
Deferred and Promise¶
In version 2, jQuery-like Deferred were removed in favor of native ECMAScript 6 Promise/A+, which are now widely available.
If you are currently developing for an older browser, you can use a polyfill such as:
<script src="https://www.promisejs.org/polyfills/promise-6.0.0.min.js"></script>
As jQuery’s Deferred do not implement Promises/A+, you will also have to adapt your API calls as follows:
// QiMessaging 1.0
proxy.method().done(success).fail(error);
// QiMessaging 2
proxy.method().then(success, error);
Binary buffer serialization¶
Binary data used to be serialized as base64 strings. Buffers are now received
as Array
of unsigned bytes, which also means atob()
shouldn’t be called
anymore.