/* * Spreed WebRTC. * Copyright (C) 2013-2014 struktur AG * * This file is part of Spreed WebRTC. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * */ define(['jquery', 'underscore'], function($, _) { var timeout = 5000; var timeout_max = 20000; var Connector = function() { this.e = $({}); this.error = false; this.connected = false; this.connecting = null; this.connecting_timeout = timeout; this.disabled = false; this.token = null; this.queue = []; }; Connector.prototype.connect = function(url) { //console.log("connect", this.disabled, url); if (this.disabled) { return; } this.error = false; this.e.triggerHandler("connecting", [url]); this.url = url; if (this.token) { url += ("?t=" + this.token); //console.log("Reusing existing token", this.token); } var conn = this.conn = new WebSocket(url); conn.onopen = _.bind(this.onopen, this); conn.onerror = _.bind(this.onerror, this); conn.onclose = _.bind(this.onclose, this); conn.onmessage = _.bind(this.onmessage, this) this.connecting = window.setTimeout(_.bind(function() { console.warn("Connection timeout out after", this.connecting_timeout); if (this.connecting_timeout < timeout_max) { this.connecting_timeout += timeout; } this.e.triggerHandler("error"); this.reconnect(); }, this), this.connecting_timeout); }; Connector.prototype.disconnect = function(error) { if (error) { this.onerror(null) } else { this.conn.close(); } }; Connector.prototype.reconnect = function() { if (!this.url) { return; } this.close(); var url = this.url; this.url = null; setTimeout(_.bind(function() { this.connect(url); }, this), 200); }; Connector.prototype.close = function() { this.connected = false; if (this.conn) { var conn = this.conn; this.conn = null; if (!this.error) { conn.close(); } conn.onopen = conn.onerror = conn.onclose = conn.onmessage = null; } }; Connector.prototype.forgetAndReconnect = function() { this.token = null; if (this.conn && this.connected) { this.conn.close(); } }; Connector.prototype.onopen = function(event) { window.clearTimeout(this.connecting); this.connecting_timeout = timeout; // Connection successfully established. console.info("Connector on connection open."); this.connected = true; this.e.triggerHandler("open", [null, event]); // Send out stuff which was previously queued. var data; while (this.queue.length > 0 && this.connected) { data = this.queue.shift(); this.send(data); } }; Connector.prototype.onerror = function(event) { window.clearTimeout(this.connecting); this.connecting_timeout = timeout; //console.log("onerror", event); console.warn("Connector on connection error."); this.error = true; this.close(); this.e.triggerHandler("error", [null, event]); }; Connector.prototype.onclose = function(event) { window.clearTimeout(this.connecting); this.connecting_timeout = timeout; //console.log("onclose", event); console.info("Connector on connection close.", event, this.error); this.close(); if (!this.error) { this.e.triggerHandler("close", [null, event]); } }; Connector.prototype.onmessage = function(event) { //console.log("onmessage", event); var msg = JSON.parse(event.data); this.e.triggerHandler("received", [msg]); }; Connector.prototype.send = function(data, noqueue) { if (!this.connected) { if (!noqueue) { this.queue.push(data); console.warn("Queuing sending data because of not connected.", data); return; } } this.conn.send(JSON.stringify(data)); }; Connector.prototype.ready = function(func) { /* Call a function whenever the Connection is ready */ this.e.on("open", func); if (this.connected) { func(); } }; return Connector; });