RobotWebTools / roslibjs

The Standard ROS JavaScript Library
https://robotwebtools.github.io/roslibjs
Other
682 stars 381 forks source link

Service.advertise(callback) appends callbacks to the event listener for given service #299

Open leorich opened 6 years ago

leorich commented 6 years ago

If the same service is advertised, unadvertised, then advertised again, both callbacks given to service.advertise(callback) end up getting executed. They keep stacking up the more you readvertise.

Example:

    this.startUserConfirmationService = () => {
        this.userConfirmationService = new ROSLIB.Service({
            ros : ros,
            name : name,
            serviceType: type,
        })
    };
    this.startUserConfirmationService();

    this.advertiseUserConfirmation = () => {
        if (allowedToPublish) {
            this.userConfirmationService.advertise((req,res) => {
                if (confirm(req.info)) {
                    res.confirmation_response = true;
                    return true
                } else {
                    res.confirmation_response = false;
                    return true
                }
            })
        } else {
            this.userConfirmationService.unadvertise()
            console.log('alert! not allowed to send')
        }
    };

this.advertiseUserConfirmation() //allowedToPublish = true
// At this point, when the service is called there is 1 'confirm' dialog box
this.advertiseUserConfirmation() //allowedToPublish = false
// At this point, when the service is called, it is not available
this.advertiseUserConfirmation() //allowedToPublish = true
// At this point, when the service is called a 'confirm' dialog box pops up, followed by a second 'confirm' pup up

Adding this.ros.removeAllListeners(this.name) before line 85 of src/core/Service.js: this.ros.on(this.name, this._serviceResponse.bind(this)); should solve this issue fairly simply. I tested and it solved the issue for me.

sradmard commented 6 years ago

Hi @leorich , I was wondering whether you have any idea on how to set up a ros service server on the html side, rather than setting up a ros service client. Right now, we can set up a service server in a ros node, and then make a service call through the ros service client that resides inside the html code. What I am looking for is the opposite. I basically want to play a video clip once, upon a service call from a ros node, and then return to ros upon completion of the video (publishing through a ros topic won't work properly). I would like the ros service server to reside in the html code so that the service client inside my ros node can activate the video streaming whenever needed. I would appreciate any insight on that.

f-o-w-l commented 3 weeks ago

Really surprised this hasn't been addressed. Bump!