Skip to content

Instantly share code, notes, and snippets.

@ytiq
Last active April 4, 2021 17:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ytiq/8d8cda82397d2cca6c7121163762cc52 to your computer and use it in GitHub Desktop.
Save ytiq/8d8cda82397d2cca6c7121163762cc52 to your computer and use it in GitHub Desktop.
cometd.js
import {loadScript} from 'lightning/platformResourceLoader';
import cometd from '@salesforce/resourceUrl/cometd';
import {LightningElement, api} from "lwc";
import getSessionId from '@salesforce/apex/CommetD.getSessionId';
export default class CommetD extends LightningElement {
@api sessionId;
replayExtension;
cometd;
subscribedToChannel;
isExtensionEnabled;
metaConnectListener;
metaDisconnectListener;
metaHandshakeListener;
metaSubscribeListener;
metaUnSubscribeListener
metaUnSucessfulListener;
ready =
loadScript(this, cometd);
counter = 0;
async connectedCallback() {
await this.ready;
}
REPLAY_FROM_KEY = 'replay';
REPLAY_FROM = 'replayFrom';
visited = false;
isInitialized = false;
async renderedCallback() {
if (this.isInitialized) {
return;
}
this.sessionId = await getSessionId();
await this.ready;
this.initialize();
}
initialize() {
this.cometd = new window.org.cometd.CometD();
if (!this.metaSubscribeListener) {
this.metaSubscribeListener = this.cometd.addListener('/meta/subscribe', (message) => {
if (message.successful) {
console.log('Subscribe::success', message);
} else {
console.error('Subscribe::fail', message);
}
});
}
if (!this.metaHandshakeListener) {
this.metaHandshakeListener = this.cometd.addListener('/meta/handshake', (message) => {
if (message.successful) {
console.log('Handshake::success', message);
if (message.ext && message.ext[this.REPLAY_FROM_KEY] == true) {
this.isExtensionEnabled = true;
}
this.isHandshakeSuccess = true;
if (this.handshakeCallback) {
this.handshakeCallback.forEach((item) => {
this.cometd.subscribe(item.channel, item.replayFrom, item.callback);
})
this.handshakeCallback = [];
}
} else {
console.log('Handshake::fail', message);
}
});
}
let _connected = false;
if (!this.metaConnectListener) {
this.metaConnectListener = this.cometd.addListener('/meta/connect', (message) => {
if (this.cometd.isDisconnected()) {
if (!message.successful && message.error === '403::Unknown client') {
this.cometd.handshake();
}
}
var wasConnected = _connected;
_connected = message.successful;
if (!wasConnected && _connected) {
console.log('Connect::success', message);
} else if (wasConnected && !_connected) {
console.log('Connect::fail', message);
} else {
console.log('Connect::success', message);
}
});
}
if (!this.metaDisconnectListener) {
this.metaDisconnectListener = this.cometd.addListener('/meta/disconnect', (message) => {
console.log('disconnected', message);
});
}
const config = {
url: window.location.protocol + '//' + window.location.hostname + (null != window.location.port ? (':' + window.location.port) : '') + '/cometd/46.0/',
requestHeaders: {Authorization: `OAuth ${this.sessionId}`},
appendMessageTypeToURL: false,
logLevel: 'debug'
};
this.cometd.configure(config);
this.cometd.websocketEnabled = false;
this.cometd.handshake();
this.isInitialized = true;
}
@api
async subscribe(channel, replayFrom, callback) {
await this.ready;
if (this.visited) {
return;
}
this.visited = true;
// ensure extension isn't already registered
if (this.cometd.getExtension(this.REPLAY_FROM) != null) {
this.cometd.unregisterExtension(this.REPLAY_FROM);
}
// register durable generic streaming replayFrom extension
this.replayExtension = this.cometdReplayExtension();
this.replayExtension.setChannel(channel);
this.replayExtension.setReplay(replayFrom);
if (this.isExtensionEnabled) {
this.replayExtension.setExtensionEnabled(this.isExtensionEnabled);
}
this.cometd.registerExtension(this.REPLAY_FROM, this.replayExtension);
// unsubscribe if you have already subscribed
if (this.subscribedToChannel) {
this.cometd.unsubscribe(this.subscribedToChannel, null, (unsubscribeReply) => {
this.subscribedToChannel = this.cometd.subscribe(channel, callback);
});
}
if (this.isHandshakeSuccess) {
this.subscribedToChannel = this.cometd.subscribe(channel, callback);
} else {
this.handshakeCallback = this.handshakeCallback || [];
this.handshakeCallback.push({
channel,
replayFrom,
callback
});
}
return null;
// return this.cometd.subscribe(channel, callback);
}
disconnect(callback) {
console.log('call discconnect');
if (this.cometd) {
this.cometd.removeListener(this.metaConnectListener);
this.cometd.removeListener(this.metaDisconnectListener);
this.cometd.removeListener(this.metaHandshakeListener);
this.cometd.removeListener(this.metaSubscribeListener);
this.subscribedToChannel && this.cometd.unsubscribe(this.subscribedToChannel);
this.cometd.disconnect(callback);
}
}
disconnectedCallback() {
this.disconnect();
}
subscribe1() {
return
this.ready()
.then(() => {
});
}
cometdReplayExtension() {
var REPLAY_FROM_KEY = "replay";
var _cometd;
var _extensionEnabled;
var _replay;
var _channel;
this.setExtensionEnabled = function (extensionEnabled) {
_extensionEnabled = extensionEnabled;
}
this.setReplay = function (replay) {
_replay = parseInt(replay, 10);
}
this.setChannel = function (channel) {
_channel = channel;
}
this.registered = function (name, cometd) {
_cometd = cometd;
};
this.incoming = function (message) {
if (message.channel === '/meta/handshake') {
if (message.ext && message.ext[REPLAY_FROM_KEY] == true) {
_extensionEnabled = true;
}
} else if (message.channel === _channel && message.data && message.data.event && message.data.event.replayId) {
_replay = message.data.event.replayId;
}
}
this.outgoing = function (message) {
if (message.channel === '/meta/subscribe') {
if (_extensionEnabled) {
if (!message.ext) {
message.ext = {};
}
var replayFromMap = {};
replayFromMap[_channel] = _replay;
// add "ext : { "replay" : { CHANNEL : REPLAY_VALUE }}" to subscribe message
message.ext[REPLAY_FROM_KEY] = replayFromMap;
}
}
};
return this;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment