Last active
April 4, 2021 17:07
-
-
Save ytiq/8d8cda82397d2cca6c7121163762cc52 to your computer and use it in GitHub Desktop.
cometd.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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