mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Use data channel ids
This commit is contained in:
parent
960b010d30
commit
9d456d5d17
3 changed files with 148 additions and 144 deletions
|
@ -128,7 +128,7 @@ use servo_media::player::video::VideoFrame;
|
||||||
use servo_media::player::Player;
|
use servo_media::player::Player;
|
||||||
use servo_media::streams::registry::MediaStreamId;
|
use servo_media::streams::registry::MediaStreamId;
|
||||||
use servo_media::streams::MediaStreamType;
|
use servo_media::streams::MediaStreamType;
|
||||||
use servo_media::webrtc::{WebRtcController, WebRtcDataChannelBackend};
|
use servo_media::webrtc::WebRtcController;
|
||||||
use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl};
|
use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -607,7 +607,6 @@ unsafe_no_jsmanaged_fields!(NodeId);
|
||||||
unsafe_no_jsmanaged_fields!(AnalysisEngine, DistanceModel, PanningModel, ParamType);
|
unsafe_no_jsmanaged_fields!(AnalysisEngine, DistanceModel, PanningModel, ParamType);
|
||||||
unsafe_no_jsmanaged_fields!(Arc<Mutex<dyn Player>>);
|
unsafe_no_jsmanaged_fields!(Arc<Mutex<dyn Player>>);
|
||||||
unsafe_no_jsmanaged_fields!(WebRtcController);
|
unsafe_no_jsmanaged_fields!(WebRtcController);
|
||||||
unsafe_no_jsmanaged_fields!(Box<dyn WebRtcDataChannelBackend>);
|
|
||||||
unsafe_no_jsmanaged_fields!(MediaStreamId, MediaStreamType);
|
unsafe_no_jsmanaged_fields!(MediaStreamId, MediaStreamType);
|
||||||
unsafe_no_jsmanaged_fields!(Mutex<MediaFrameRenderer>);
|
unsafe_no_jsmanaged_fields!(Mutex<MediaFrameRenderer>);
|
||||||
unsafe_no_jsmanaged_fields!(ResourceFetchTiming);
|
unsafe_no_jsmanaged_fields!(ResourceFetchTiming);
|
||||||
|
|
|
@ -2,39 +2,32 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
|
||||||
use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelInit;
|
use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelInit;
|
||||||
use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelMethods;
|
use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelMethods;
|
||||||
use crate::dom::bindings::codegen::Bindings::RTCErrorBinding::{RTCErrorDetailType, RTCErrorInit};
|
use crate::dom::bindings::codegen::Bindings::RTCErrorBinding::{RTCErrorDetailType, RTCErrorInit};
|
||||||
use crate::dom::bindings::inheritance::Castable;
|
use crate::dom::bindings::inheritance::Castable;
|
||||||
use crate::dom::bindings::refcounted::Trusted;
|
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
||||||
use crate::dom::bindings::root::DomRoot;
|
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||||
use crate::dom::bindings::str::{DOMString, USVString};
|
use crate::dom::bindings::str::{DOMString, USVString};
|
||||||
use crate::dom::blob::Blob;
|
|
||||||
use crate::dom::event::{Event, EventBubbles, EventCancelable};
|
use crate::dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
use crate::dom::eventtarget::EventTarget;
|
use crate::dom::eventtarget::EventTarget;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::messageevent::MessageEvent;
|
use crate::dom::messageevent::MessageEvent;
|
||||||
use crate::dom::rtcerror::RTCError;
|
use crate::dom::rtcerror::RTCError;
|
||||||
use crate::dom::rtcerrorevent::RTCErrorEvent;
|
use crate::dom::rtcerrorevent::RTCErrorEvent;
|
||||||
use crate::task_source::TaskSource;
|
use crate::dom::rtcpeerconnection::RTCPeerConnection;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use js::conversions::ToJSValConvertible;
|
use js::conversions::ToJSValConvertible;
|
||||||
use js::jsapi::JSAutoRealm;
|
use js::jsapi::JSAutoRealm;
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::CustomAutoRooterGuard;
|
use servo_media::webrtc::{DataChannelId, DataChannelInit, DataChannelMessage, WebRtcError};
|
||||||
use js::typedarray::{ArrayBuffer, ArrayBufferView};
|
|
||||||
use servo_media::webrtc::{
|
|
||||||
WebRtcController, WebRtcDataChannelBackend, WebRtcDataChannelInit, WebRtcError,
|
|
||||||
};
|
|
||||||
use std::sync::mpsc;
|
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct RTCDataChannel {
|
pub struct RTCDataChannel {
|
||||||
eventtarget: EventTarget,
|
eventtarget: EventTarget,
|
||||||
#[ignore_malloc_size_of = "defined in servo-media"]
|
#[ignore_malloc_size_of = "defined in servo-media"]
|
||||||
channel: Box<dyn WebRtcDataChannelBackend>,
|
servo_media_id: DataChannelId,
|
||||||
|
peer_connection: Dom<RTCPeerConnection>,
|
||||||
label: USVString,
|
label: USVString,
|
||||||
ordered: bool,
|
ordered: bool,
|
||||||
max_packet_life_time: Option<u16>,
|
max_packet_life_time: Option<u16>,
|
||||||
|
@ -45,30 +38,29 @@ pub struct RTCDataChannel {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RTCDataChannel {
|
impl RTCDataChannel {
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new_inherited(
|
pub fn new_inherited(
|
||||||
webrtc_controller: &DomRefCell<Option<WebRtcController>>,
|
peer_connection: &RTCPeerConnection,
|
||||||
label: USVString,
|
label: USVString,
|
||||||
options: &RTCDataChannelInit,
|
options: &RTCDataChannelInit,
|
||||||
channel: Option<Box<dyn WebRtcDataChannelBackend>>,
|
servo_media_id: Option<DataChannelId>,
|
||||||
) -> RTCDataChannel {
|
) -> RTCDataChannel {
|
||||||
let webrtc = webrtc_controller.borrow();
|
let mut init: DataChannelInit = options.into();
|
||||||
let webrtc = webrtc.as_ref().unwrap();
|
|
||||||
|
|
||||||
let (sender, receiver) = mpsc::channel::<Box<dyn WebRtcDataChannelBackend>>();
|
|
||||||
|
|
||||||
let mut init: WebRtcDataChannelInit = options.into();
|
|
||||||
init.label = label.to_string();
|
init.label = label.to_string();
|
||||||
|
|
||||||
let channel = if channel.is_none() {
|
let controller = peer_connection.get_webrtc_controller().borrow();
|
||||||
webrtc.create_data_channel(init, sender);
|
let servo_media_id = servo_media_id.unwrap_or(
|
||||||
receiver.recv().unwrap()
|
controller
|
||||||
} else {
|
.as_ref()
|
||||||
channel.unwrap()
|
.unwrap()
|
||||||
};
|
.create_data_channel(init)
|
||||||
|
.expect("Expected data channel id"),
|
||||||
|
);
|
||||||
|
|
||||||
RTCDataChannel {
|
let channel = RTCDataChannel {
|
||||||
eventtarget: EventTarget::new_inherited(),
|
eventtarget: EventTarget::new_inherited(),
|
||||||
channel,
|
servo_media_id,
|
||||||
|
peer_connection: Dom::from_ref(&peer_connection),
|
||||||
label,
|
label,
|
||||||
ordered: options.ordered,
|
ordered: options.ordered,
|
||||||
max_packet_life_time: options.maxPacketLifeTime,
|
max_packet_life_time: options.maxPacketLifeTime,
|
||||||
|
@ -76,96 +68,34 @@ impl RTCDataChannel {
|
||||||
protocol: options.protocol.clone(),
|
protocol: options.protocol.clone(),
|
||||||
negotiated: options.negotiated,
|
negotiated: options.negotiated,
|
||||||
id: options.id,
|
id: options.id,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
peer_connection.register_data_channel(servo_media_id, &channel);
|
||||||
|
|
||||||
|
channel
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
global: &GlobalScope,
|
global: &GlobalScope,
|
||||||
webrtc_controller: &DomRefCell<Option<WebRtcController>>,
|
peer_connection: &RTCPeerConnection,
|
||||||
label: USVString,
|
label: USVString,
|
||||||
options: &RTCDataChannelInit,
|
options: &RTCDataChannelInit,
|
||||||
channel: Option<Box<dyn WebRtcDataChannelBackend>>,
|
servo_media_id: Option<DataChannelId>,
|
||||||
) -> DomRoot<RTCDataChannel> {
|
) -> DomRoot<RTCDataChannel> {
|
||||||
let rtc_data_channel = reflect_dom_object(
|
let rtc_data_channel = reflect_dom_object(
|
||||||
Box::new(RTCDataChannel::new_inherited(
|
Box::new(RTCDataChannel::new_inherited(
|
||||||
webrtc_controller,
|
peer_connection,
|
||||||
label,
|
label,
|
||||||
options,
|
options,
|
||||||
channel,
|
servo_media_id,
|
||||||
)),
|
)),
|
||||||
global,
|
global,
|
||||||
);
|
);
|
||||||
|
|
||||||
let trusted = Trusted::new(&*rtc_data_channel);
|
|
||||||
let (task_source, canceller) = global
|
|
||||||
.as_window()
|
|
||||||
.task_manager()
|
|
||||||
.networking_task_source_with_canceller();
|
|
||||||
|
|
||||||
let this = trusted.clone();
|
|
||||||
rtc_data_channel.channel.set_on_open(Box::new(move || {
|
|
||||||
let this = this.clone();
|
|
||||||
let _ = task_source.queue_with_canceller(
|
|
||||||
task!(on_open: move || {
|
|
||||||
this.root().on_open();
|
|
||||||
}),
|
|
||||||
&canceller,
|
|
||||||
);
|
|
||||||
}));
|
|
||||||
|
|
||||||
let this = trusted.clone();
|
|
||||||
let (task_source, canceller) = global
|
|
||||||
.as_window()
|
|
||||||
.task_manager()
|
|
||||||
.networking_task_source_with_canceller();
|
|
||||||
rtc_data_channel.channel.set_on_close(Box::new(move || {
|
|
||||||
let this = this.clone();
|
|
||||||
let _ = task_source.queue_with_canceller(
|
|
||||||
task!(on_close: move || {
|
|
||||||
this.root().on_close();
|
|
||||||
}),
|
|
||||||
&canceller,
|
|
||||||
);
|
|
||||||
}));
|
|
||||||
|
|
||||||
let this = trusted.clone();
|
|
||||||
let (task_source, canceller) = global
|
|
||||||
.as_window()
|
|
||||||
.task_manager()
|
|
||||||
.networking_task_source_with_canceller();
|
|
||||||
rtc_data_channel
|
|
||||||
.channel
|
|
||||||
.set_on_error(Box::new(move |error| {
|
|
||||||
let this = this.clone();
|
|
||||||
let _ = task_source.queue_with_canceller(
|
|
||||||
task!(on_error: move || {
|
|
||||||
this.root().on_error(error);
|
|
||||||
}),
|
|
||||||
&canceller,
|
|
||||||
);
|
|
||||||
}));
|
|
||||||
|
|
||||||
let this = trusted.clone();
|
|
||||||
let (task_source, canceller) = global
|
|
||||||
.as_window()
|
|
||||||
.task_manager()
|
|
||||||
.networking_task_source_with_canceller();
|
|
||||||
rtc_data_channel
|
|
||||||
.channel
|
|
||||||
.set_on_message(Box::new(move |message| {
|
|
||||||
let this = this.clone();
|
|
||||||
let _ = task_source.queue_with_canceller(
|
|
||||||
task!(on_message: move || {
|
|
||||||
this.root().on_message(message);
|
|
||||||
}),
|
|
||||||
&canceller,
|
|
||||||
);
|
|
||||||
}));
|
|
||||||
|
|
||||||
rtc_data_channel
|
rtc_data_channel
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_open(&self) {
|
pub fn on_open(&self) {
|
||||||
let event = Event::new(
|
let event = Event::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
atom!("open"),
|
atom!("open"),
|
||||||
|
@ -175,7 +105,7 @@ impl RTCDataChannel {
|
||||||
event.upcast::<Event>().fire(self.upcast());
|
event.upcast::<Event>().fire(self.upcast());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_close(&self) {
|
pub fn on_close(&self) {
|
||||||
let event = Event::new(
|
let event = Event::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
atom!("close"),
|
atom!("close"),
|
||||||
|
@ -183,9 +113,12 @@ impl RTCDataChannel {
|
||||||
EventCancelable::NotCancelable,
|
EventCancelable::NotCancelable,
|
||||||
);
|
);
|
||||||
event.upcast::<Event>().fire(self.upcast());
|
event.upcast::<Event>().fire(self.upcast());
|
||||||
|
|
||||||
|
self.peer_connection
|
||||||
|
.unregister_data_channel(&self.servo_media_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_error(&self, error: WebRtcError) {
|
pub fn on_error(&self, error: WebRtcError) {
|
||||||
let init = RTCErrorInit {
|
let init = RTCErrorInit {
|
||||||
errorDetail: RTCErrorDetailType::Data_channel_failure,
|
errorDetail: RTCErrorDetailType::Data_channel_failure,
|
||||||
httpRequestStatusCode: None,
|
httpRequestStatusCode: None,
|
||||||
|
@ -203,9 +136,10 @@ impl RTCDataChannel {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn on_message(&self, text: String) {
|
pub fn on_message(&self, message: DataChannelMessage) {
|
||||||
// XXX(ferjm) Support binary messages
|
// XXX(ferjm) Support binary messages
|
||||||
unsafe {
|
match message {
|
||||||
|
DataChannelMessage::Text(text) => unsafe {
|
||||||
let global = self.global();
|
let global = self.global();
|
||||||
let cx = global.get_cx();
|
let cx = global.get_cx();
|
||||||
let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get());
|
let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get());
|
||||||
|
@ -220,10 +154,19 @@ impl RTCDataChannel {
|
||||||
None,
|
None,
|
||||||
vec![],
|
vec![],
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
DataChannelMessage::Binary(_) => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for RTCDataChannel {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.peer_connection
|
||||||
|
.unregister_data_channel(&self.servo_media_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl RTCDataChannelMethods for RTCDataChannel {
|
impl RTCDataChannelMethods for RTCDataChannel {
|
||||||
// https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onopen
|
// https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onopen
|
||||||
event_handler!(open, GetOnopen, SetOnopen);
|
event_handler!(open, GetOnopen, SetOnopen);
|
||||||
|
@ -282,16 +225,24 @@ impl RTCDataChannelMethods for RTCDataChannel {
|
||||||
// fn SetBufferedAmountLowThreshold(&self, value: u32) -> ();
|
// fn SetBufferedAmountLowThreshold(&self, value: u32) -> ();
|
||||||
|
|
||||||
// https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-close
|
// https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-close
|
||||||
fn Close(&self) {}
|
fn Close(&self) {
|
||||||
|
let controller = self.peer_connection.get_webrtc_controller().borrow();
|
||||||
|
controller
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.close_data_channel(&self.servo_media_id);
|
||||||
|
}
|
||||||
|
|
||||||
// fn BinaryType(&self) -> DOMString;
|
// fn BinaryType(&self) -> DOMString;
|
||||||
// fn SetBinaryType(&self, value: DOMString) -> ();
|
// fn SetBinaryType(&self, value: DOMString) -> ();
|
||||||
|
|
||||||
// https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send
|
// https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send
|
||||||
fn Send(&self, data: USVString) {
|
fn Send(&self, data: USVString) {
|
||||||
if let Err(error) = self.channel.send(&data.0) {
|
let controller = self.peer_connection.get_webrtc_controller().borrow();
|
||||||
warn!("Could not send data channel message. Error: {:?}", error);
|
controller
|
||||||
}
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.send_data_channel_message(&self.servo_media_id, DataChannelMessage::Text(data.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-1
|
// https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-1
|
||||||
|
@ -304,9 +255,9 @@ impl RTCDataChannelMethods for RTCDataChannel {
|
||||||
// fn Send___(&self, data: CustomAutoRooterGuard<ArrayBufferView>) -> () {}
|
// fn Send___(&self, data: CustomAutoRooterGuard<ArrayBufferView>) -> () {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&RTCDataChannelInit> for WebRtcDataChannelInit {
|
impl From<&RTCDataChannelInit> for DataChannelInit {
|
||||||
fn from(init: &RTCDataChannelInit) -> WebRtcDataChannelInit {
|
fn from(init: &RTCDataChannelInit) -> DataChannelInit {
|
||||||
WebRtcDataChannelInit {
|
DataChannelInit {
|
||||||
label: String::new(),
|
label: String::new(),
|
||||||
id: init.id,
|
id: init.id,
|
||||||
max_packet_life_time: init.maxPacketLifeTime,
|
max_packet_life_time: init.maxPacketLifeTime,
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::dom::bindings::inheritance::Castable;
|
||||||
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
||||||
use crate::dom::bindings::reflector::reflect_dom_object;
|
use crate::dom::bindings::reflector::reflect_dom_object;
|
||||||
use crate::dom::bindings::reflector::DomObject;
|
use crate::dom::bindings::reflector::DomObject;
|
||||||
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
|
||||||
use crate::dom::bindings::str::USVString;
|
use crate::dom::bindings::str::USVString;
|
||||||
use crate::dom::event::{Event, EventBubbles, EventCancelable};
|
use crate::dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
use crate::dom::eventtarget::EventTarget;
|
use crate::dom::eventtarget::EventTarget;
|
||||||
|
@ -44,12 +44,14 @@ use dom_struct::dom_struct;
|
||||||
use servo_media::streams::registry::MediaStreamId;
|
use servo_media::streams::registry::MediaStreamId;
|
||||||
use servo_media::streams::MediaStreamType;
|
use servo_media::streams::MediaStreamType;
|
||||||
use servo_media::webrtc::{
|
use servo_media::webrtc::{
|
||||||
BundlePolicy, GatheringState, IceCandidate, IceConnectionState, SdpType, SessionDescription,
|
BundlePolicy, DataChannelEvent, DataChannelId, GatheringState, IceCandidate,
|
||||||
SignalingState, WebRtcController, WebRtcDataChannelBackend, WebRtcSignaller,
|
IceConnectionState, SdpType, SessionDescription, SignalingState, WebRtcController,
|
||||||
|
WebRtcSignaller,
|
||||||
};
|
};
|
||||||
use servo_media::ServoMedia;
|
use servo_media::ServoMedia;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -70,6 +72,8 @@ pub struct RTCPeerConnection {
|
||||||
gathering_state: Cell<RTCIceGatheringState>,
|
gathering_state: Cell<RTCIceGatheringState>,
|
||||||
ice_connection_state: Cell<RTCIceConnectionState>,
|
ice_connection_state: Cell<RTCIceConnectionState>,
|
||||||
signaling_state: Cell<RTCSignalingState>,
|
signaling_state: Cell<RTCSignalingState>,
|
||||||
|
#[ignore_malloc_size_of = "defined in servo-media"]
|
||||||
|
data_channels: DomRefCell<HashMap<DataChannelId, Dom<RTCDataChannel>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RTCSignaller {
|
struct RTCSignaller {
|
||||||
|
@ -146,13 +150,18 @@ impl WebRtcSignaller for RTCSignaller {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_data_channel(&self, channel: Box<dyn WebRtcDataChannelBackend>) {
|
fn on_data_channel_event(
|
||||||
|
&self,
|
||||||
|
channel: DataChannelId,
|
||||||
|
event: DataChannelEvent,
|
||||||
|
_: &WebRtcController,
|
||||||
|
) {
|
||||||
// XXX(ferjm) get label and options from channel properties.
|
// XXX(ferjm) get label and options from channel properties.
|
||||||
let this = self.trusted.clone();
|
let this = self.trusted.clone();
|
||||||
let _ = self.task_source.queue_with_canceller(
|
let _ = self.task_source.queue_with_canceller(
|
||||||
task!(on_data_channel: move || {
|
task!(on_data_channel_event: move || {
|
||||||
let this = this.root();
|
let this = this.root();
|
||||||
this.on_data_channel(channel);
|
this.on_data_channel_event(channel, event);
|
||||||
}),
|
}),
|
||||||
&self.canceller,
|
&self.canceller,
|
||||||
);
|
);
|
||||||
|
@ -160,6 +169,7 @@ impl WebRtcSignaller for RTCSignaller {
|
||||||
|
|
||||||
fn close(&self) {
|
fn close(&self) {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
// XXX(ferjm) close all data channels.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,6 +187,7 @@ impl RTCPeerConnection {
|
||||||
gathering_state: Cell::new(RTCIceGatheringState::New),
|
gathering_state: Cell::new(RTCIceGatheringState::New),
|
||||||
ice_connection_state: Cell::new(RTCIceConnectionState::New),
|
ice_connection_state: Cell::new(RTCIceConnectionState::New),
|
||||||
signaling_state: Cell::new(RTCSignalingState::Stable),
|
signaling_state: Cell::new(RTCSignalingState::Stable),
|
||||||
|
data_channels: DomRefCell::new(HashMap::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,6 +226,10 @@ impl RTCPeerConnection {
|
||||||
Ok(RTCPeerConnection::new(&window.global(), config))
|
Ok(RTCPeerConnection::new(&window.global(), config))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_webrtc_controller(&self) -> &DomRefCell<Option<WebRtcController>> {
|
||||||
|
&self.controller
|
||||||
|
}
|
||||||
|
|
||||||
fn make_signaller(&self) -> Box<dyn WebRtcSignaller> {
|
fn make_signaller(&self) -> Box<dyn WebRtcSignaller> {
|
||||||
let trusted = Trusted::new(self);
|
let trusted = Trusted::new(self);
|
||||||
let (task_source, canceller) = self
|
let (task_source, canceller) = self
|
||||||
|
@ -272,22 +287,61 @@ impl RTCPeerConnection {
|
||||||
event.upcast::<Event>().fire(self.upcast());
|
event.upcast::<Event>().fire(self.upcast());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_data_channel(&self, channel: Box<dyn WebRtcDataChannelBackend>) {
|
fn on_data_channel_event(&self, channel_id: DataChannelId, event: DataChannelEvent) {
|
||||||
if self.closed.get() {
|
if self.closed.get() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match event {
|
||||||
|
DataChannelEvent::NewChannel => {
|
||||||
let channel = RTCDataChannel::new(
|
let channel = RTCDataChannel::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
&self.controller,
|
&self,
|
||||||
USVString::from("".to_owned()),
|
USVString::from("".to_owned()),
|
||||||
&RTCDataChannelInit::empty(),
|
&RTCDataChannelInit::empty(),
|
||||||
Some(channel),
|
Some(channel_id),
|
||||||
);
|
);
|
||||||
|
|
||||||
let event =
|
self.register_data_channel(channel_id, &channel);
|
||||||
RTCDataChannelEvent::new(&self.global(), atom!("datachannel"), false, false, &channel);
|
|
||||||
|
let event = RTCDataChannelEvent::new(
|
||||||
|
&self.global(),
|
||||||
|
atom!("datachannel"),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&channel,
|
||||||
|
);
|
||||||
event.upcast::<Event>().fire(self.upcast());
|
event.upcast::<Event>().fire(self.upcast());
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
if let Some(ref channel) = self.data_channels.borrow().get(&channel_id) {
|
||||||
|
match event {
|
||||||
|
DataChannelEvent::Open => channel.on_open(),
|
||||||
|
DataChannelEvent::Close => channel.on_close(),
|
||||||
|
DataChannelEvent::Error(error) => channel.on_error(error),
|
||||||
|
DataChannelEvent::OnMessage(message) => channel.on_message(message),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
debug_assert!(false, "Got an event for an unregistered data channel");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn register_data_channel(&self, id: DataChannelId, channel: &RTCDataChannel) {
|
||||||
|
if self
|
||||||
|
.data_channels
|
||||||
|
.borrow_mut()
|
||||||
|
.insert(id, Dom::from_ref(channel))
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
|
debug_assert!(false, "Could not register data channel");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unregister_data_channel(&self, id: &DataChannelId) {
|
||||||
|
self.data_channels.borrow_mut().remove(&id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://www.w3.org/TR/webrtc/#update-ice-gathering-state
|
/// https://www.w3.org/TR/webrtc/#update-ice-gathering-state
|
||||||
|
@ -677,7 +731,7 @@ impl RTCPeerConnectionMethods for RTCPeerConnection {
|
||||||
label: USVString,
|
label: USVString,
|
||||||
init: &RTCDataChannelInit,
|
init: &RTCDataChannelInit,
|
||||||
) -> DomRoot<RTCDataChannel> {
|
) -> DomRoot<RTCDataChannel> {
|
||||||
RTCDataChannel::new(&self.global(), &self.controller, label, init, None)
|
RTCDataChannel::new(&self.global(), &self, label, init, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue