Created
February 10, 2018 14:08
-
-
Save igordata/c2be98b75f2f713b078820ec14e8de24 to your computer and use it in GitHub Desktop.
centrifugo web worker
This file contains hidden or 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
console.log('ww starting'); | |
function wwsClass() { | |
var wws = this; | |
wws.tabs = []; | |
wws.onconnect = function (e) { | |
for (var i = e.ports.length; i--;) { | |
wws.tabs.push(new wwsTab(e.ports[i])); | |
} | |
console.log('New tabs ' + e.ports.length); | |
console.log(wws.tabs); | |
}; | |
wws.broadcast = function (msg) { | |
console.log("Broadcasting message to " + wws.tabs.length + "tabss."); | |
console.log(msg); | |
for (var i = wws.tabs.length; i--;) { | |
try { | |
wws.tabs[i].send(msg); | |
} catch (e) { | |
wws.tabs[i].close(); | |
} | |
} | |
}; | |
wws.sendToRandom = function (msg) { | |
var tab = Math.floor(Math.random() * wws.tabs.length); | |
console.log("Sending message to " + tab + " tab."); | |
console.log(msg); | |
try { | |
wws.tabs[tab].send(msg); | |
} catch (e) { | |
wws.tabs[tab].close(); | |
} | |
}; | |
function wwsTab(port) { | |
console.log('New tab', port); | |
var tab = this; | |
tab.port = port; | |
tab.channels = []; | |
tab.send = function (msg) { | |
tab.port.postMessage(msg); | |
}; | |
tab.port.onmessage = function (e) { | |
tab.onTabMessage(e.data); | |
}; | |
tab.onTabMessage = function (msg) { | |
//console.log('Tab message: ', msg); | |
if (!msg.type) { | |
return false; | |
} | |
switch (msg.type) { | |
case 'command': | |
tab.onTabCommand(msg.command, msg.data); | |
break; | |
case 'message': | |
console.log(msg.data); | |
break; | |
} | |
}; | |
tab.onTabCommand = function (command, data) { | |
switch (command) { | |
case 'ping': | |
console.log('tab ping received'); | |
break; | |
case 'subscribe': | |
tab.commands.subscribe(data); | |
break; | |
case 'bye': | |
console.log('Tab closing'); | |
wws.onTabClose(tab); | |
break; | |
} | |
}; | |
tab.commands = { | |
subscribe: function (channels) { | |
console.log('Tab want to subscribe to channels: ', channels); | |
if (typeof channels === 'undefined') { | |
return false; | |
} | |
if (channels.length == 0) { | |
return false; | |
} | |
for (var i = channels.length; i--;) { | |
tab.channels.push(channels[i]); | |
} | |
tab.channels = tab.channels.filter(function (item, pos, self) { | |
return self.indexOf(item) == pos; | |
}); | |
wws.subscribe(channels); | |
} | |
}; | |
console.log(tab); | |
} | |
wws.onTabClose = function (tab) { | |
wws.channels.unsub(tab.channels); | |
console.log('closing tab port'); | |
wws.tabs.splice(wws.tabs.indexOf(tab), 1); | |
console.log(wws.tabs); | |
if (wws.tabs.length === 0) { | |
wws.onGoodbye(); | |
} | |
}; | |
wws.onGoodbye = function () { | |
console.log('Bye! Have a good time!'); | |
}; | |
wws.notice = function (options) { | |
if (typeof options !== 'object') { | |
options = {text: options}; | |
} | |
var defaults = { | |
html: false, | |
header: false, | |
text: '', | |
type: 'info', | |
image: false, | |
url: false | |
}; | |
function extend() { | |
for (var i = 1; i < arguments.length; i++) | |
for (var key in arguments[i]) | |
if (arguments[i].hasOwnProperty(key)) | |
arguments[0][key] = arguments[i][key]; | |
return arguments[0]; | |
} | |
var settings = extend({}, defaults, options); | |
if (typeof Notification !== 'undefined') { | |
try { | |
var notification = new Notification(settings.header, { | |
icon: settings.image, | |
body: settings.text | |
}); | |
notification.onclick = function (e) { | |
console.log('Notice clicked'); | |
console.log(e); | |
wws.sendToRandom({type: 'navigate', data: {url: settings.url}}); | |
notification.close(); | |
}; | |
notification.onclose = function () { | |
console.log('Notice closed'); | |
}; | |
} catch (err) { | |
} | |
} | |
}; | |
wws.processOptions = function (options) { | |
for (var key in options) { | |
switch (key) { | |
case 'notice': | |
if ((Notification.permission === "granted")) { | |
/* permission granted, рисуем сами, отрезаем нотис, чтобы из браузера со странички он не рисовался уже */ | |
wws.notice(options['notice']); | |
delete options['notice']; | |
} | |
break; | |
} | |
} | |
return options; | |
}; | |
wws.callbacks = { | |
"message": function (msg) { | |
console.log(msg); | |
msg = msg.data; | |
if (typeof msg.options !== 'undefined') { | |
msg.options = wws.processOptions(msg.options); | |
} | |
console.log('sending message', msg); | |
wws.broadcast(msg); | |
}, | |
"join": function (message) { | |
console.log('join', message); | |
}, | |
"leave": function (message) { | |
console.log('leave', message); | |
}, | |
"subscribe": function (context) { | |
console.log('subscribe', context); | |
}, | |
"error": function (error) { | |
console.log('error', error); | |
}, | |
"unsubscribe": function (context) { | |
console.log('unsubscribe', context); | |
if (wws.channels.list.hasOwnProperty(context.channel)) { | |
delete wws.channels.list[context.channel]; | |
} | |
console.log(wws.channels.list); | |
} | |
}; | |
wws.channels = new ChannelsList(); | |
function ChannelsList() { | |
var cl = this; | |
cl.list = {}; | |
cl.sub = function (channels) { | |
if (typeof channels === 'undefined') { | |
return false; | |
} | |
if (channels.length == 0) { | |
return false; | |
} | |
for (var i = channels.length; i--;) { | |
if (!cl.list.hasOwnProperty(channels[i])) { | |
cl.list[channels[i]] = {counter: 0, subscription: false}; | |
} | |
cl.list[channels[i]].counter++; | |
} | |
console.log('Current channels list: ', cl.list); | |
}; | |
cl.unsub = function (channels) { | |
console.log(channels); | |
if (typeof channels === 'undefined') { | |
return false; | |
} | |
if (channels.length == 0) { | |
return false; | |
} | |
for (var i = channels.length; i--;) { | |
if (!cl.list.hasOwnProperty(channels[i])) { | |
// already unsubcribed, but how is it possible? | |
} | |
cl.list[channels[i]].counter--; | |
} | |
var abandoned = []; | |
for (var chan in cl.list) { | |
if (cl.list[chan].counter < 1) { | |
abandoned.push(chan); | |
} | |
} | |
console.log('Abandoned channels list: ', abandoned); | |
// тут надо кильнуть абандонед | |
cl.kill(abandoned); | |
console.log('Current channels list: ', cl.list); | |
}; | |
cl.kill = function (channels) { | |
if (typeof channels === 'undefined') { | |
return false; | |
} | |
if (channels.length == 0) { | |
return false; | |
} | |
wws.centrifuge.startAuthBatching(); | |
for (var i = channels.length; i--;) { | |
if (cl.list.hasOwnProperty(channels[i])) { | |
console.log('Closing channel ' + channels[i]); | |
cl.list[channels[i]].subscription.unsubscribe(); | |
} | |
} | |
wws.centrifuge.stopAuthBatching(); | |
}; | |
}; | |
wws.subscribe = function (channels) { | |
wws.channels.sub(channels); | |
console.log('Want to subscribe to: ', channels); | |
console.log('Current channels list: ', wws.channels.list); | |
if (!wws.centrifuge) { | |
console.log("can't subscribe now, maybe later"); | |
return false; | |
} | |
console.log('Subscribing'); | |
wws.centrifuge.startAuthBatching(); | |
for (var chan in wws.channels.list) { | |
if (wws.channels.list[chan].subscription == false) { | |
/* не подписаны, надо подписаться */ | |
wws.channels.list[chan].subscription = wws.centrifuge.subscribe(chan, wws.callbacks); | |
} | |
} | |
wws.centrifuge.stopAuthBatching(); | |
}; | |
wws.centrifuge = null; | |
wws.init = function () { | |
var data = []; | |
var xmlhttp = new XMLHttpRequest(); | |
xmlhttp.open("POST", '/api/rtm/subscribe'); | |
xmlhttp.onreadystatechange = function () { | |
if (xmlhttp.readyState == XMLHttpRequest.DONE) { | |
if (xmlhttp.status == 200) { | |
console.log('Response: ' + xmlhttp.responseText); | |
var reply = ajaxResponseParse(xmlhttp.responseText); | |
console.log(reply); | |
wws.centrifuge = new Centrifuge({ | |
/*debug: true,*/ | |
url: '/centrifugo', | |
user: reply.getData('user'), | |
timestamp: reply.getData('timestamp'), | |
token: reply.getData('token'), | |
authEndpoint: '/api/rtm/auth', | |
transports: ['websocket', 'xdr-streaming', 'xhr-streaming', 'eventsource', 'xdr-polling', 'xhr-polling', 'jsonp-polling'] | |
}); | |
wws.subscribe(reply.getData('channels')); | |
wws.centrifuge.connect(); | |
} else { | |
console.log('Error: ' + xmlhttp.statusText) | |
} | |
} | |
}; | |
xmlhttp.send(data); | |
}; | |
} | |
var worker = new wwsClass(); | |
console.log('ww created'); | |
onconnect = worker.onconnect; | |
console.log('2'); | |
/*setInterval(function () { | |
worker.broadcast("time: " + (new Date().getTime())); | |
}, 5000);*/ | |
console.log('3'); | |
importScripts( | |
"/rtm/ajaxresponse.js", | |
"/rtm/sockjs.js" | |
); | |
importScripts("/rtm/centrifugo.js"); | |
console.log('worker.init();'); | |
worker.init(); | |
console.log('waiting for messages'); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment