12

I am trying to subscribe to a platform event using cometd. I have asserted that the event is getting published just fine but its subscribing that is an issue.

I have placed console logs in the cometd.js file and found out that when it subscribes, it logs out unsuccessful on the _notifylisteners method as the channel is gets passed is meta/unsuccessful.

Anyone have any suggestions? This is how im using cometd in in javascript:

$.cometd.init({
                url: window.location.protocol + '//' + window.location.hostname + '/cometd/44.0/',
                requestHeaders: {Authorization: 'OAuth {!$Api.Session_ID}'}
    });



        $.cometd.subscribe('/event/EPlatformEvent__e', function (message) 
       {
                console.log('Worked');
        });    

Upon further debugging, this is what I am getting in the message object that is being passed:

{advice: {…}, channel: "/meta/subscribe", id: "8", error: "403::Unknown client", successful: false}

Edit:

So after researching more into this issue, there were a few suggestions suggesting that the subscribe might be happening before the handshake therefore it's wise to add some sort of delay. I've got the following code and it now does connect to the platform event as it gives the following in the console logs: {clientId: "13qcqfozc84hy0n1hmd3u5jscryk", channel: "/meta/subscribe", id: "29", subscription: "/event/EPlatformEvent__e", successful: true} but still does not output the code that's supposed to get outputted when an event is published. This is my code now:

(function ($) {
        $(document).ready(function () {
            $.cometd.init({
                url: window.location.protocol + '//' + window.location.hostname + '/cometd/44.0/',
                requestHeaders: {Authorization: 'OAuth {!$Api.Session_ID}'}
            });
            setTimeout( function(){console.log('waiting..');}, 5000);
            $.cometd.addListener('/meta/unsuccessful', metaUnSucessfulListener);

            //$.cometd.subscribe('/event/EPlatformEvent__e', function (message) {
            //    console.log('working!');
            //});
            try{
                $.cometd.subscribe('/event/EPlatformEvent__e', function (message) {
                      console.log('wor33king!');
                    });
            }catch(e){
                console.log('catch block subscribe');
            }

        });
    })(jQuery)

     function metaUnSucessfulListener(message) {
            console.log(
                'DEBUG:  /meta/unsuccessful Error: ' +
                JSON.stringify(message) + ' <br>');
                unsubscribe();
                setTimeout( function(){
                    console.log('init of pt failed');
                    $.cometd.init({
                        url: window.location.protocol + '//' + window.location.hostname + '/cometd/44.0/',
                        requestHeaders: {Authorization: 'OAuth {!$Api.Session_ID}'}
                    });
                    $.cometd.addListener('/meta/unsuccessful', metaUnSucessfulListener);
                    $.cometd.subscribe('/event/EPlatformEvent__e', function (message) {
                        console.log('wor22king!');
                    });
                }, 5000);




        };


    function unsubscribee() {
    $.cometd.unsubscribe('/event/EPlatformEvent__e');
        $.cometd.disconnect();
    }

    function subscribee(){
    console.log('subscribing...');
        $.cometd.subscribe('/event/EPlatformEvent__e', function (message) {
                console.log('working!');
        });
    }

     function unsubscribe() {
       console.log('in the unsub');
       $.cometd.unsubscribe('/event/EPlatformEvent__e');
            $.cometd.disconnect(true);

        }
7
  • Are you missing __e in the event name? Shouldn't it be as /event/EPlatformEvent__e?
    – Jayant Das
    Oct 19, 2018 at 13:55
  • @JayantDas that was a typo, I have got __e in my code
    – oijekl
    Oct 19, 2018 at 14:00
  • If you using lightnig you can directly use lightning:empAPI . developer.salesforce.com/docs/component-library/bundle/… Oct 19, 2018 at 14:08
  • @PranayJaiswal I am using salesforce classic so I cant use the empApi..
    – oijekl
    Oct 19, 2018 at 14:10
  • How about embeding a lightning component in VF page using lightning out? Oct 19, 2018 at 15:49

1 Answer 1

5
+100

There are some Salesforce Docs on Subscribe to and Replay Events Using a Visualforce Page. They seem like a good place to start.

Here I'll replicate that example, except from sfdx.

sfdx force:project:create --projectname cometd
cd cometd
mkdir mdapipkg
git clone https://github.com/developerforce/SalesforceDurableStreamingDemo.git mdapipkg

Remove the mdapipkg\.git folder

sfdx force:mdapi:convert --rootdir mdapipkg
sfdx force:org:create -f config\project-scratch-def.json -a cometd
sfdx force:org:open -u cometd

Alter the file force-app\main\default\applications\Durable_Streaming_Demo.app-meta.xml to remove the two tab elements and replace then with tabs.

<?xml version="1.0" encoding="UTF-8"?>
<CustomApplication xmlns="http://soap.sforce.com/2006/04/metadata">
    <defaultLandingTab>standard-home</defaultLandingTab>
    <isNavAutoTempTabsDisabled>false</isNavAutoTempTabsDisabled>
    <isNavPersonalizationDisabled>false</isNavPersonalizationDisabled>
    <label>Durable Streaming Demo</label>
    <tabs>DurablePushTopicStreamingDemo</tabs>
    <tabs>DurableGenericStreamingDemo</tabs>
</CustomApplication>

Push the source to the scratch org and configure:

sfdx force:source:push -u cometd
sfdx force:user:permset:assign --permsetname DurableStreamingDemo --targetusername cometd

If I go to the Durable PushTopic Streaming Demo tab in the UI I can see cometD notifications coming into the Visualforce page.

enter image description here

The cometD subscription is actually occurring in DurablePushTopicEventDisplay.component.

I haven't compared their code to yours in great depth, but something that stands out is how the authentication is handled.

In their code they have:

// Connect to the CometD endpoint
cometd.configure({
        url: window.location.protocol+'//'+window.location.hostname+ (null != window.location.port ? (':'+window.location.port) : '') +'/cometd/37.0/',
        requestHeaders: { Authorization: 'OAuth {!$Api.Session_ID}'}
});

In comparison, your sample code does the equivalent in the init call. This may or may not be significant.

Another difference here is that the sample code is locked at API v37.0 and you are trying to use v44.0. I know this was historically an issue with the developer console, which is still using v36.0.

Check that you are using v3.1.0 of CometD. See Supported CometD Versions


Changing the demo to work with Platform Events rather than PushTopics.

According to Subscribe to Platform Event Notifications with CometD we want the channel to be

/event/EPlatformEvent__e

This should be changed in DurablePushTopicStreamingController.cls

Change line 3 to:

private static final String TOPIC_NAME = 'EPlatformEvent__e';

And line 10 to use /event/ rather than /topic/.

this.channel = '/event/' + TOPIC_NAME;

We should probably do something with getOrCreatePushChannel() as the PushTopic isn't required anymore, but for now I've left it as is.

Push these changes to your scratch org then publish a new Platform Event.

EPlatformEvent__e testEvent = new EPlatformEvent__e();
EventBus.publish(testEvent);

enter image description here

2
  • I do see that you question is specifically about Platform Events and not just subscribing to the CometD stream. I'll try and update this answer shortly. Oct 23, 2018 at 20:57
  • sorry for the late reply. I've tried that but still the same issue. Seems like theres a bug causing it since this is now my issue: github.com/forceworkbench/forceworkbench/issues/687 but I've tried the workaorund they suggested and still doesn't seem to work
    – oijekl
    Nov 9, 2018 at 13:44

You must log in to answer this question.

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