source: trunk/webmap/html/js/ros.js @ 21

Last change on this file since 21 was 15, checked in by wcaarls, 12 years ago

Imported webmap at revision 1169

File size: 5.5 KB
Line 
1/* A simple javascript websockets client for the rosbridge v2.0 protocol.
2 *
3 * An AMD-compatible version of ros.js is provided as ros_amd.js
4 *
5 * A backwards-compatible ros.js is provided as ros_compatible.js
6 *
7 * Recommended practice is to use ros.js
8 *
9 * **/
10
11var Bridge = function(url) {
12    // Initialize internal variables
13    this.service_handlers = {};
14    this.service_seed = 0;
15    this.subscription_handlers = {};
16   
17    // Ensure that JSON and WebSocket are available.  Thrown an exception if not
18    if (!WebSocket && MozWebSocket) {
19        WebSocket = MozWebSocket;
20    }
21    if (!WebSocket) {
22        throw "Browser does not support WebSockets";
23    }
24    if (!JSON) {
25        throw "Browser does not support JSON";
26    }
27   
28    // Create the connection
29    this.socket = new WebSocket(url);
30   
31    var self = this
32    this.socket.onmessage = function() {
33        self.receiveMessage.apply(self, arguments);
34        self.onMessage.apply(self, arguments);
35    }
36    this.socket.onerror = function() {
37        self.onError.apply(self, arguments);
38    }
39    this.socket.onopen = function() {
40        self.onOpen.apply(self, arguments);
41    }
42    this.socket.onclose = function() {
43        self.onClose.apply(self, arguments);
44    }
45}
46
47Bridge.prototype.send = function(op, id, msg) {
48    msg.op = op;
49    if (id != null) {
50        msg.id = id;
51    }
52    this.socket.send(JSON.stringify(msg));
53}
54
55Bridge.prototype.advertise = function(topic, type, /*optional*/ id) {
56    this.send("advertise", id, {topic: topic, type: type});
57}
58
59Bridge.prototype.unadvertise = function(topic, /*optional*/ id) {
60    this.send("unadvertise", id, {topic: topic});
61}
62
63Bridge.prototype.publish = function(topic, msg, /*optional*/ id) {
64    this.send("publish", id, {topic: topic, msg: msg});
65}
66
67Bridge.prototype.subscribe = function(callback, topic, /*optional*/ type, /*optional*/ throttle_rate,
68      /*optional*/ queue_length, /*optional*/ fragment_size, /*optional*/ compression, /*optional*/ id) {
69    // Construct the message
70    msg = {topic: topic};
71    if (type != null) msg.type = type;
72    if (throttle_rate != null) msg.throttle_rate = throttle_rate;
73    if (queue_length != null) msg.queue_length = queue_length;
74    if (fragment_size != null) msg.fragment_size = fragment_size;
75    if (compression != null) msg.compression = compression;
76   
77    // Send the message
78    this.send("subscribe", id, msg);
79   
80    // Save the callback
81    if (this.subscription_handlers[topic] == null) {
82        this.subscription_handlers[topic] = {};
83    }
84    if (this.subscription_handlers[topic][id] == null) {
85        this.subscription_handlers[topic][id] = [];
86    }
87    this.subscription_handlers[topic][id].push(callback);
88}
89
90Bridge.prototype.unsubscribe = function(topic, /*optional*/ id) {
91    // Send the message
92    this.send("unsubscribe", id, {topic: topic});
93   
94    // Delete callbacks
95    if (this.subscription_handlers[topic] && this.subscription_handlers[topic][id]) {
96        delete this.subscription_handlers[topic][id];
97    }
98    if (id==null || Object.keys(this.subscription_handlers[topic]).length == 0) {
99        delete this.subscription_handlers[topic];
100    }
101}
102
103Bridge.prototype.callService = function(callback, service, /*optional*/ args,
104        /*optional*/ fragment_size, /*optional*/ compression, /*optional*/ id) {
105    // Construct the message
106    msg = {service: service};
107    if (args != null) msg.args = args;
108    if (fragment_size != null) msg.fragment_size = fragment_size;
109    if (compression != null) msg.compression = compression;
110   
111    // Generate an ID for service calls
112    if (id == null) {
113        id = this.service_seed;
114        this.service_seed++;
115    }
116   
117    // Send the message
118    this.send("call_service", id, msg);
119   
120    // Save the callback
121    if (this.service_handlers[service] == null) {
122        this.service_handlers[service] = {};
123    }
124    this.service_handlers[service][id] = callback;
125}
126
127Bridge.prototype.receiveMessage = function(event) {
128    msg = JSON.parse(event.data);
129   
130    switch(msg.op) {
131        case "publish": this.onPublish(msg); break;
132        case "service_response": this.onServiceResponse(msg); break;
133    }
134}
135
136Bridge.prototype.onOpen = function(event) {}
137Bridge.prototype.onClose = function(event) {}
138Bridge.prototype.onError = function(event) {}
139Bridge.prototype.onMessage = function(event) {}
140
141Bridge.prototype.onPublish = function(message) {
142    // Extract message details
143    topic = message.topic;
144    msg = message.msg;
145   
146    // Copy the callbacks - in case the callback modifies the subscription
147    var callbacks = [];
148    for (var id in this.subscription_handlers[topic]) {
149        callbacks = callbacks.concat(this.subscription_handlers[topic][id]);
150    }
151   
152    // Call all the callbacks
153    for (var i = 0; i < callbacks.length; i++) {
154        try {
155            callbacks[i](msg);
156        } catch (err) {
157            // Best we can do is print the error
158            console.error(err);
159        }
160    }
161}
162
163Bridge.prototype.onServiceResponse = function(response) {
164    // Extract message details
165    service = response.service;
166    values = response.values;
167    id = response.id;
168   
169    // Call the callback and remove it
170    if (this.service_handlers[service] && this.service_handlers[service][id]) {
171        callback = this.service_handlers[service][id];
172        delete this.service_handlers[service][id];
173        if (Object.keys(this.service_handlers[service]).length == 0) {
174            delete this.service_handlers[service];
175        }
176        callback(values);
177    }
178}
179
180var ros = ros || {};
181ros.Bridge = Bridge;
Note: See TracBrowser for help on using the repository browser.