mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 01:31:37 +02:00
add ping timer tied to NetworkPeer
This commit is contained in:
parent
757d02a600
commit
0cb67cce2c
9 changed files with 126 additions and 71 deletions
|
@ -472,7 +472,8 @@ void LimitedNodeList::handleNodeKill(const SharedNodePointer& node) {
|
|||
|
||||
SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
|
||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
|
||||
bool canAdjustLocks, bool canRez) {
|
||||
bool canAdjustLocks, bool canRez,
|
||||
const QUuid& connectionSecret) {
|
||||
NodeHash::const_iterator it = _nodeHash.find(uuid);
|
||||
|
||||
if (it != _nodeHash.end()) {
|
||||
|
@ -482,11 +483,13 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t
|
|||
matchingNode->setLocalSocket(localSocket);
|
||||
matchingNode->setCanAdjustLocks(canAdjustLocks);
|
||||
matchingNode->setCanRez(canRez);
|
||||
matchingNode->setConnectionSecret(connectionSecret);
|
||||
|
||||
return matchingNode;
|
||||
} else {
|
||||
// we didn't have this node, so add them
|
||||
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket, canAdjustLocks, canRez);
|
||||
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket, canAdjustLocks, canRez, connectionSecret);
|
||||
|
||||
SharedNodePointer newNodePointer(newNode);
|
||||
|
||||
_nodeHash.insert(UUIDNodePair(newNode->getUUID(), newNodePointer));
|
||||
|
|
|
@ -151,7 +151,8 @@ public:
|
|||
|
||||
SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
|
||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
|
||||
bool canAdjustLocks, bool canRez);
|
||||
bool canAdjustLocks, bool canRez,
|
||||
const QUuid& connectionSecret = QUuid());
|
||||
|
||||
bool hasCompletedInitialSTUN() const { return _hasCompletedInitialSTUN; }
|
||||
|
||||
|
|
|
@ -75,6 +75,24 @@ QByteArray NetworkPeer::toByteArray() const {
|
|||
return peerByteArray;
|
||||
}
|
||||
|
||||
void NetworkPeer::startPingTimer() {
|
||||
if (!_pingTimer) {
|
||||
_pingTimer = new QTimer(this);
|
||||
|
||||
connect(_pingTimer, &QTimer::timeout, this, &NetworkPeer::pingTimerTimeout);
|
||||
|
||||
_pingTimer->start(UDP_PUNCH_PING_INTERVAL_MS);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkPeer::stopPingTimer() {
|
||||
if (_pingTimer) {
|
||||
_pingTimer->stop();
|
||||
_pingTimer->deleteLater();
|
||||
_pingTimer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
QDataStream& operator<<(QDataStream& out, const NetworkPeer& peer) {
|
||||
out << peer._uuid;
|
||||
out << peer._publicSocket;
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
#ifndef hifi_NetworkPeer_h
|
||||
#define hifi_NetworkPeer_h
|
||||
|
||||
#include <qobject.h>
|
||||
#include <quuid.h>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#include "HifiSockAddr.h"
|
||||
|
||||
|
@ -22,7 +23,10 @@ const int ICE_SERVER_DEFAULT_PORT = 7337;
|
|||
const int ICE_HEARBEAT_INTERVAL_MSECS = 2 * 1000;
|
||||
const int MAX_ICE_CONNECTION_ATTEMPTS = 5;
|
||||
|
||||
const int UDP_PUNCH_PING_INTERVAL_MS = 25;
|
||||
|
||||
class NetworkPeer : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
NetworkPeer();
|
||||
NetworkPeer(const QUuid& uuid, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
||||
|
@ -61,8 +65,13 @@ public:
|
|||
float getOutboundBandwidth(); // in kbps
|
||||
float getInboundBandwidth(); // in kbps
|
||||
|
||||
void startPingTimer();
|
||||
void stopPingTimer();
|
||||
|
||||
friend QDataStream& operator<<(QDataStream& out, const NetworkPeer& peer);
|
||||
friend QDataStream& operator>>(QDataStream& in, NetworkPeer& peer);
|
||||
signals:
|
||||
void pingTimerTimeout();
|
||||
protected:
|
||||
QUuid _uuid;
|
||||
|
||||
|
@ -72,6 +81,8 @@ protected:
|
|||
quint64 _wakeTimestamp;
|
||||
quint64 _lastHeardMicrostamp;
|
||||
|
||||
QTimer* _pingTimer = NULL;
|
||||
|
||||
int _connectionAttempts;
|
||||
private:
|
||||
void swap(NetworkPeer& otherPeer);
|
||||
|
|
|
@ -42,12 +42,12 @@ const QString& NodeType::getNodeTypeName(NodeType_t nodeType) {
|
|||
}
|
||||
|
||||
Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
|
||||
const HifiSockAddr& localSocket, bool canAdjustLocks, bool canRez) :
|
||||
const HifiSockAddr& localSocket, bool canAdjustLocks, bool canRez, const QUuid& connectionSecret) :
|
||||
NetworkPeer(uuid, publicSocket, localSocket),
|
||||
_type(type),
|
||||
_activeSocket(NULL),
|
||||
_symmetricSocket(),
|
||||
_connectionSecret(),
|
||||
_connectionSecret(connectionSecret),
|
||||
_linkedData(NULL),
|
||||
_isAlive(true),
|
||||
_pingMs(-1), // "Uninitialized"
|
||||
|
@ -114,19 +114,26 @@ void Node::setSymmetricSocket(const HifiSockAddr& symmetricSocket) {
|
|||
}
|
||||
}
|
||||
|
||||
void Node::setActiveSocket(HifiSockAddr* discoveredSocket) {
|
||||
_activeSocket = discoveredSocket;
|
||||
|
||||
// we have an active socket, stop our ping timer
|
||||
stopPingTimer();
|
||||
}
|
||||
|
||||
void Node::activateLocalSocket() {
|
||||
qCDebug(networking) << "Activating local socket for network peer with ID" << uuidStringWithoutCurlyBraces(_uuid);
|
||||
_activeSocket = &_localSocket;
|
||||
setActiveSocket(&_localSocket);
|
||||
}
|
||||
|
||||
void Node::activatePublicSocket() {
|
||||
qCDebug(networking) << "Activating public socket for network peer with ID" << uuidStringWithoutCurlyBraces(_uuid);
|
||||
_activeSocket = &_publicSocket;
|
||||
setActiveSocket(&_publicSocket);
|
||||
}
|
||||
|
||||
void Node::activateSymmetricSocket() {
|
||||
qCDebug(networking) << "Activating symmetric socket for network peer with ID" << uuidStringWithoutCurlyBraces(_uuid);
|
||||
_activeSocket = &_symmetricSocket;
|
||||
setActiveSocket(&_symmetricSocket);
|
||||
}
|
||||
|
||||
PacketSequenceNumber Node::getLastSequenceNumberForPacketType(PacketType packetType) const {
|
||||
|
|
|
@ -46,7 +46,8 @@ class Node : public NetworkPeer {
|
|||
Q_OBJECT
|
||||
public:
|
||||
Node(const QUuid& uuid, NodeType_t type,
|
||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, bool canAdjustLocks, bool canRez);
|
||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
|
||||
bool canAdjustLocks, bool canRez, const QUuid& connectionSecret = QUuid());
|
||||
~Node();
|
||||
|
||||
bool operator==(const Node& otherNode) const { return _uuid == otherNode._uuid; }
|
||||
|
@ -100,6 +101,8 @@ private:
|
|||
Node(const Node &otherNode);
|
||||
Node& operator=(Node otherNode);
|
||||
|
||||
void setActiveSocket(HifiSockAddr* discoveredSocket);
|
||||
|
||||
NodeType_t _type;
|
||||
|
||||
HifiSockAddr* _activeSocket;
|
||||
|
|
|
@ -82,6 +82,9 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned
|
|||
// clear our NodeList when logout is requested
|
||||
connect(&AccountManager::getInstance(), &AccountManager::logoutComplete , this, &NodeList::reset);
|
||||
|
||||
// anytime we get a new node we will want to attempt to punch to it
|
||||
connect(this, &LimitedNodeList::nodeAdded, this, &NodeList::startNodeHolePunch);
|
||||
|
||||
// we definitely want STUN to update our public socket, so call the LNL to kick that off
|
||||
startSTUNPublicSocketUpdate();
|
||||
}
|
||||
|
@ -521,7 +524,7 @@ int NodeList::processDomainServerList(const QByteArray& packet) {
|
|||
setThisNodeCanRez(thisNodeCanRez);
|
||||
|
||||
// pull each node in the packet
|
||||
while(packetStream.device()->pos() < packet.size()) {
|
||||
while (packetStream.device()->pos() < packet.size()) {
|
||||
// setup variables to read into from QDataStream
|
||||
qint8 nodeType;
|
||||
QUuid nodeUUID, connectionUUID;
|
||||
|
@ -537,16 +540,12 @@ int NodeList::processDomainServerList(const QByteArray& packet) {
|
|||
nodePublicSocket.setAddress(_domainHandler.getIP());
|
||||
}
|
||||
|
||||
SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket,
|
||||
nodeLocalSocket, canAdjustLocks, canRez);
|
||||
|
||||
packetStream >> connectionUUID;
|
||||
node->setConnectionSecret(connectionUUID);
|
||||
}
|
||||
|
||||
// ping inactive nodes in conjunction with receipt of list from domain-server
|
||||
// this makes it happen every second and also pings any newly added nodes
|
||||
pingInactiveNodes();
|
||||
SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket,
|
||||
nodeLocalSocket, canAdjustLocks, canRez,
|
||||
connectionUUID);
|
||||
}
|
||||
|
||||
return readNodes;
|
||||
}
|
||||
|
@ -566,6 +565,10 @@ void NodeList::sendAssignment(Assignment& assignment) {
|
|||
}
|
||||
|
||||
void NodeList::pingPunchForInactiveNode(const SharedNodePointer& node) {
|
||||
if (node->getType() == NodeType::AudioMixer) {
|
||||
flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::SendAudioPing);
|
||||
}
|
||||
|
||||
// send the ping packet to the local and public sockets for this node
|
||||
QByteArray localPingPacket = constructPingPacket(PingType::Local);
|
||||
writeDatagram(localPingPacket, node, node->getLocalSocket());
|
||||
|
@ -577,19 +580,27 @@ void NodeList::pingPunchForInactiveNode(const SharedNodePointer& node) {
|
|||
QByteArray symmetricPingPacket = constructPingPacket(PingType::Symmetric);
|
||||
writeDatagram(symmetricPingPacket, node, node->getSymmetricSocket());
|
||||
}
|
||||
|
||||
node->incrementConnectionAttempts();
|
||||
}
|
||||
|
||||
void NodeList::pingInactiveNodes() {
|
||||
eachNode([this](const SharedNodePointer& node){
|
||||
if (!node->getActiveSocket()) {
|
||||
// we don't have an active link to this node, ping it to set that up
|
||||
pingPunchForInactiveNode(node);
|
||||
void NodeList::startNodeHolePunch(const SharedNodePointer& node) {
|
||||
// connect to the correct signal on this node so we know when to ping it
|
||||
connect(node.data(), &Node::pingTimerTimeout, this, &NodeList::handleNodePingTimeout);
|
||||
|
||||
if (node->getType() == NodeType::AudioMixer) {
|
||||
flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::SendAudioPing);
|
||||
// start the ping timer for this node
|
||||
node->startPingTimer();
|
||||
|
||||
// ping this node immediately
|
||||
pingPunchForInactiveNode(node);
|
||||
}
|
||||
|
||||
void NodeList::handleNodePingTimeout() {
|
||||
Node* senderNode = qobject_cast<Node*>(sender());
|
||||
|
||||
if (senderNode) {
|
||||
pingPunchForInactiveNode(nodeWithUUID(senderNode->getUUID()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NodeList::activateSocketFromNodeCommunication(const QByteArray& packet, const SharedNodePointer& sendingNode) {
|
||||
|
|
|
@ -70,13 +70,15 @@ public:
|
|||
public slots:
|
||||
void reset();
|
||||
void sendDomainServerCheckIn();
|
||||
void pingInactiveNodes();
|
||||
void handleDSPathQuery(const QString& newPath);
|
||||
signals:
|
||||
void limitOfSilentDomainCheckInsReached();
|
||||
private slots:
|
||||
void sendPendingDSPathQuery();
|
||||
void handleICEConnectionToDomainServer();
|
||||
|
||||
void startNodeHolePunch(const SharedNodePointer& node);
|
||||
void handleNodePingTimeout();
|
||||
private:
|
||||
NodeList() : LimitedNodeList(0, 0) { assert(false); } // Not implemented, needed for DependencyManager templates compile
|
||||
NodeList(char ownerType, unsigned short socketListenPort = 0, unsigned short dtlsListenPort = 0);
|
||||
|
|
|
@ -46,7 +46,6 @@ protected:
|
|||
|
||||
private slots:
|
||||
void checkInWithDomainServerOrExit();
|
||||
|
||||
};
|
||||
|
||||
typedef QSharedPointer<ThreadedAssignment> SharedAssignmentPointer;
|
||||
|
|
Loading…
Reference in a new issue