Skip to content

Instantly share code, notes, and snippets.

@mercmobily
Created December 8, 2016 07:19
Show Gist options
  • Save mercmobily/b82ceea6c3bf90d1b0fafd9e577a4c88 to your computer and use it in GitHub Desktop.
Save mercmobily/b82ceea6c3bf90d1b0fafd9e577a4c88 to your computer and use it in GitHub Desktop.
A very unusual behaviour for Polymer
<link rel="import" href="../polymer/polymer.html">
<!--
Manage websocket connection
Expose websocket connection
@demo demo/index.html
-->
<script>
(function() {
// 'use strict';
var object = {
/* Properties */
status: 'neveropened',
subscribers: [],
browserStatus: 'online', // Will always be up-to-date
clientId: '',
url: '',
protocol: '',
reconnectDelay: 5000,
socket: null,
messageQueue: [],
/* Methods */
onOpen: function( e ){
console.log("Websocket opened");
if( this.status != 'neveropened' ){
console.log("It wasn't the first time! So, broadcasting 'reconnected' ");
this.sendLocal( { type: 'status', data: 'reconnected' } )
}
},
onError: function( e ){
console.log("Websocket closed because of error, re-attempting connection later");
this.status = 'closed';
this.reconnectLater();
},
onClose: function( e ){
console.log("Websocket closed, reattempting connection later");
this.status = 'closed';
this.reconnectLater();
},
reconnectLater: function(){
console.log("Reconnecting in ", this.reconnectDelay );
setTimeout( function(){
console.log("Reconnecting now!" );
this.connect( this.url, this.protocol );
}.bind(this), this.reconnectDelay );
},
onMessage: function( e ){
// A message arrived: broadcast it to subscribers
this.notifySubscribers( e.data );
},
connect: function( url, protocol ){
this.url = url || this.url;
this.protocol = this.protocol || protocol;
console.log("Connecting to:", this.url, this.protocol );
this.socket = new WebSocket( this.url, this.protocol );
this.socket.onerror = this.onError.bind( this );
this.socket.onopen = this.onOpen.bind( this );
this.socket.onopen = this.onClose.bind( this );
this.socket.onmessage = this.onMessage.bind( this );
},
sendWs: function( payload ){
console.log("Putting payload in sending queue...", payload )
this.messageQueue.push( payload );
this.sendQueue();
},
sendQueue: function(){
console.log("In sending queue...")
if( this.inSendQueue ) return;
this.inSendQueue = true;
console.log("ACTUALLY entered sending queue, broadcasting payloads: ", this.inSendQueue.length );
var payload;
for( var i = 0, l = this.inSendQueue.length; i < l; i ++ ){
var payload = this.inSendQueue[ k ];
payload.clientId = object.clientId;
try {
console.log("Attempting to send...");
this.socket.send( payload );
} catch( e ){
console.log("Error sending!", err );
break;
}
}
this.inSendQueue = false;
},
sendLocal: function( payload ){
console.log("Sending payload to local subscribers...")
this.notifySubscribers( payload );
},
notifySubscribers: function( payload ) {
console.log("Sending payload to local subscribers:", this.subscribers.length, payload )
for (var i = 0; i < this.subscribers.length; ++i) {
if( payload.wsClientId != this.clientId ){
this.subscribers[ i ].wsMessage( payload );
}
}
}
}
window.addEventListener('online', function(){ object.browserStatus='online'; } );
window.addEventListener('offline', function(){ object.browserStatus='offline'; } );
// Attempt to send messages after 10 seconds
setInterval( function(){
object.sendQueue();
}, 10000 );
/**
* @hotplateBehavior
*
* Broadcast a message either locally, or via WebSocket.
* Keeps the connection going, and keeps messages in a queue
* Provides a "tabId" (or "clientId") so that a broadcaster won't
* receive from the server messages
*
*
{
type: 'record',
data: {
op: 'changeRecord' | 'addRecord' | 'deleteRecord'
record: { ... }
}
}
{
type: 'status',
data: 'reconnected',
}
*/
if( typeof Hotplate == 'undefined' ) Hotplate = {};
Hotplate.HotWsBehavior = {
properties: {
wsData: {
type: Object,
value: object,
readOnly: true,
},
wsClientId: {
type: String,
observer: "_wsClientIdChanged",
},
wsUrl: {
type: String,
observer: "_wsUrlChanged",
},
wsReconnectDelay: {
type: String,
observer: "_wsReconnectDelayChanged",
},
wsAutoConnect: {
type: Boolean,
observer: "_wsAutoConnectChanged",
default: false,
}
},
_wsClientIdChanged: function( clientId ){
debugger;
this.set('wsData.clientId', clientId );
},
_wsUrlChanged: function( url ){
debugger;
this.set('wsData.url', url );
},
_wsReconnectDelayChanged: function( delay ){
debugger;
this.set('wsData.reconnectDelay', delay );
},
_wsAutoConnectChanged: function( autoConnect ){
debugger;
if( autoConnect) object.connect()
},
// Function to be overridden by element to receive messages
wsMessage: function( payload ){
},
wsSendLocal: function( payload ){
object.sendLocal( payload );
},
wsSendWs: function( payload ){
object.sendWs( payload );
},
attached: function() {
object.subscribers.push(this);
},
detached: function() {
var index = data.subscribers.indexOf(this);
if (index < 0) {
return;
}
data.subscribers.splice(index, 1);
},
};
})();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment