mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 03:40:20 +02:00
Merge branch 'webapp' into dev/webrtc-packet
# Conflicts: # libraries/networking/src/webrtc/WebRTCDataChannels.h
This commit is contained in:
commit
ed13cbd01b
3 changed files with 118 additions and 33 deletions
|
@ -11,7 +11,7 @@ endif ()
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
# we need ws2_32.lib on windows, but it's static so we don't bubble it up
|
# we need ws2_32.lib on windows, but it's static so we don't bubble it up
|
||||||
# Libraries needed for WebRTC: security.log winmm.lib
|
# Libraries needed for WebRTC: security.lib winmm.lib
|
||||||
target_link_libraries(${TARGET_NAME} ws2_32.lib security.lib winmm.lib)
|
target_link_libraries(${TARGET_NAME} ws2_32.lib security.lib winmm.lib)
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
# IOKit is needed for getting machine fingerprint
|
# IOKit is needed for getting machine fingerprint
|
||||||
|
|
|
@ -21,8 +21,9 @@
|
||||||
// - https://webrtc.googlesource.com/src/+/master/api/peer_connection_interface.h
|
// - https://webrtc.googlesource.com/src/+/master/api/peer_connection_interface.h
|
||||||
|
|
||||||
const std::string ICE_SERVER_URI = "stun://ice.vircadia.com:7337";
|
const std::string ICE_SERVER_URI = "stun://ice.vircadia.com:7337";
|
||||||
|
const int MAX_WEBRTC_BUFFER_SIZE = 16777216; // 16MB
|
||||||
|
|
||||||
#define WEBRTC_DEBUG
|
// #define WEBRTC_DEBUG
|
||||||
|
|
||||||
using namespace webrtc;
|
using namespace webrtc;
|
||||||
|
|
||||||
|
@ -104,6 +105,10 @@ void WDCPeerConnectionObserver::OnDataChannel(rtc::scoped_refptr<DataChannelInte
|
||||||
}
|
}
|
||||||
|
|
||||||
void WDCPeerConnectionObserver::OnConnectionChange(PeerConnectionInterface::PeerConnectionState newState) {
|
void WDCPeerConnectionObserver::OnConnectionChange(PeerConnectionInterface::PeerConnectionState newState) {
|
||||||
|
#ifdef WEBRTC_DEBUG
|
||||||
|
qCDebug(networking_webrtc) << "WDCPeerConnectionObserver::OnConnectionChange()" << (uint)newState;
|
||||||
|
#endif
|
||||||
|
_parent->onPeerConnectionStateChanged(newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -126,9 +131,9 @@ void WDCDataChannelObserver::OnMessage(const DataBuffer& buffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WDCConnection::WDCConnection(quint16 webSocketID, WebRTCDataChannels* parent) :
|
WDCConnection::WDCConnection(WebRTCDataChannels* parent, quint16 webSocketID) :
|
||||||
_webSocketID(webSocketID),
|
_parent(parent),
|
||||||
_parent(parent)
|
_webSocketID(webSocketID)
|
||||||
{
|
{
|
||||||
#ifdef WEBRTC_DEBUG
|
#ifdef WEBRTC_DEBUG
|
||||||
qCDebug(networking_webrtc) << "WDCConnection::WDCConnection() :" << webSocketID;
|
qCDebug(networking_webrtc) << "WDCConnection::WDCConnection() :" << webSocketID;
|
||||||
|
@ -255,6 +260,20 @@ void WDCConnection::sendIceCandidate(const IceCandidateInterface* candidate) {
|
||||||
_parent->sendSignalingMessage(jsonObject);
|
_parent->sendSignalingMessage(jsonObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WDCConnection::onPeerConnectionStateChanged(PeerConnectionInterface::PeerConnectionState state) {
|
||||||
|
#ifdef WEBRTC_DEBUG
|
||||||
|
const char* STATES[] = {
|
||||||
|
"New",
|
||||||
|
"Connecting",
|
||||||
|
"Connected",
|
||||||
|
"Disconnected",
|
||||||
|
"Failed",
|
||||||
|
"Closed"
|
||||||
|
};
|
||||||
|
qCDebug(networking_webrtc) << "WDCConnection::onPeerConnectionStateChanged() :" << (int)state << STATES[(int)state];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void WDCConnection::onDataChannelOpened(rtc::scoped_refptr<DataChannelInterface> dataChannel) {
|
void WDCConnection::onDataChannelOpened(rtc::scoped_refptr<DataChannelInterface> dataChannel) {
|
||||||
#ifdef WEBRTC_DEBUG
|
#ifdef WEBRTC_DEBUG
|
||||||
qCDebug(networking_webrtc) << "WDCConnection::onDataChannelOpened() :"
|
qCDebug(networking_webrtc) << "WDCConnection::onDataChannelOpened() :"
|
||||||
|
@ -278,16 +297,19 @@ void WDCConnection::onDataChannelOpened(rtc::scoped_refptr<DataChannelInterface>
|
||||||
void WDCConnection::onDataChannelStateChanged() {
|
void WDCConnection::onDataChannelStateChanged() {
|
||||||
auto state = _dataChannel->state();
|
auto state = _dataChannel->state();
|
||||||
#ifdef WEBRTC_DEBUG
|
#ifdef WEBRTC_DEBUG
|
||||||
qCDebug(networking_webrtc) << "WDCConnection::dataChannelStateChanged() :" << (int)state
|
qCDebug(networking_webrtc) << "WDCConnection::onDataChannelStateChanged() :" << (int)state
|
||||||
<< DataChannelInterface::DataStateString(state);
|
<< DataChannelInterface::DataStateString(state);
|
||||||
#endif
|
#endif
|
||||||
if (state == DataChannelInterface::kClosed) {
|
if (state == DataChannelInterface::kClosed) {
|
||||||
_dataChannel->Close();
|
// Close data channel.
|
||||||
|
_dataChannel->UnregisterObserver();
|
||||||
|
_dataChannelObserver = nullptr;
|
||||||
_dataChannel = nullptr;
|
_dataChannel = nullptr;
|
||||||
// WEBRTC FIXME: The following line causes the _peerConnectionFactory to fail.
|
#ifdef WEBRTC_DEBUG
|
||||||
//_peerConnection->Close();
|
qCDebug(networking_webrtc) << "Disposed of data channel";
|
||||||
//_peerConnection = nullptr;
|
#endif
|
||||||
_parent->onDataChannelClosed(this, _dataChannelID);
|
// Close peer connection.
|
||||||
|
_parent->closePeerConnection(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,14 +343,27 @@ bool WDCConnection::sendDataMessage(const DataBuffer& buffer) {
|
||||||
#ifdef WEBRTC_DEBUG
|
#ifdef WEBRTC_DEBUG
|
||||||
qCDebug(networking_webrtc) << "WDCConnection::sendDataMessage()";
|
qCDebug(networking_webrtc) << "WDCConnection::sendDataMessage()";
|
||||||
#endif
|
#endif
|
||||||
const int MAX_WEBRTC_BUFFER_SIZE = 16 * 1024 * 1024; // 16MB
|
|
||||||
if (_dataChannel->buffered_amount() + buffer.size() > MAX_WEBRTC_BUFFER_SIZE) {
|
if (_dataChannel->buffered_amount() + buffer.size() > MAX_WEBRTC_BUFFER_SIZE) {
|
||||||
// Don't send, otherwise the data channel will be closed.
|
// Don't send, otherwise the data channel will be closed.
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
qCDebug(networking_webrtc) << "WebRTC send buffer overflow";
|
||||||
}
|
}
|
||||||
return _dataChannel->Send(buffer);
|
return _dataChannel->Send(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WDCConnection::closePeerConnection() {
|
||||||
|
#ifdef WEBRTC_DEBUG
|
||||||
|
qCDebug(networking_webrtc) << "WDCConnection::closePeerConnection()";
|
||||||
|
#endif
|
||||||
|
_peerConnection->Close();
|
||||||
|
_peerConnection = nullptr;
|
||||||
|
_peerConnectionObserver = nullptr;
|
||||||
|
#ifdef WEBRTC_DEBUG
|
||||||
|
qCDebug(networking_webrtc) << "Disposed of peer connection";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WebRTCDataChannels::WebRTCDataChannels(QObject* parent, NodeType_t nodeType) :
|
WebRTCDataChannels::WebRTCDataChannels(QObject* parent, NodeType_t nodeType) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
|
@ -358,6 +393,9 @@ WebRTCDataChannels::WebRTCDataChannels(QObject* parent, NodeType_t nodeType) :
|
||||||
if (!_peerConnectionFactory) {
|
if (!_peerConnectionFactory) {
|
||||||
qCWarning(networking_webrtc) << "Failed to create WebRTC peer connection factory";
|
qCWarning(networking_webrtc) << "Failed to create WebRTC peer connection factory";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up mechanism for closing peer connections.
|
||||||
|
connect(this, &WebRTCDataChannels::closePeerConnectionSoon, this, &WebRTCDataChannels::closePeerConnectionNow);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebRTCDataChannels::~WebRTCDataChannels() {
|
WebRTCDataChannels::~WebRTCDataChannels() {
|
||||||
|
@ -397,18 +435,6 @@ void WebRTCDataChannels::onDataChannelOpened(WDCConnection* connection, quint16
|
||||||
_connectionsByDataChannel.insert(dataChannelID, connection);
|
_connectionsByDataChannel.insert(dataChannelID, connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebRTCDataChannels::onDataChannelClosed(WDCConnection* connection, quint16 dataChannelID) {
|
|
||||||
#ifdef WEBRTC_DEBUG
|
|
||||||
qCDebug(networking_webrtc) << "WebRTCDataChannels::onDataChannelClosed() :" << dataChannelID;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Delete WDCConnection.
|
|
||||||
_connectionsByWebSocket.remove(connection->getWebSocketID());
|
|
||||||
_connectionsByDataChannel.remove(dataChannelID);
|
|
||||||
// WEBRTC FIXME: The following line causes the _peerConnectionFactory to fail.
|
|
||||||
//delete connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebRTCDataChannels::onSignalingMessage(const QJsonObject& message) {
|
void WebRTCDataChannels::onSignalingMessage(const QJsonObject& message) {
|
||||||
#ifdef WEBRTC_DEBUG
|
#ifdef WEBRTC_DEBUG
|
||||||
qCDebug(networking_webrtc) << "WebRTCDataChannel::onSignalingMessage()" << message;
|
qCDebug(networking_webrtc) << "WebRTCDataChannel::onSignalingMessage()" << message;
|
||||||
|
@ -429,7 +455,7 @@ void WebRTCDataChannels::onSignalingMessage(const QJsonObject& message) {
|
||||||
if (_connectionsByWebSocket.contains(from)) {
|
if (_connectionsByWebSocket.contains(from)) {
|
||||||
connection = _connectionsByWebSocket.value(from);
|
connection = _connectionsByWebSocket.value(from);
|
||||||
} else {
|
} else {
|
||||||
connection = new WDCConnection(from, this);
|
connection = new WDCConnection(this, from);
|
||||||
_connectionsByWebSocket.insert(from, connection);
|
_connectionsByWebSocket.insert(from, connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,12 +528,42 @@ rtc::scoped_refptr<PeerConnectionInterface> WebRTCDataChannels::createPeerConnec
|
||||||
configuration.servers.push_back(iceServer);
|
configuration.servers.push_back(iceServer);
|
||||||
|
|
||||||
#ifdef WEBRTC_DEBUG
|
#ifdef WEBRTC_DEBUG
|
||||||
qCDebug(networking_webrtc) << "2. Create a new PeerConnection";
|
qCDebug(networking_webrtc) << "2. Create a new peer connection";
|
||||||
#endif
|
#endif
|
||||||
PeerConnectionDependencies dependencies(peerConnectionObserver.get());
|
PeerConnectionDependencies dependencies(peerConnectionObserver.get());
|
||||||
auto result = _peerConnectionFactory->CreatePeerConnection(configuration, std::move(dependencies));
|
auto result = _peerConnectionFactory->CreatePeerConnection(configuration, std::move(dependencies));
|
||||||
|
#ifdef WEBRTC_DEBUG
|
||||||
|
qCDebug(networking_webrtc) << "Created peer connection";
|
||||||
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WebRTCDataChannels::closePeerConnection(WDCConnection* connection) {
|
||||||
|
#ifdef WEBRTC_DEBUG
|
||||||
|
qCDebug(networking_webrtc) << "WebRTCDataChannels::closePeerConnection()";
|
||||||
|
#endif
|
||||||
|
// Use Qt's signals/slots mechanism to close the peer connection on its own call stack, separate from the DataChannel
|
||||||
|
// callback that initiated the peer connection.
|
||||||
|
// https://bugs.chromium.org/p/webrtc/issues/detail?id=3721
|
||||||
|
emit closePeerConnectionSoon(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WebRTCDataChannels::closePeerConnectionNow(WDCConnection* connection) {
|
||||||
|
#ifdef WEBRTC_DEBUG
|
||||||
|
qCDebug(networking_webrtc) << "WebRTCDataChannels::closePeerConnectionNow()";
|
||||||
|
#endif
|
||||||
|
// Close the peer connection.
|
||||||
|
connection->closePeerConnection();
|
||||||
|
|
||||||
|
// Delete the WDCConnection.
|
||||||
|
_connectionsByWebSocket.remove(connection->getWebSocketID());
|
||||||
|
_connectionsByDataChannel.remove(connection->getDataChannelID());
|
||||||
|
delete connection;
|
||||||
|
#ifdef WEBRTC_DEBUG
|
||||||
|
qCDebug(networking_webrtc) << "Disposed of connection";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif // WEBRTC_DATA_CHANNELS
|
#endif // WEBRTC_DATA_CHANNELS
|
||||||
|
|
|
@ -46,6 +46,9 @@ public:
|
||||||
/// @brief A WebRTC create session description observer.
|
/// @brief A WebRTC create session description observer.
|
||||||
class WDCCreateSessionDescriptionObserver : public webrtc::CreateSessionDescriptionObserver {
|
class WDCCreateSessionDescriptionObserver : public webrtc::CreateSessionDescriptionObserver {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// @brief Constructs a session description observer.
|
||||||
|
/// @param parent The parent connection object.
|
||||||
WDCCreateSessionDescriptionObserver(WDCConnection* parent);
|
WDCCreateSessionDescriptionObserver(WDCConnection* parent);
|
||||||
|
|
||||||
/// @brief The call to CreateAnswer succeeded.
|
/// @brief The call to CreateAnswer succeeded.
|
||||||
|
@ -64,6 +67,9 @@ private:
|
||||||
/// @brief A WebRTC peer connection observer.
|
/// @brief A WebRTC peer connection observer.
|
||||||
class WDCPeerConnectionObserver : public webrtc::PeerConnectionObserver {
|
class WDCPeerConnectionObserver : public webrtc::PeerConnectionObserver {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// @brief Constructs a peer connection observer.
|
||||||
|
/// @param parent The parent connection object.
|
||||||
WDCPeerConnectionObserver(WDCConnection* parent);
|
WDCPeerConnectionObserver(WDCConnection* parent);
|
||||||
|
|
||||||
/// @brief Called when the SignalingState changes.
|
/// @brief Called when the SignalingState changes.
|
||||||
|
@ -97,6 +103,9 @@ private:
|
||||||
/// @brief A WebRTC data channel observer.
|
/// @brief A WebRTC data channel observer.
|
||||||
class WDCDataChannelObserver : public webrtc::DataChannelObserver {
|
class WDCDataChannelObserver : public webrtc::DataChannelObserver {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// @brief Constructs a data channel observer.
|
||||||
|
/// @param parent The parent connection object.
|
||||||
WDCDataChannelObserver(WDCConnection* parent);
|
WDCDataChannelObserver(WDCConnection* parent);
|
||||||
|
|
||||||
/// @brief The data channel state changed.
|
/// @brief The data channel state changed.
|
||||||
|
@ -116,10 +125,11 @@ private:
|
||||||
class WDCConnection {
|
class WDCConnection {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// @brief Constructs a new WDCConnection and opens a WebRTC data connection.
|
/// @brief Constructs a new WDCConnection and opens a WebRTC data connection.
|
||||||
/// @param webSocketID The signaling channel that initiated the opening of the WebRTC data channel.
|
|
||||||
/// @param parent The parent WebRTCDataChannels object.
|
/// @param parent The parent WebRTCDataChannels object.
|
||||||
WDCConnection(quint16 webSocketID, WebRTCDataChannels* parent);
|
/// @param webSocketID The signaling channel that initiated the opening of the WebRTC data channel.
|
||||||
|
WDCConnection(WebRTCDataChannels* parent, quint16 webSocketID);
|
||||||
|
|
||||||
/// @brief Gets the WebSocket ID.
|
/// @brief Gets the WebSocket ID.
|
||||||
/// @return The ID of the WebSocket.
|
/// @return The ID of the WebSocket.
|
||||||
|
@ -153,6 +163,10 @@ public:
|
||||||
/// @param candidate The ICE candidate.
|
/// @param candidate The ICE candidate.
|
||||||
void sendIceCandidate(const webrtc::IceCandidateInterface* candidate);
|
void sendIceCandidate(const webrtc::IceCandidateInterface* candidate);
|
||||||
|
|
||||||
|
/// @brief Monitors the peer connection state.
|
||||||
|
/// @param state The new peer connection state.
|
||||||
|
void onPeerConnectionStateChanged(PeerConnectionInterface::PeerConnectionState state);
|
||||||
|
|
||||||
/// @brief Handles the WebRTC data channel being opened.
|
/// @brief Handles the WebRTC data channel being opened.
|
||||||
/// @param dataChannel The WebRTC data channel.
|
/// @param dataChannel The WebRTC data channel.
|
||||||
void onDataChannelOpened(rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel);
|
void onDataChannelOpened(rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel);
|
||||||
|
@ -174,6 +188,9 @@ public:
|
||||||
/// @param buffer The message to send.
|
/// @param buffer The message to send.
|
||||||
/// @return `true` if the message was sent, otherwise `false`.
|
/// @return `true` if the message was sent, otherwise `false`.
|
||||||
bool sendDataMessage(const webrtc::DataBuffer& buffer);
|
bool sendDataMessage(const webrtc::DataBuffer& buffer);
|
||||||
|
|
||||||
|
/// @brief Closes the WebRTC peer connection.
|
||||||
|
void closePeerConnection();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WebRTCDataChannels* _parent;
|
WebRTCDataChannels* _parent;
|
||||||
|
@ -236,11 +253,6 @@ public:
|
||||||
/// @param dataChannelID The WebRTC data channel ID.
|
/// @param dataChannelID The WebRTC data channel ID.
|
||||||
void onDataChannelOpened(WDCConnection* connection, quint16 dataChannelID);
|
void onDataChannelOpened(WDCConnection* connection, quint16 dataChannelID);
|
||||||
|
|
||||||
/// @brief Handles a WebRTC data channel closing.
|
|
||||||
/// @param connection The WebRTC data channel connection.
|
|
||||||
/// @param dataChannelID The WebRTC data channel ID.
|
|
||||||
void onDataChannelClosed(WDCConnection* connection, quint16 dataChannelID);
|
|
||||||
|
|
||||||
/// @brief Emits a signalingMessage to be sent to the Interface client.
|
/// @brief Emits a signalingMessage to be sent to the Interface client.
|
||||||
/// @param message The WebRTC signaling message to send.
|
/// @param message The WebRTC signaling message to send.
|
||||||
void sendSignalingMessage(const QJsonObject& message);
|
void sendSignalingMessage(const QJsonObject& message);
|
||||||
|
@ -267,12 +279,24 @@ public:
|
||||||
rtc::scoped_refptr<webrtc::PeerConnectionInterface> createPeerConnection(
|
rtc::scoped_refptr<webrtc::PeerConnectionInterface> createPeerConnection(
|
||||||
const std::shared_ptr<WDCPeerConnectionObserver> peerConnectionObserver);
|
const std::shared_ptr<WDCPeerConnectionObserver> peerConnectionObserver);
|
||||||
|
|
||||||
|
/// @brief Initiates closing the peer connection for a WebRTC data channel.
|
||||||
|
/// @details Emits a {@link WebRTCDataChannels.closePeerConnectionSoon} signal which is connected to
|
||||||
|
/// {@link WebRTCDataChannels.closePeerConnectionNow} in order to close the peer connection on a new call stack. This is
|
||||||
|
/// necessary to work around a WebRTC library limitation.
|
||||||
|
/// @param connection The WebRTC data channel connection.
|
||||||
|
void closePeerConnection(WDCConnection* connection);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/// @brief Handles a WebRTC signaling message received from the Interface client.
|
/// @brief Handles a WebRTC signaling message received from the Interface client.
|
||||||
/// @param message The WebRTC signaling message.
|
/// @param message The WebRTC signaling message.
|
||||||
void onSignalingMessage(const QJsonObject& message);
|
void onSignalingMessage(const QJsonObject& message);
|
||||||
|
|
||||||
|
/// @brief Closes the peer connection for a WebRTC data channel.
|
||||||
|
/// @details Used by {@link WebRTCDataChannels.closePeerConnection}.
|
||||||
|
/// @param connection The WebRTC data channel connection.
|
||||||
|
void closePeerConnectionNow(WDCConnection* connection);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
/// @brief A WebRTC signaling message to be sent to the Interface client.
|
/// @brief A WebRTC signaling message to be sent to the Interface client.
|
||||||
|
@ -286,6 +310,11 @@ signals:
|
||||||
/// @param byteArray The Vircadia protocol message.
|
/// @param byteArray The Vircadia protocol message.
|
||||||
void dataMessage(int dataChannelID, const QByteArray& byteArray);
|
void dataMessage(int dataChannelID, const QByteArray& byteArray);
|
||||||
|
|
||||||
|
/// @brief Signals that the peer connection for a WebRTC data channel should be closed.
|
||||||
|
/// @details Used by {@link WebRTCDataChannels.closePeerConnection}.
|
||||||
|
/// @param connection The WebRTC data channel connection.
|
||||||
|
void closePeerConnectionSoon(WDCConnection* connection);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QObject* _parent;
|
QObject* _parent;
|
||||||
|
|
Loading…
Reference in a new issue