我正在编写一个使用 webrtc nativeapi 与浏览器通信的程序,浏览器发起一个提议,我的程序回答它。
在我的需要中,浏览器端不发送任何流,我不希望浏览器端调用 CreateDataChannel函数,它只提供一个报价,然后等待,等待我的程序中只有一个数据通道。
问题是:在我的程序中,当接收到报价消息时,它首先调用 CreateDatachannel,然后处理报价消息,调用 SetRemoteDescription 和 CreateAnswer。这不起作用,我的数据通道没有成功建立,数据通道的状态保持在状态。在connecting
浏览器端,ondatachannel 事件从未调用过。
那么,CreateDatachannel 是否只能在 CreateOffer 端调用?
编辑:这是我创建的程序的报价:
{"type":"offer","sdp":"v=0
o=- 9054715805476854106 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0
a=extmap-allow-mixed
a=msid-semantic: WMS
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=ice-ufrag:W/Jh
a=ice-pwd:Buy4NhHzquBPT5dqvRKeued0
a=ice-options:trickle
a=fingerprint:sha-256 F5:BC:CE:66:EE:63:F2:76:1B:4A:5F:68:49:AB:4A:98:23:10:53:87:00:82:81:20:F0:64:F1:B9:BC:88:F5:3A
a=setup:actpass
a=mid:0
a=sctp-port:5000
a=max-message-size:262144
"}
PS:如果浏览器端调用 CreateDatachannel 创建一个虚拟数据通道,一切正常,浏览器 ondatachannel 事件被触发,它可以从我的程序接收消息。
代码非常简单。我的程序,创建对等连接和数据通道:
webrtc::PeerConnectionInterface::RTCConfiguration config;
config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
config.enable_dtls_srtp = true;
webrtc::PeerConnectionInterface::IceServer server;
server.uri = RTC2Config::get().GetTurnServer();
config.servers.push_back(server);
pc = peerFactory->CreatePeerConnection(config, nullptr, nullptr, this);
webrtc::DataChannelInit channelConfig;
auto temp = pc->CreateDataChannelOrError("rtc_node", &channelConfig);
if (temp.ok())
{
this->channelRTCNode = temp.value();
this->channelRTCNode->RegisterObserver(&obsChannelRTCNode);
std::cout << "create datachannel ok";
}
else
{
std::cout << "create datachannel error";
}
工艺报价:
void PeerClient::SetOffer(std::string offer)
{
this->thSignaling->PostTask(RTC_FROM_HERE, [this,offer]()
{
auto sd = webrtc::CreateSessionDescription(webrtc::SdpType::kOffer, offer);
pc->SetRemoteDescription(
std::move(sd),
new SetDescriptionDummyObserver());
pc->CreateAnswer(
csdObserver, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
});
}
浏览器端:
peer_connection_client = new RTCPeerConnection(peer_connection_config, peer_connection_options);
peer_connection_client.onicecandidate = function (e) {
onIceCandidate(peer_id, e);
};
peer_connection_client.onconnecting = onSessionConnecting;
peer_connection_client.onopen = onSessionOpened;
peer_connection_client.onaddstream = onRemoteStreamAdded;
peer_connection_client.onremovestream = onRemoteStreamRemoved;
// data_channel_sender = peer_connection_client.createDataChannel('dataChannel');
// data_channel_sender.onopen = onSendChannelStateChange;
// data_channel_sender.onclose = onSendChannelStateChange;
peer_connection_client.ondatachannel = receiveChannelCallback; // never called if above 3 lines are commented
peer_connection_client.createOffer(offer_options).then(
onCreateOfferSuccess,
onCreateSessionDescriptionError
);