You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
3.7 KiB
119 lines
3.7 KiB
//===== Constructor
|
|
|
|
const Connection = function() {
|
|
this.retryCounter = 0;
|
|
this.name = null;
|
|
this.heartbeatTimer = null;
|
|
|
|
this.socketListeners = {
|
|
open: this.onOpen.bind(this),
|
|
error: this.onError.bind(this),
|
|
message: this.onReceiveMessage.bind(this)
|
|
};
|
|
|
|
// Local event listeners
|
|
document.addEventListener('L-join', (evt) => {
|
|
this.name = evt.detail;
|
|
this.connect();
|
|
});
|
|
|
|
document.addEventListener('G-heartbeat', () => {
|
|
this.heartbeat();
|
|
});
|
|
|
|
document.addEventListener('L-newround', () => this.send({ type: 'newround' }) );
|
|
|
|
document.addEventListener('L-objective', () => this.send({ type: 'objective' }) );
|
|
|
|
document.addEventListener('L-robots', () => this.send({ type: 'robots' }) );
|
|
|
|
document.addEventListener('L-solve', (evt) => this.send({ type: 'solve', rawBody: evt.detail }) );
|
|
|
|
document.addEventListener('L-walls', () => this.send({ type: 'walls' }) );
|
|
|
|
document.addEventListener('L-skip', () => this.send({ type: 'skip' }) );
|
|
};
|
|
|
|
Connection.prototype.connect = function() {
|
|
const hostname = window.location.hostname;
|
|
const uuid = Cookie.getCookie({ name: 'player_id' });
|
|
|
|
this.ws = new WebSocket(`ws://${hostname}:8081/ricochet?name=${this.name}&uuid=${uuid}`);
|
|
|
|
this.ws.addEventListener('open', this.socketListeners.open);
|
|
this.ws.addEventListener('error', this.socketListeners.error);
|
|
this.ws.addEventListener('message', this.socketListeners.message);
|
|
};
|
|
|
|
Connection.prototype.send = function(json) {
|
|
if (this.ws.readyState === 1) {
|
|
this.ws.send(JSON.stringify(json));
|
|
} else {
|
|
this.onError('WebSocket connection interrupted.');
|
|
}
|
|
};
|
|
|
|
Connection.prototype.heartbeat = function() {
|
|
setTimeout(this.send.bind(this, { type: 'heartbeat' }), 30000);
|
|
};
|
|
|
|
//===== Connection event handlers
|
|
|
|
Connection.prototype.onOpen = function() {
|
|
this.retryCounter = 0;
|
|
|
|
this.heartbeat();
|
|
|
|
const evt = new Event('L-conn-open');
|
|
document.dispatchEvent(evt);
|
|
};
|
|
|
|
Connection.prototype.onError = function(err) {
|
|
console.error(err);
|
|
|
|
this.ws.removeEventListener('open', this.socketListeners.open);
|
|
this.ws.removeEventListener('error', this.socketListeners.error);
|
|
this.ws.removeEventListener('message', this.socketListeners.message);
|
|
|
|
const evt = new CustomEvent('L-conn-error', { detail: err });
|
|
document.dispatchEvent(evt);
|
|
|
|
if (this.retryCounter < 5) {
|
|
this.retryCounter++;
|
|
console.error("Retrying connection...");
|
|
setTimeout(this.connect.bind(this), Math.pow(this.retryCounter, 2) * 1000);
|
|
} else {
|
|
console.error("Retries exhausted. Server can't be contacted.");
|
|
}
|
|
};
|
|
|
|
Connection.prototype.onReceiveMessage = function({ data }) {
|
|
const msg = JSON.parse(data);
|
|
console.warn(JSON.stringify(msg));
|
|
|
|
if (!msg.type) {
|
|
console.warn("Unprocessable message: ", msg)
|
|
return;
|
|
}
|
|
|
|
let eventName;
|
|
|
|
switch (msg.type) {
|
|
case 'connected': eventName = 'G-connected'; break;
|
|
case 'countdown': eventName = 'G-countdown'; break;
|
|
case 'full': eventName = 'G-full'; break;
|
|
case 'heartbeat': eventName = 'G-heartbeat'; break;
|
|
case 'newround': eventName = 'G-newround'; break;
|
|
case 'objective': eventName = 'G-objective'; break;
|
|
case 'players': eventName = 'G-players'; break;
|
|
case 'robots': eventName = 'G-robots'; break;
|
|
case 'state': eventName = 'G-state'; break;
|
|
case 'walls': eventName = 'G-walls'; break;
|
|
case 'win': eventName = 'G-win'; break;
|
|
}
|
|
|
|
if (eventName) {
|
|
const evt = new CustomEvent(eventName, { detail: msg });
|
|
document.dispatchEvent(evt);
|
|
}
|
|
};
|
|
|