2019-01-20 15:26:06 +00:00
|
|
|
/**
|
|
|
|
* Signal exchanger web client
|
|
|
|
*
|
|
|
|
* @author Pierre HUBERT
|
|
|
|
*/
|
|
|
|
|
|
|
|
class SignalExchangerClient {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Server domain
|
|
|
|
*
|
|
|
|
* @type {String}
|
|
|
|
*/
|
|
|
|
//domain;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Server port
|
|
|
|
*
|
|
|
|
* @type {Number}
|
|
|
|
*/
|
|
|
|
//port;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Current client ID
|
|
|
|
*
|
|
|
|
* @type {String}
|
|
|
|
*/
|
|
|
|
//clientID;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Socket connection to the server
|
|
|
|
*
|
|
|
|
* @type {WebSocket}
|
|
|
|
*/
|
|
|
|
//socket;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function called in case of error
|
|
|
|
*
|
|
|
|
* @type {Function}
|
|
|
|
*/
|
|
|
|
//onError = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function called when the connection is etablished
|
|
|
|
*
|
|
|
|
* @type {Function}
|
|
|
|
*/
|
|
|
|
//onConnected = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function called when the connection to the socket is closed
|
|
|
|
*
|
|
|
|
* @type {Function}
|
|
|
|
*/
|
|
|
|
//onClosed = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function called when we get a new signal information
|
|
|
|
*
|
|
|
|
* @type {Function}
|
|
|
|
*/
|
|
|
|
//onSignal = null;
|
|
|
|
|
2019-01-25 09:47:42 +00:00
|
|
|
/**
|
|
|
|
* Function called when we get a ready message notice
|
|
|
|
*
|
|
|
|
* @type {Function}
|
|
|
|
*/
|
|
|
|
//onReadyMessage = null;
|
|
|
|
|
2019-01-20 15:26:06 +00:00
|
|
|
/**
|
|
|
|
* Construct a client instance
|
|
|
|
*
|
|
|
|
* @param {String} domain The name of the signal server
|
|
|
|
* @param {Number} port The port of the server to use
|
|
|
|
* @param {String} clientID The ID of current client
|
|
|
|
*/
|
|
|
|
constructor(domain, port, clientID) {
|
|
|
|
|
|
|
|
//Save information
|
|
|
|
this.domain = domain,
|
|
|
|
this.port = port;
|
|
|
|
this.clientID = clientID;
|
|
|
|
|
|
|
|
this.socket = new WebSocket("ws://" + this.domain + ":" + this.port + "/socket");
|
|
|
|
|
|
|
|
//Add a few events listeners
|
|
|
|
this.socket.addEventListener("open", () => {
|
|
|
|
this.serverConnected();
|
|
|
|
|
|
|
|
if(this.onConnected != null)
|
|
|
|
setTimeout(this.onConnected, 10);
|
|
|
|
});
|
|
|
|
|
|
|
|
this.socket.addEventListener("message", message => {
|
|
|
|
|
|
|
|
let data;
|
|
|
|
try {
|
|
|
|
data = JSON.parse(message.data);
|
|
|
|
} catch(e){
|
|
|
|
console.error("Could not parse message from server!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log("New message from socket", data);
|
|
|
|
|
|
|
|
this.serverMessage(data);
|
|
|
|
});
|
|
|
|
|
|
|
|
this.socket.addEventListener("error", () => {
|
|
|
|
if(this.onError != null)
|
|
|
|
setTimeout(this.onError, 0);
|
|
|
|
});
|
|
|
|
|
|
|
|
this.socket.addEventListener("close", () => {
|
|
|
|
if(this.onClosed != null)
|
|
|
|
setTimeout(this.onClosed, 0);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Method called once the client is successfully
|
|
|
|
* connected to the client
|
|
|
|
*/
|
|
|
|
serverConnected(){
|
|
|
|
|
|
|
|
//Send data to the server to identificate client
|
|
|
|
this.sendData({
|
|
|
|
client_id: this.clientID
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-01-25 09:47:42 +00:00
|
|
|
/**
|
|
|
|
* Send ready message to a peer
|
|
|
|
*
|
|
|
|
* @param {String} peerID The ID of the target peer for the message
|
|
|
|
*/
|
|
|
|
sendReadyMessage(peerID){
|
|
|
|
|
|
|
|
this.sendData({
|
|
|
|
ready_msg: true,
|
|
|
|
target_id: peerID
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-01-20 15:26:06 +00:00
|
|
|
/**
|
|
|
|
* Send a signal to the server
|
|
|
|
*
|
|
|
|
* @param target_id The ID of the target for the signal
|
|
|
|
* @param content Signal to send to the target
|
|
|
|
*/
|
|
|
|
sendSignal(target_id, content){
|
|
|
|
|
|
|
|
//Send directly the message to the server
|
|
|
|
this.sendData({
|
|
|
|
signal: content,
|
|
|
|
target_id: target_id
|
|
|
|
});
|
|
|
|
|
|
|
|
//Save the current signal being sent to be able to send
|
|
|
|
//it again in case of failure
|
|
|
|
this.pending_signal = content;
|
|
|
|
this.pending_signal_target = target_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stop to try to send the current signal message in queue
|
|
|
|
*
|
|
|
|
* This does not cancel the sending of messages already sent through
|
|
|
|
* socket
|
|
|
|
*/
|
|
|
|
cancelCurrentSignal() {
|
|
|
|
this.pending_signal = undefined;
|
|
|
|
this.pending_signal_target = undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send data to the server
|
|
|
|
*
|
|
|
|
* @param {Object} data The data to send to the server
|
|
|
|
*/
|
|
|
|
sendData(data){
|
|
|
|
console.log("Sending data to server", data);
|
|
|
|
this.socket.send(JSON.stringify(data));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method is called when the server has sent a new message to this client
|
|
|
|
*
|
|
|
|
* @param {Object} message The message sent by the server, as a JSON object
|
|
|
|
*/
|
|
|
|
serverMessage(message){
|
|
|
|
|
|
|
|
//Check if it is a callback for a pending message
|
|
|
|
if(message.signal_sent){
|
|
|
|
if(message.number_of_targets < 1 && this.pending_signal && this.pending_signal_target){
|
|
|
|
|
|
|
|
//We have to send the message again
|
|
|
|
setTimeout(() => {
|
|
|
|
this.sendSignal(this.pending_signal, this.pending_signal_target);
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
//Else we can remove from this class information about the signal being sent
|
|
|
|
this.cancelCurrentSignal();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-25 09:47:42 +00:00
|
|
|
//Check if message is a callback for a ready notice
|
|
|
|
else if(message.ready_message_sent){
|
|
|
|
|
|
|
|
if(message.number_of_targets < 1){
|
|
|
|
|
|
|
|
//Try to send message again
|
|
|
|
setTimeout(() => {
|
|
|
|
this.sendReadyMessage(message.target_id);
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if message is a ready notice
|
|
|
|
else if(message.ready_msg){
|
|
|
|
if(this.onReadyMessage != null)
|
|
|
|
this.onReadyMessage(message.source_id);
|
|
|
|
}
|
|
|
|
|
2019-01-20 15:26:06 +00:00
|
|
|
// Check if the message is a signal
|
|
|
|
else if(message.signal){
|
|
|
|
if(this.onSignal != null)
|
|
|
|
this.onSignal(message.signal, message.source_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|