Skip to content

Commit 46d184e

Browse files
Faibkjihoonl
authored andcommitted
Added an option to resubscribe/readvertise topic on close event, And add dispose() in ActionClient, TFClient (RobotWebTools#267)
* dispose() in Actionclient and TFClient * Topic reconnection, closes RobotWebTools#246
1 parent b47beb5 commit 46d184e

File tree

5 files changed

+137
-20
lines changed

5 files changed

+137
-20
lines changed

build/roslib.js

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -890,19 +890,19 @@ function ActionClient(options) {
890890
var receivedStatus = false;
891891

892892
// create the topics associated with actionlib
893-
var feedbackListener = new Topic({
893+
this.feedbackListener = new Topic({
894894
ros : this.ros,
895895
name : this.serverName + '/feedback',
896896
messageType : this.actionName + 'Feedback'
897897
});
898898

899-
var statusListener = new Topic({
899+
this.statusListener = new Topic({
900900
ros : this.ros,
901901
name : this.serverName + '/status',
902902
messageType : 'actionlib_msgs/GoalStatusArray'
903903
});
904904

905-
var resultListener = new Topic({
905+
this.resultListener = new Topic({
906906
ros : this.ros,
907907
name : this.serverName + '/result',
908908
messageType : this.actionName + 'Result'
@@ -926,7 +926,7 @@ function ActionClient(options) {
926926

927927
// subscribe to the status topic
928928
if (!this.omitStatus) {
929-
statusListener.subscribe(function(statusMessage) {
929+
this.statusListener.subscribe(function(statusMessage) {
930930
receivedStatus = true;
931931
statusMessage.status_list.forEach(function(status) {
932932
var goal = that.goals[status.goal_id.id];
@@ -939,7 +939,7 @@ function ActionClient(options) {
939939

940940
// subscribe the the feedback topic
941941
if (!this.omitFeedback) {
942-
feedbackListener.subscribe(function(feedbackMessage) {
942+
this.feedbackListener.subscribe(function(feedbackMessage) {
943943
var goal = that.goals[feedbackMessage.status.goal_id.id];
944944
if (goal) {
945945
goal.emit('status', feedbackMessage.status);
@@ -950,7 +950,7 @@ function ActionClient(options) {
950950

951951
// subscribe to the result topic
952952
if (!this.omitResult) {
953-
resultListener.subscribe(function(resultMessage) {
953+
this.resultListener.subscribe(function(resultMessage) {
954954
var goal = that.goals[resultMessage.status.goal_id.id];
955955

956956
if (goal) {
@@ -980,6 +980,17 @@ ActionClient.prototype.cancel = function() {
980980
this.cancelTopic.publish(cancelMessage);
981981
};
982982

983+
/**
984+
* Unsubscribe and unadvertise all topics associated with this ActionClient.
985+
*/
986+
ActionClient.prototype.dispose = function() {
987+
this.goalTopic.unadvertise();
988+
this.cancelTopic.unadvertise();
989+
if (!this.omitStatus) {this.statusListener.unsubscribe();}
990+
if (!this.omitFeedback) {this.feedbackListener.unsubscribe();}
991+
if (!this.omitResult) {this.resultListener.unsubscribe();}
992+
};
993+
983994
module.exports = ActionClient;
984995

985996
},{"../core/Message":10,"../core/Topic":17,"eventemitter2":1}],6:[function(require,module,exports){
@@ -2420,10 +2431,11 @@ function Topic(options) {
24202431
this.latch = options.latch || false;
24212432
this.queue_size = options.queue_size || 100;
24222433
this.queue_length = options.queue_length || 0;
2434+
this.reconnect_on_close = options.reconnect_on_close || true;
24232435

24242436
// Check for valid compression types
24252437
if (this.compression && this.compression !== 'png' &&
2426-
this.compression !== 'none') {
2438+
this.compression !== 'none') {
24272439
this.emit('warning', this.compression +
24282440
' compression is not supported. No compression will be used.');
24292441
}
@@ -2435,6 +2447,27 @@ function Topic(options) {
24352447
}
24362448

24372449
var that = this;
2450+
if (this.reconnect_on_close) {
2451+
this.callForSubscribeAndAdvertise = function(message) {
2452+
that.ros.callOnConnection(message);
2453+
2454+
that.waitForReconnect = false;
2455+
that.reconnectFunc = function() {
2456+
if(!that.waitForReconnect) {
2457+
that.waitForReconnect = true;
2458+
that.ros.callOnConnection(message);
2459+
that.ros.once('connection', function() {
2460+
that.waitForReconnect = false;
2461+
});
2462+
}
2463+
};
2464+
that.ros.on('close', that.reconnectFunc);
2465+
};
2466+
}
2467+
else {
2468+
this.callForSubscribeAndAdvertise = this.ros.callOnConnection;
2469+
}
2470+
24382471
this._messageCallback = function(data) {
24392472
that.emit('message', new Message(data));
24402473
};
@@ -2456,7 +2489,8 @@ Topic.prototype.subscribe = function(callback) {
24562489
if (this.subscribeId) { return; }
24572490
this.ros.on(this.name, this._messageCallback);
24582491
this.subscribeId = 'subscribe:' + this.name + ':' + (++this.ros.idCounter);
2459-
this.ros.callOnConnection({
2492+
2493+
this.callForSubscribeAndAdvertise({
24602494
op: 'subscribe',
24612495
id: this.subscribeId,
24622496
type: this.messageType,
@@ -2485,6 +2519,9 @@ Topic.prototype.unsubscribe = function(callback) {
24852519
if (!this.subscribeId) { return; }
24862520
// Note: Don't call this.removeAllListeners, allow client to handle that themselves
24872521
this.ros.off(this.name, this._messageCallback);
2522+
if(this.reconnect_on_close) {
2523+
this.ros.off('close', this.reconnectFunc);
2524+
}
24882525
this.emit('unsubscribe');
24892526
this.ros.callOnConnection({
24902527
op: 'unsubscribe',
@@ -2494,6 +2531,7 @@ Topic.prototype.unsubscribe = function(callback) {
24942531
this.subscribeId = null;
24952532
};
24962533

2534+
24972535
/**
24982536
* Registers as a publisher for the topic.
24992537
*/
@@ -2502,7 +2540,7 @@ Topic.prototype.advertise = function() {
25022540
return;
25032541
}
25042542
this.advertiseId = 'advertise:' + this.name + ':' + (++this.ros.idCounter);
2505-
this.ros.callOnConnection({
2543+
this.callForSubscribeAndAdvertise({
25062544
op: 'advertise',
25072545
id: this.advertiseId,
25082546
type: this.messageType,
@@ -2511,6 +2549,13 @@ Topic.prototype.advertise = function() {
25112549
queue_size: this.queue_size
25122550
});
25132551
this.isAdvertised = true;
2552+
2553+
if(!this.reconnect_on_close) {
2554+
var that = this;
2555+
this.ros.on('close', function() {
2556+
that.isAdvertised = false;
2557+
});
2558+
}
25142559
};
25152560

25162561
/**
@@ -2520,6 +2565,9 @@ Topic.prototype.unadvertise = function() {
25202565
if (!this.isAdvertised) {
25212566
return;
25222567
}
2568+
if(this.reconnect_on_close) {
2569+
this.ros.off('close', this.reconnectFunc);
2570+
}
25232571
this.emit('unadvertise');
25242572
this.ros.callOnConnection({
25252573
op: 'unadvertise',
@@ -3047,6 +3095,16 @@ TFClient.prototype.unsubscribe = function(frameID, callback) {
30473095
}
30483096
};
30493097

3098+
/**
3099+
* Unsubscribe and unadvertise all topics associated with this TFClient.
3100+
*/
3101+
TFClient.prototype.dispose = function() {
3102+
this.actionClient.dispose();
3103+
if (this.currentTopic) {
3104+
this.currentTopic.unsubscribe();
3105+
}
3106+
};
3107+
30503108
module.exports = TFClient;
30513109

30523110
},{"../actionlib/ActionClient":5,"../actionlib/Goal":7,"../core/Service.js":13,"../core/ServiceRequest.js":14,"../math/Transform":21}],26:[function(require,module,exports){

build/roslib.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/actionlib/ActionClient.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,19 @@ function ActionClient(options) {
3939
var receivedStatus = false;
4040

4141
// create the topics associated with actionlib
42-
var feedbackListener = new Topic({
42+
this.feedbackListener = new Topic({
4343
ros : this.ros,
4444
name : this.serverName + '/feedback',
4545
messageType : this.actionName + 'Feedback'
4646
});
4747

48-
var statusListener = new Topic({
48+
this.statusListener = new Topic({
4949
ros : this.ros,
5050
name : this.serverName + '/status',
5151
messageType : 'actionlib_msgs/GoalStatusArray'
5252
});
5353

54-
var resultListener = new Topic({
54+
this.resultListener = new Topic({
5555
ros : this.ros,
5656
name : this.serverName + '/result',
5757
messageType : this.actionName + 'Result'
@@ -75,7 +75,7 @@ function ActionClient(options) {
7575

7676
// subscribe to the status topic
7777
if (!this.omitStatus) {
78-
statusListener.subscribe(function(statusMessage) {
78+
this.statusListener.subscribe(function(statusMessage) {
7979
receivedStatus = true;
8080
statusMessage.status_list.forEach(function(status) {
8181
var goal = that.goals[status.goal_id.id];
@@ -88,7 +88,7 @@ function ActionClient(options) {
8888

8989
// subscribe the the feedback topic
9090
if (!this.omitFeedback) {
91-
feedbackListener.subscribe(function(feedbackMessage) {
91+
this.feedbackListener.subscribe(function(feedbackMessage) {
9292
var goal = that.goals[feedbackMessage.status.goal_id.id];
9393
if (goal) {
9494
goal.emit('status', feedbackMessage.status);
@@ -99,7 +99,7 @@ function ActionClient(options) {
9999

100100
// subscribe to the result topic
101101
if (!this.omitResult) {
102-
resultListener.subscribe(function(resultMessage) {
102+
this.resultListener.subscribe(function(resultMessage) {
103103
var goal = that.goals[resultMessage.status.goal_id.id];
104104

105105
if (goal) {
@@ -129,4 +129,15 @@ ActionClient.prototype.cancel = function() {
129129
this.cancelTopic.publish(cancelMessage);
130130
};
131131

132+
/**
133+
* Unsubscribe and unadvertise all topics associated with this ActionClient.
134+
*/
135+
ActionClient.prototype.dispose = function() {
136+
this.goalTopic.unadvertise();
137+
this.cancelTopic.unadvertise();
138+
if (!this.omitStatus) {this.statusListener.unsubscribe();}
139+
if (!this.omitFeedback) {this.feedbackListener.unsubscribe();}
140+
if (!this.omitResult) {this.resultListener.unsubscribe();}
141+
};
142+
132143
module.exports = ActionClient;

src/core/Topic.js

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ var Message = require('./Message');
2323
* * queue_size - the queue created at bridge side for re-publishing webtopics (defaults to 100)
2424
* * latch - latch the topic when publishing
2525
* * queue_length - the queue length at bridge side used when subscribing (defaults to 0, no queueing).
26+
* * reconnect_on_close - the flag to enable resubscription and readvertisement on close event(defaults to true).
2627
*/
2728
function Topic(options) {
2829
options = options || {};
@@ -35,10 +36,11 @@ function Topic(options) {
3536
this.latch = options.latch || false;
3637
this.queue_size = options.queue_size || 100;
3738
this.queue_length = options.queue_length || 0;
39+
this.reconnect_on_close = options.reconnect_on_close || true;
3840

3941
// Check for valid compression types
4042
if (this.compression && this.compression !== 'png' &&
41-
this.compression !== 'none') {
43+
this.compression !== 'none') {
4244
this.emit('warning', this.compression +
4345
' compression is not supported. No compression will be used.');
4446
}
@@ -50,6 +52,27 @@ function Topic(options) {
5052
}
5153

5254
var that = this;
55+
if (this.reconnect_on_close) {
56+
this.callForSubscribeAndAdvertise = function(message) {
57+
that.ros.callOnConnection(message);
58+
59+
that.waitForReconnect = false;
60+
that.reconnectFunc = function() {
61+
if(!that.waitForReconnect) {
62+
that.waitForReconnect = true;
63+
that.ros.callOnConnection(message);
64+
that.ros.once('connection', function() {
65+
that.waitForReconnect = false;
66+
});
67+
}
68+
};
69+
that.ros.on('close', that.reconnectFunc);
70+
};
71+
}
72+
else {
73+
this.callForSubscribeAndAdvertise = this.ros.callOnConnection;
74+
}
75+
5376
this._messageCallback = function(data) {
5477
that.emit('message', new Message(data));
5578
};
@@ -71,7 +94,8 @@ Topic.prototype.subscribe = function(callback) {
7194
if (this.subscribeId) { return; }
7295
this.ros.on(this.name, this._messageCallback);
7396
this.subscribeId = 'subscribe:' + this.name + ':' + (++this.ros.idCounter);
74-
this.ros.callOnConnection({
97+
98+
this.callForSubscribeAndAdvertise({
7599
op: 'subscribe',
76100
id: this.subscribeId,
77101
type: this.messageType,
@@ -100,6 +124,9 @@ Topic.prototype.unsubscribe = function(callback) {
100124
if (!this.subscribeId) { return; }
101125
// Note: Don't call this.removeAllListeners, allow client to handle that themselves
102126
this.ros.off(this.name, this._messageCallback);
127+
if(this.reconnect_on_close) {
128+
this.ros.off('close', this.reconnectFunc);
129+
}
103130
this.emit('unsubscribe');
104131
this.ros.callOnConnection({
105132
op: 'unsubscribe',
@@ -109,6 +136,7 @@ Topic.prototype.unsubscribe = function(callback) {
109136
this.subscribeId = null;
110137
};
111138

139+
112140
/**
113141
* Registers as a publisher for the topic.
114142
*/
@@ -117,7 +145,7 @@ Topic.prototype.advertise = function() {
117145
return;
118146
}
119147
this.advertiseId = 'advertise:' + this.name + ':' + (++this.ros.idCounter);
120-
this.ros.callOnConnection({
148+
this.callForSubscribeAndAdvertise({
121149
op: 'advertise',
122150
id: this.advertiseId,
123151
type: this.messageType,
@@ -126,6 +154,13 @@ Topic.prototype.advertise = function() {
126154
queue_size: this.queue_size
127155
});
128156
this.isAdvertised = true;
157+
158+
if(!this.reconnect_on_close) {
159+
var that = this;
160+
this.ros.on('close', function() {
161+
that.isAdvertised = false;
162+
});
163+
}
129164
};
130165

131166
/**
@@ -135,6 +170,9 @@ Topic.prototype.unadvertise = function() {
135170
if (!this.isAdvertised) {
136171
return;
137172
}
173+
if(this.reconnect_on_close) {
174+
this.ros.off('close', this.reconnectFunc);
175+
}
138176
this.emit('unadvertise');
139177
this.ros.callOnConnection({
140178
op: 'unadvertise',

src/tf/TFClient.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,4 +206,14 @@ TFClient.prototype.unsubscribe = function(frameID, callback) {
206206
}
207207
};
208208

209+
/**
210+
* Unsubscribe and unadvertise all topics associated with this TFClient.
211+
*/
212+
TFClient.prototype.dispose = function() {
213+
this.actionClient.dispose();
214+
if (this.currentTopic) {
215+
this.currentTopic.unsubscribe();
216+
}
217+
};
218+
209219
module.exports = TFClient;

0 commit comments

Comments
 (0)