|
@@ -11,6 +11,9 @@ function DataConnection(id, peer, socket, cb, options) {
|
|
}, options);
|
|
}, options);
|
|
this._options = options;
|
|
this._options = options;
|
|
|
|
|
|
|
|
+ // Connection is not open yet
|
|
|
|
+ this._open = false;
|
|
|
|
+
|
|
this._id = id;
|
|
this._id = id;
|
|
this._peer = peer;
|
|
this._peer = peer;
|
|
this._originator = (options.sdp === undefined);
|
|
this._originator = (options.sdp === undefined);
|
|
@@ -128,7 +131,8 @@ DataConnection.prototype._configureDataChannel = function() {
|
|
}
|
|
}
|
|
this._dc.onopen = function() {
|
|
this._dc.onopen = function() {
|
|
util.log('Data channel connection success');
|
|
util.log('Data channel connection success');
|
|
- self._cb(null, self);
|
|
|
|
|
|
+ self._open = true;
|
|
|
|
+ self._callback(null, self);
|
|
};
|
|
};
|
|
this._dc.onmessage = function(e) {
|
|
this._dc.onmessage = function(e) {
|
|
self._handleDataMessage(e);
|
|
self._handleDataMessage(e);
|
|
@@ -162,7 +166,7 @@ DataConnection.prototype._makeOffer = function() {
|
|
metadata: self.metadata
|
|
metadata: self.metadata
|
|
});
|
|
});
|
|
}, function(err) {
|
|
}, function(err) {
|
|
- self._cb('Failed to setLocalDescription');
|
|
|
|
|
|
+ self._callback('Failed to setLocalDescription');
|
|
util.log('Failed to setLocalDescription, ', err);
|
|
util.log('Failed to setLocalDescription, ', err);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
@@ -182,11 +186,11 @@ DataConnection.prototype._makeAnswer = function() {
|
|
dst: self._peer
|
|
dst: self._peer
|
|
});
|
|
});
|
|
}, function(err) {
|
|
}, function(err) {
|
|
- self._cb('Failed to setLocalDescription');
|
|
|
|
|
|
+ self._callback('Failed to setLocalDescription');
|
|
util.log('Failed to setLocalDescription, ', err)
|
|
util.log('Failed to setLocalDescription, ', err)
|
|
});
|
|
});
|
|
}, function(err) {
|
|
}, function(err) {
|
|
- self._cb('Failed to create answer');
|
|
|
|
|
|
+ self._callback('Failed to create answer');
|
|
util.log('Failed to create answer, ', err)
|
|
util.log('Failed to create answer, ', err)
|
|
});
|
|
});
|
|
};
|
|
};
|
|
@@ -204,6 +208,13 @@ DataConnection.prototype._cleanup = function() {
|
|
this.emit('close', this._peer);
|
|
this.emit('close', this._peer);
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+// Make sure _cb only gets called once
|
|
|
|
+DataConnection.prototype._callback = function(err, dc) {
|
|
|
|
+ if (this._cb) {
|
|
|
|
+ this._cb(err, dc);
|
|
|
|
+ delete this._cb;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
|
|
|
|
// Handles a DataChannel message.
|
|
// Handles a DataChannel message.
|
|
@@ -233,11 +244,16 @@ DataConnection.prototype._handleDataMessage = function(e) {
|
|
DataConnection.prototype.close = function() {
|
|
DataConnection.prototype.close = function() {
|
|
this._cleanup();
|
|
this._cleanup();
|
|
var self = this;
|
|
var self = this;
|
|
- this._socket.send({
|
|
|
|
- type: 'LEAVE',
|
|
|
|
- dst: self._peer,
|
|
|
|
- src: self._id,
|
|
|
|
- });
|
|
|
|
|
|
+ if (this._open) {
|
|
|
|
+ this._socket.send({
|
|
|
|
+ type: 'LEAVE',
|
|
|
|
+ dst: self._peer,
|
|
|
|
+ src: self._id,
|
|
|
|
+ });
|
|
|
|
+ } else {
|
|
|
|
+ this._callback('Could not connect to peer ' + this._peer);
|
|
|
|
+ }
|
|
|
|
+ this._open = false;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -281,7 +297,7 @@ DataConnection.prototype.handleSDP = function(message) {
|
|
self._makeAnswer();
|
|
self._makeAnswer();
|
|
}
|
|
}
|
|
}, function(err) {
|
|
}, function(err) {
|
|
- self._cb('Failed to setRemoteDescription');
|
|
|
|
|
|
+ self._callback('Failed to setRemoteDescription');
|
|
util.log('Failed to setRemoteDescription, ', err);
|
|
util.log('Failed to setRemoteDescription, ', err);
|
|
});
|
|
});
|
|
};
|
|
};
|