More work on client/server communication.

This commit is contained in:
Andrzej Kapolka 2014-01-02 17:40:43 -08:00
parent 25b2353df1
commit a08afae319
5 changed files with 99 additions and 9 deletions

View file

@ -6,6 +6,8 @@
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include <QDateTime>
#include <PacketHeaders.h>
#include <MetavoxelMessages.h>
@ -13,8 +15,13 @@
#include "MetavoxelServer.h"
const int SEND_INTERVAL = 50;
MetavoxelServer::MetavoxelServer(const unsigned char* dataBuffer, int numBytes) :
ThreadedAssignment(dataBuffer, numBytes) {
_sendTimer.setSingleShot(true);
connect(&_sendTimer, SIGNAL(timeout()), SLOT(sendDeltas()));
}
void MetavoxelServer::removeSession(const QUuid& sessionId) {
@ -23,8 +30,11 @@ void MetavoxelServer::removeSession(const QUuid& sessionId) {
void MetavoxelServer::run() {
commonInit("metavoxel-server", NODE_TYPE_METAVOXEL_SERVER);
}
_lastSend = QDateTime::currentMSecsSinceEpoch();
_sendTimer.start(SEND_INTERVAL);
}
void MetavoxelServer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) {
switch (dataByteArray.at(0)) {
case PACKET_TYPE_METAVOXEL_DATA:
@ -37,6 +47,20 @@ void MetavoxelServer::processDatagram(const QByteArray& dataByteArray, const Hif
}
}
void MetavoxelServer::sendDeltas() {
// send deltas for all sessions
foreach (MetavoxelSession* session, _sessions) {
session->sendDelta();
}
// restart the send timer
qint64 now = QDateTime::currentMSecsSinceEpoch();
int elapsed = now - _lastSend;
_lastSend = now;
_sendTimer.start(qMax(0, 2 * SEND_INTERVAL - elapsed));
}
void MetavoxelServer::processData(const QByteArray& data, const HifiSockAddr& sender) {
// read the session id
int headerPlusIDSize;
@ -66,6 +90,11 @@ MetavoxelSession::MetavoxelSession(MetavoxelServer* server, const QUuid& session
connect(&_sequencer, SIGNAL(readyToWrite(const QByteArray&)), SLOT(sendData(const QByteArray&)));
connect(&_sequencer, SIGNAL(readyToRead(Bitstream&)), SLOT(readPacket(Bitstream&)));
connect(&_sequencer, SIGNAL(sendAcknowledged(int)), SLOT(clearSendRecordsBefore(int)));
// insert the baseline send record
SendRecord record = { 0 };
_sendRecords.append(record);
}
void MetavoxelSession::receivedData(const QByteArray& data, const HifiSockAddr& sender) {
@ -79,6 +108,15 @@ void MetavoxelSession::receivedData(const QByteArray& data, const HifiSockAddr&
_sequencer.receivedDatagram(data);
}
void MetavoxelSession::sendDelta() {
Bitstream& out = _sequencer.startPacket();
_sequencer.endPacket();
// record the send
SendRecord record = { _sequencer.getOutgoingPacketNumber() };
_sendRecords.append(record);
}
void MetavoxelSession::timedOut() {
qDebug() << "Session timed out [sessionId=" << _sessionId << ", sender=" << _sender << "]\n";
_server->removeSession(_sessionId);
@ -89,11 +127,31 @@ void MetavoxelSession::sendData(const QByteArray& data) {
}
void MetavoxelSession::readPacket(Bitstream& in) {
QVariant msg;
in >> msg;
glm::vec3 position = msg.value<ClientStateMessage>().position;
qDebug() << position.x << " " << position.y << " " << position.z << "\n";
Bitstream& out = _sequencer.startPacket();
_sequencer.endPacket();
QVariant message;
in >> message;
handleMessage(message);
}
void MetavoxelSession::clearSendRecordsBefore(int packetNumber) {
if (_sendRecords.isEmpty()) {
return;
}
int index = packetNumber - _sendRecords.first().packetNumber;
if (index <= 0 || index >= _sendRecords.size()) {
return;
}
_sendRecords.erase(_sendRecords.begin(), _sendRecords.begin() + index);
}
void MetavoxelSession::handleMessage(const QVariant& message) {
int userType = message.userType();
if (userType == ClientStateMessage::Type) {
ClientStateMessage state = message.value<ClientStateMessage>();
_position = state.position;
} else if (userType == QMetaType::QVariantList) {
foreach (const QVariant& element, message.toList()) {
handleMessage(element);
}
}
}

View file

@ -10,6 +10,7 @@
#define __hifi__MetavoxelServer__
#include <QHash>
#include <QList>
#include <QTimer>
#include <QUuid>
@ -35,12 +36,19 @@ public:
virtual void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr);
private slots:
void sendDeltas();
private:
void processData(const QByteArray& data, const HifiSockAddr& sender);
MetavoxelData _data;
QTimer _sendTimer;
qint64 _lastSend;
QHash<QUuid, MetavoxelSession*> _sessions;
};
@ -54,6 +62,8 @@ public:
void receivedData(const QByteArray& data, const HifiSockAddr& sender);
void sendDelta();
private slots:
void timedOut();
@ -62,8 +72,17 @@ private slots:
void readPacket(Bitstream& in);
void clearSendRecordsBefore(int packetNumber);
private:
void handleMessage(const QVariant& message);
class SendRecord {
public:
int packetNumber;
};
MetavoxelServer* _server;
QUuid _sessionId;
@ -71,6 +90,10 @@ private:
DatagramSequencer _sequencer;
HifiSockAddr _sender;
glm::vec3 _position;
QList<SendRecord> _sendRecords;
};
#endif /* defined(__hifi__MetavoxelServer__) */

View file

@ -194,7 +194,7 @@ MetavoxelClient::MetavoxelClient(const HifiSockAddr& address) :
void MetavoxelClient::simulate(float deltaTime) {
Bitstream& out = _sequencer.startPacket();
ClientStateMessage state = { glm::vec3(0.5f, 0.5f, 1.0f) };
ClientStateMessage state = { Application::getInstance()->getCamera()->getPosition() };
out << QVariant::fromValue(state);
_sequencer.endPacket();
}

View file

@ -140,6 +140,9 @@ void DatagramSequencer::sendRecordAcknowledged(const SendRecord& record) {
_receiveRecords.erase(_receiveRecords.begin(), it + 1);
}
_outputStream.persistWriteMappings(record.mappings);
// notify any listeners
emit sendAcknowledged(record.packetNumber);
}
void DatagramSequencer::sendPacket(const QByteArray& packet) {

View file

@ -25,6 +25,9 @@ public:
DatagramSequencer(const QByteArray& datagramHeader = QByteArray());
/// Returns the packet number of the last packet sent.
int getOutgoingPacketNumber() const { return _outgoingPacketNumber; }
/// Starts a new packet for transmission.
/// \return a reference to the Bitstream to use for writing to the packet
Bitstream& startPacket();
@ -44,6 +47,9 @@ signals:
/// Emitted when a packet is available to read.
void readyToRead(Bitstream& input);
/// Emitted when a sent packet has been acknowledged by the remote side.
void sendAcknowledged(int packetNumber);
private:
class SendRecord {