Пример #1
0
int ModelServer::sendSpecialPacket(OctreeQueryNode* queryNode, const SharedNodePointer& node) {
    unsigned char outputBuffer[MAX_PACKET_SIZE];
    size_t packetLength = 0;

    ModelNodeData* nodeData = static_cast<ModelNodeData*>(node->getLinkedData());
    if (nodeData) {
        quint64 deletedModelsSentAt = nodeData->getLastDeletedModelsSentAt();
        quint64 deletePacketSentAt = usecTimestampNow();

        ModelTree* tree = static_cast<ModelTree*>(_tree);
        bool hasMoreToSend = true;

        // TODO: is it possible to send too many of these packets? what if you deleted 1,000,000 models?
        while (hasMoreToSend) {
            hasMoreToSend = tree->encodeModelsDeletedSince(queryNode->getSequenceNumber(), deletedModelsSentAt,
                                                outputBuffer, MAX_PACKET_SIZE, packetLength);

            //qDebug() << "sending PacketType_MODEL_ERASE packetLength:" << packetLength;

            NodeList::getInstance()->writeDatagram((char*) outputBuffer, packetLength, SharedNodePointer(node));
            queryNode->incrementSequenceNumber();
        }

        nodeData->setLastDeletedModelsSentAt(deletePacketSentAt);
    }

    // TODO: caller is expecting a packetLength, what if we send more than one packet??
    return packetLength;
}
Пример #2
0
SharedNodePointer LimitedNodeList::nodeWithUUID(const QUuid& nodeUUID) {
    QReadLocker readLocker(&_nodeMutex);

    NodeHash::const_iterator it = _nodeHash.find(nodeUUID);
    return it == _nodeHash.cend() ? SharedNodePointer() : it->second;
}
Пример #3
0
int OctreeSendThread::handlePacketSend(const SharedNodePointer& node, OctreeQueryNode* nodeData, int& trueBytesSent, int& truePacketsSent) {
    bool debug = _myServer->wantsDebugSending();
    quint64 now = usecTimestampNow();

    bool packetSent = false; // did we send a packet?
    int packetsSent = 0;
    
    // double check that the node has an active socket, otherwise, don't send...

    quint64 lockWaitStart = usecTimestampNow();
    QMutexLocker locker(&node->getMutex());
    quint64 lockWaitEnd = usecTimestampNow();
    float lockWaitElapsedUsec = (float)(lockWaitEnd - lockWaitStart);
    OctreeServer::trackNodeWaitTime(lockWaitElapsedUsec);
    
    const HifiSockAddr* nodeAddress = node->getActiveSocket();
    if (!nodeAddress) {
        return packetsSent; // without sending...
    }
    
    // Here's where we check to see if this packet is a duplicate of the last packet. If it is, we will silently
    // obscure the packet and not send it. This allows the callers and upper level logic to not need to know about
    // this rate control savings.
    if (nodeData->shouldSuppressDuplicatePacket()) {
        nodeData->resetOctreePacket(true); // we still need to reset it though!
        return packetsSent; // without sending...
    }

    const unsigned char* messageData = nodeData->getPacket();
    int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<const char*>(messageData));
    const unsigned char* dataAt = messageData + numBytesPacketHeader;
    dataAt += sizeof(OCTREE_PACKET_FLAGS);
    OCTREE_PACKET_SEQUENCE sequence = (*(OCTREE_PACKET_SEQUENCE*)dataAt);
    dataAt += sizeof(OCTREE_PACKET_SEQUENCE);


    // If we've got a stats message ready to send, then see if we can piggyback them together
    if (nodeData->stats.isReadyToSend()) {
        // Send the stats message to the client
        unsigned char* statsMessage = nodeData->stats.getStatsMessage();
        int statsMessageLength = nodeData->stats.getStatsMessageLength();
        int piggyBackSize = nodeData->getPacketLength() + statsMessageLength;

        // If the size of the stats message and the voxel message will fit in a packet, then piggyback them
        if (piggyBackSize < MAX_PACKET_SIZE) {

            // copy voxel message to back of stats message
            memcpy(statsMessage + statsMessageLength, nodeData->getPacket(), nodeData->getPacketLength());
            statsMessageLength += nodeData->getPacketLength();

            // since a stats message is only included on end of scene, don't consider any of these bytes "wasted", since
            // there was nothing else to send.
            int thisWastedBytes = 0;
            _totalWastedBytes += thisWastedBytes;
            _totalBytes += nodeData->getPacketLength();
            _totalPackets++;
            if (debug) {
                qDebug() << "Adding stats to packet at " << now << " [" << _totalPackets <<"]: sequence: " << sequence <<
                        " statsMessageLength: " << statsMessageLength <<
                        " original size: " << nodeData->getPacketLength() << " [" << _totalBytes <<
                        "] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]";
            }

            // actually send it
            NodeList::getInstance()->writeDatagram((char*) statsMessage, statsMessageLength, SharedNodePointer(node));
            packetSent = true;
        } else {
            // not enough room in the packet, send two packets
            NodeList::getInstance()->writeDatagram((char*) statsMessage, statsMessageLength, SharedNodePointer(node));

            // since a stats message is only included on end of scene, don't consider any of these bytes "wasted", since
            // there was nothing else to send.
            int thisWastedBytes = 0;
            _totalWastedBytes += thisWastedBytes;
            _totalBytes += statsMessageLength;
            _totalPackets++;
            if (debug) {
                qDebug() << "Sending separate stats packet at " << now << " [" << _totalPackets <<"]: sequence: " << sequence <<
                        " size: " << statsMessageLength << " [" << _totalBytes <<
                        "] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]";
            }

            trueBytesSent += statsMessageLength;
            truePacketsSent++;
            packetsSent++;

            NodeList::getInstance()->writeDatagram((char*) nodeData->getPacket(), nodeData->getPacketLength(),
                                                   SharedNodePointer(node));

            packetSent = true;

            thisWastedBytes = MAX_PACKET_SIZE - nodeData->getPacketLength();
            _totalWastedBytes += thisWastedBytes;
            _totalBytes += nodeData->getPacketLength();
            _totalPackets++;
            if (debug) {
                qDebug() << "Sending packet at " << now << " [" << _totalPackets <<"]: sequence: " << sequence <<
                        " size: " << nodeData->getPacketLength() << " [" << _totalBytes <<
                        "] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]";
            }
        }
        nodeData->stats.markAsSent();
    } else {
        // If there's actually a packet waiting, then send it.
        if (nodeData->isPacketWaiting()) {
            // just send the voxel packet
            NodeList::getInstance()->writeDatagram((char*) nodeData->getPacket(), nodeData->getPacketLength(),
                                                   SharedNodePointer(node));
            packetSent = true;

            int thisWastedBytes = MAX_PACKET_SIZE - nodeData->getPacketLength();
            _totalWastedBytes += thisWastedBytes;
            _totalBytes += nodeData->getPacketLength();
            _totalPackets++;
            if (debug) {
                qDebug() << "Sending packet at " << now << " [" << _totalPackets <<"]: sequence: " << sequence <<
                        " size: " << nodeData->getPacketLength() << " [" << _totalBytes <<
                        "] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]";
            }
        }
    }
    // remember to track our stats
    if (packetSent) {
        nodeData->stats.packetSent(nodeData->getPacketLength());
        trueBytesSent += nodeData->getPacketLength();
        truePacketsSent++;
        packetsSent++;
        nodeData->resetOctreePacket();
    }

    return packetsSent;
}
Пример #4
0
int VoxelServer::sendSpecialPacket(const SharedNodePointer& node) {
    int numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(_tempOutputBuffer), PacketTypeEnvironmentData);
    int envPacketLength = numBytesPacketHeader;
    int environmentsToSend = getSendMinimalEnvironment() ? 1 : getEnvironmentDataCount();

    for (int i = 0; i < environmentsToSend; i++) {
        envPacketLength += getEnvironmentData(i)->getBroadcastData(_tempOutputBuffer + envPacketLength);
    }

    NodeList::getInstance()->writeDatagram((char*) _tempOutputBuffer, envPacketLength, SharedNodePointer(node));
    return envPacketLength;
}