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.
240 lines
5.2 KiB
240 lines
5.2 KiB
/* |
|
* 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 <http://www.gnu.org/licenses/>. |
|
* |
|
*/ |
|
define(['jquery', 'underscore', 'ua-parser'], function($, _, uaparser) { |
|
|
|
var timeout = 5000; |
|
var timeout_max = 20000; |
|
|
|
var Connector = function(version) { |
|
|
|
this.version = version; |
|
this.e = $({}); |
|
this.error = false; |
|
this.connected = false; |
|
this.disabled = false; |
|
this.connecting = null; |
|
this.connecting_timeout = timeout; |
|
|
|
this.token = null; |
|
this.queue = []; |
|
|
|
this.roomid = null; |
|
|
|
var ua = uaparser(); |
|
if (ua.os.name && /Spreed Desktop Caller/i.test(ua.ua)) { |
|
this.userAgent = ua.ua.match(/Spreed Desktop Caller\/([\d.]+)/i)[1] + " (" + ua.os.name + ")"; |
|
} else if (ua.browser.name) { |
|
this.userAgent = ua.browser.name + " " + ua.browser.major; |
|
} else { |
|
this.userAgent = ua.ua; |
|
} |
|
|
|
}; |
|
|
|
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.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.room = function(roomid, cb) { |
|
|
|
var was_connected = this.connected; |
|
|
|
if (was_connected) { |
|
if (this.roomid === roomid) { |
|
return; |
|
} |
|
this.e.triggerHandler("closed", [{ |
|
soft: true |
|
}]); |
|
} |
|
|
|
this.roomid = roomid; |
|
roomid = this.roomid ? this.roomid : ""; |
|
|
|
if (cb) { |
|
cb(); |
|
} |
|
|
|
this.send({ |
|
Type: "Hello", |
|
Hello: { |
|
Version: this.version, |
|
Ua: this.userAgent, |
|
Id: roomid |
|
} |
|
}); |
|
|
|
if (was_connected) { |
|
this.e.triggerHandler("open", [{ |
|
soft: true |
|
}]); |
|
} |
|
|
|
}; |
|
|
|
Connector.prototype.onopen = function(event) { |
|
|
|
window.clearTimeout(this.connecting); |
|
this.connecting_timeout = timeout; |
|
|
|
//console.log("onopen", event); |
|
console.info("Connector on connection open."); |
|
this.room(this.roomid, _.bind(function() { |
|
this.connected = true; |
|
}, this)); |
|
this.e.triggerHandler("open", [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", [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.close(); |
|
if (!this.error) { |
|
this.e.triggerHandler("close", [event]); |
|
} |
|
this.e.triggerHandler("closed", [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; |
|
|
|
});
|
|
|