10

I am using the notification Console Component described in this trailhead:

Subscribe to Platform Events Trailhead

I am able to get it working, and the majority of the time I have no issues. However, every once in a while I am expecting a notification to pop up, but it does not. I check the console and I am presented with this message:

08:53:38.264 Exception during handling of messages Unrecognized advice action handshake

This is called from the cometD library, and it doesn't happen when I call the connectCometd function in the notificationConsoleHelper.jc class, it happens later in the session.

Has anyone else experienced this issues?

I want to wrap it in a try catch block, but I don't know which method in the notificationConsoleController or Helper classes is responsible for calling it - it is abstracted away by CometD.

1
  • Are you putting this in your helper class or the controller itself? Commented Jul 27, 2018 at 14:27

2 Answers 2

7

This is a know issue documented in the Platform Event project Build an Instant Notification App:

If you notice an "Exception during handling of messages Unrecognized advice action handshake" error in your developer console, please turn off notifications for your org:

  1. From Setup, enter Notifications in the Quick Find box, then select Salesforce Notifications.
  2. Uncheck the Enable in-app notifications and Enable push notifications checkboxes.
  3. Click Save.
  4. Log out then log in again.

This happens because of a conflict between the CometD connection that your app is trying to establish and the connection used internally by Salesforce to track notifications.

EDIT on Nov 13 2018: this issue is now solved with the use of lightning:empApi and the Trailhead project has been update accordingly.
Read more about this component in this blog post

1
  • :- tried but it doesn't help either. Commented Sep 6, 2018 at 20:22
6

I'm receiving this message as well. Not in the Trailhead but in my own code both within Visualforce page and withing a lightning component. I don't think you can catch this exception as it's caught by the cometd.js client lib. Note... before that happens.... in a connect listener I am seeing at 403::Unknown Client message.. then the cometd tries to handshaked / subscribe again (which it should).. then the unrecognized handshake message is caught by cometd.js.

Note. 403::Unknown client is not a standard error thrown by the cometd server code. this is probably a sfdc customized version of server code (@see https://github.com/cometd/cometd/issues/644)

It's also possibly related to the version of the cometd client lib being used. I've seen different versions all over the place in different samples / demos..

There are many intricacies described by salesforce with long polling and what the 'client' should do after certain time periods. but the confusing point is what exactly is meant by the client. ie cometd.js or our code that uses cometd.js. none of the examples / samples have this type of beef to them.

refer to this issue. I may try later versions and let you know! https://github.com/cometd/cometd/issues/722

Durable streaming is not something I want to have to use for this as I don't want to send a replyfrom of -2 and get a ton of messages back for the last 24 hours (it's 24 hours or none basically)

Note. One thing I've done to defend against this which seems to work.. And I don't think it's right but it's the only way I have got it to work. is.. from a connect listener i'm looking for a 403.. if I get it.. I know I'm done. i basically unsubscribe / destroy. configure again. handshake and subscribe again. Feels like way too much but I'm not losing messages this way soo. until I can find a sample that shows me a better way. I'm sticking with it.

    /**
 * A meta/connect listener for cometd. generally cometd should rehandshake on it's own but in case we have issues
 * this may be the spot to address.
 *
 * @param component
 * @param event
 * @param helper
 */
addConnectListener: function(component, event, helper) {
    //--- extra meta/connect listener for further bulletproofing.... this makes me sad that we have to do this!!
    var cometd = component.get("v.cometd");
    cometd.addListener('/meta/connect',$A.getCallback(function(message) {
        if(!message.successful) {
            helper.log('--- streamer meta/connect..xxx isDisconnected?' + cometd.isDisconnected() + '... message.error..'+message.error + 'advice=' + JSON.stringify(message.advice) + '..  message='+JSON.stringify(message),'warn',message);
            var advice = message.advice;

            //if(reconnect && reconnect!==undefined && reconnect != null) {
            if(message.error.includes('403')) {
                helper.log('--- streamer.. cometd will attempt to rehandshake on its own according to spec but always fails after the next handshake !! im forcing an entire reinit of the component doing a handledestroy here doesnot seem necessary as unsubscribe always fails.', 'warn');
                helper.doReInit(component, event, helper);
            }
                //------------------------helper.handshake(component,event.helper);
            //}
        }
    }));
},

Full code

addConnectListener: function(component, event, helper) {
    //--- extra meta/connect listener for further bulletproofing.... this makes me sad that we have to do this!!
    var cometd = component.get("v.cometd");
    cometd.addListener('/meta/connect', $A.getCallback(function(message) {
        if(!message.successful) {
            //helper.log('--- streamer meta/connect..xxx isDisconnected?' + cometd.isDisconnected() + '... message.error..'+message.error + 'advice=' + JSON.stringify(message.advice) + '..  message='+JSON.stringify(message),'warn',message);
            var advice = message.advice;

            //if(reconnect && reconnect!==undefined && reconnect != null) {
            if(message.error.includes('403')) {
                //helper.log('--- streamer.. cometd will attempt to rehandshake on its own according to spec but always fails after the next handshake !! im forcing an entire reinit of the component doing a handledestroy here doesnot seem necessary as unsubscribe always fails.', 'warn');
                //helper.connectCometd(component, event, helper);
                //helper.getRecord(component);
                var cometd = component.get("v.cometd");
                // Unsuscribe all CometD subscriptions
                cometd.batch(function() {
                  var subscriptions = component.get('v.cometdSubscriptions');
                  subscriptions.forEach(function (subscription) {
                    cometd.unsubscribe(subscription);
                  });
                });
                component.set('v.cometdSubscriptions', []);

                cometd.disconnect();
                var cometd = new org.cometd.CometD();
                component.set('v.cometd', cometd);
                helper.connectCometd(component);
                helper.addConnectListener( component, event, helper);
            }
        }
    }));
},

connectCometd : function(component) {
    var helper = this;

    // Configure CometD
    var cometdUrl = window.location.protocol+'//'+window.location.hostname+'/cometd/42.0/';
    var cometd = component.get('v.cometd');
    cometd.configure({
        url: cometdUrl,
        requestHeaders: { Authorization: 'OAuth '+ component.get('v.sessionId')},
        appendMessageTypeToURL : false
    });
    cometd.websocketEnabled = false;

    // Establish CometD connection
    console.log('Connecting to CometD: '+ cometdUrl);
    cometd.handshake(function(handshakeReply) {


        if (handshakeReply.successful) {
            console.log('Connected to CometD.');
            // Subscribe to platform event
            var newSubscription = cometd.subscribe('/event/Platform_Event__e',
                $A.getCallback(function(platformEvent) {
                    console.log('Platform event received: '+ JSON.stringify(platformEvent));
                    //helper.getRecord(component);
                })
            );

            // Save subscription for later
            var subscriptions = component.get('v.cometdSubscriptions');
            subscriptions.push(newSubscription);
            component.set('v.cometdSubscriptions', subscriptions);
        }
        else
            console.error('Failed to connected to CometD.');
    });
},
5
  • I am also facing the above error , do we have any solution apart from the one you mentioned. And also, what operation does helper.doReInit(component, event, helper); method perform?
    – Nitin
    Commented Feb 21, 2018 at 17:23
  • how do you attach add connect listener? when do you call method addConnectListener ?
    – Patlatus
    Commented Feb 23, 2018 at 11:53
  • were you able to resolve this issue? this didn't resolve the issue once I applied your solution
    – Patlatus
    Commented Feb 23, 2018 at 15:36
  • Ok, looks like I have found full code solution, I have updated the ChiCloud answer here
    – Patlatus
    Commented Feb 23, 2018 at 16:00
  • I'm starting to research Platform Events to help with detecting updates to records in our app, and saw the same handshake error. I'm using cometd 3.1.1 per a Trailhead article, but noticed in ChiCloud's issue #722 post that a commit was done against this issue, and it maybe fixed in cometd 3.1.2. Does anybody know for sure this is fixed in 3.1.2 (and later) versions of cometd, specifically when subscribing to Platform Events from within a Lightning component? Thanks! Commented Mar 29, 2018 at 22:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .