add chronoTime

This commit is contained in:
Andrei Yankovich 2017-12-17 01:23:38 +03:00
parent d69006103e
commit 17dabbaf6b
10 changed files with 220 additions and 72 deletions

View File

@ -32,7 +32,8 @@ SOURCES += \
../sync/song.cpp \ ../sync/song.cpp \
../sync/sync.cpp \ ../sync/sync.cpp \
servermodel.cpp \ servermodel.cpp \
songmodel.cpp songmodel.cpp \
../sync/chronotime.cpp
HEADERS += \ HEADERS += \
mainwindow.h \ mainwindow.h \
@ -44,7 +45,8 @@ HEADERS += \
../sync/song.h \ ../sync/song.h \
../sync/sync.h \ ../sync/sync.h \
servermodel.h \ servermodel.h \
songmodel.h songmodel.h \
../sync/chronotime.h
FORMS += \ FORMS += \
mainwindow.ui mainwindow.ui

View File

@ -1,6 +1,5 @@
#include "ETcpSocket.h" #include "ETcpSocket.h"
#include "exaptions.h" #include "exaptions.h"
#include "config.h"
ETcpSocket::ETcpSocket() ETcpSocket::ETcpSocket()
{ {
@ -23,7 +22,10 @@ ETcpSocket::ETcpSocket(const QString& address, int port){
} }
void ETcpSocket::init(){ void ETcpSocket::init(){
array=new QByteArray; array = new QByteArray;
fSynced = false;
differenceTime = 0;
connect(source,SIGNAL(connected()),this,SLOT(connected_())); connect(source,SIGNAL(connected()),this,SLOT(connected_()));
connect(source,SIGNAL(disconnected()),this,SLOT(disconnected_())); connect(source,SIGNAL(disconnected()),this,SLOT(disconnected_()));
connect(source,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(error_(QAbstractSocket::SocketError))); connect(source,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(error_(QAbstractSocket::SocketError)));
@ -59,11 +61,77 @@ void ETcpSocket::stateChanged_(QAbstractSocket::SocketState socketState){
void ETcpSocket::readReady_(){ void ETcpSocket::readReady_(){
bool sizewrite=array->isEmpty(); bool sizewrite=array->isEmpty();
//while(source->bytesAvailable())
array->append(source->readAll()); array->append(source->readAll());
QDataStream stream(array,QIODevice::ReadOnly); QDataStream stream(array,QIODevice::ReadOnly);
if(sizewrite) if(sizewrite){
stream>>size; stream >> size;
switch (size) {
case CALIBRATION_SENDER:{
milliseconds ms;
stream >> ms;
milliseconds range = ChronoTime::now() - ms;
QByteArray cArray;
QDataStream stream(&cArray,QIODevice::ReadWrite);
if(range < MIN_DIFFERENCE){
stream << CALIBRATION_RECEIVER_DONE;
fSynced = true;
}else{
stream << CALIBRATION_RECEIVER;
stream << range;
}
source->write(cArray);
return;
}
case CALIBRATION_RECEIVER:{
ping = ChronoTime::now() - lastTime;
milliseconds ms;
stream >> ms;
differenceTime += ms + ping / 2;
QByteArray cArray;
QDataStream stream(&cArray,QIODevice::ReadWrite);
stream << CALIBRATION_SENDER;
stream << milliseconds(ChronoTime::now() + differenceTime);
lastTime = ChronoTime::now();
source->write(cArray);
return;
}
case CALIBRATION_RECEIVER_DONE:{
QByteArray cArray;
QDataStream stream(&cArray,QIODevice::ReadWrite);
stream << CALIBRATION_SENDER_DONE;
stream << milliseconds(-differenceTime);
fSynced = true;
source->write(cArray);
return;
}
case CALIBRATION_SENDER_DONE:{
stream >> differenceTime;
return;
}
}
}
#ifdef QT_DEBUG #ifdef QT_DEBUG
qDebug()<<"messae size:"<<size; qDebug()<<"messae size:"<<size;
qDebug()<<"message package size:"<<array->size(); qDebug()<<"message package size:"<<array->size();
@ -77,7 +145,6 @@ void ETcpSocket::readReady_(){
}else{ }else{
emit donwload(array->size(),size); emit donwload(array->size(),size);
} }
// emit ReadReady(this);
} }
QString ETcpSocket::name() const{ QString ETcpSocket::name() const{
@ -112,12 +179,21 @@ QString ETcpSocket::toStringTcp(){
return source->peerAddress().toString(); return source->peerAddress().toString();
} }
milliseconds ETcpSocket::getDifferenceTime() const{
return differenceTime;
}
bool ETcpSocket::isSynced()const{
return fSynced;
}
bool ETcpSocket::Write(const QByteArray&data){ bool ETcpSocket::Write(const QByteArray&data){
if(source->state()==QTcpSocket::ConnectedState){ if(source->state()==QTcpSocket::ConnectedState){
QByteArray array; QByteArray array;
QDataStream stream(&array,QIODevice::ReadWrite); QDataStream stream(&array,QIODevice::ReadWrite);
stream<<qint32(0);
//stream<<data; stream << qint32(0);
array.append(data); array.append(data);
stream.device()->seek(0); stream.device()->seek(0);
stream<<qint32(array.size()); stream<<qint32(array.size());
@ -133,6 +209,19 @@ bool ETcpSocket::Write(const QByteArray&data){
return false; return false;
} }
void ETcpSocket::calibration(){
if(!fSynced){
QByteArray cArray;
QDataStream stream(&cArray,QIODevice::ReadWrite);
stream << CALIBRATION_SENDER;
stream << milliseconds(ChronoTime::now());
lastTime = ChronoTime::now();
source->write(cArray);
}
}
ETcpSocket::~ETcpSocket() ETcpSocket::~ETcpSocket()
{ {
for(QByteArray*i:ReadyStack){ for(QByteArray*i:ReadyStack){

View File

@ -4,6 +4,14 @@
#include <QTcpServer> #include <QTcpServer>
#include <QList> #include <QList>
#include <QDataStream> #include <QDataStream>
#include "chronotime.h"
#define CALIBRATION_SENDER qint32(-1)
#define CALIBRATION_RECEIVER qint32(-2)
#define CALIBRATION_SENDER_DONE qint32(-3)
#define CALIBRATION_RECEIVER_DONE qint32(-4)
/** /**
* @brief The ETcpSocket class * @brief The ETcpSocket class
@ -25,6 +33,8 @@
* } * }
* *
*/ */
class ETcpSocket:public QObject class ETcpSocket:public QObject
{ {
Q_OBJECT Q_OBJECT
@ -35,6 +45,17 @@ private:
qint32 size; qint32 size;
QList<QByteArray*> ReadyStack; QList<QByteArray*> ReadyStack;
void init(); void init();
/**
* @brief differenceTime - local time difference in milliseconds
* on milliseconds
*/
milliseconds differenceTime;
/**
* @brief fSynced - whether a time difference was found.
*/
bool fSynced;
milliseconds lastTime;
milliseconds ping;
private slots: private slots:
void connected_(); void connected_();
@ -70,6 +91,25 @@ public:
* @return true if all done else false. * @return true if all done else false.
*/ */
bool Write(const QByteArray&); bool Write(const QByteArray&);
/**
* @brief getDifferenceTime
* @return Difference Time of remoute node.
*/
milliseconds getDifferenceTime()const;
/**
* @brief isSynced
* @return
*/
bool isSynced()const;
/**
* @brief calibration - will calculate the difference in time between the connected node
* and the current node.
*/
void calibration();
~ETcpSocket(); ~ETcpSocket();
public slots: public slots:
/** /**
@ -126,6 +166,7 @@ signals:
*/ */
void StateChanged(ETcpSocket*,QAbstractSocket::SocketState socketState); void StateChanged(ETcpSocket*,QAbstractSocket::SocketState socketState);
}; };
#endif // CLIENT_H #endif // CLIENT_H

31
sync/chronotime.cpp Normal file
View File

@ -0,0 +1,31 @@
#include "chronotime.h"
#include <QDebug>
ChronoTime::ChronoTime()
{
}
/*
* information about chrono
* https://stackoverflow.com/questions/31255486/c-how-do-i-convert-a-stdchronotime-point-to-long-and-back
*/
milliseconds ChronoTime::now(){
auto tim = std::chrono::system_clock::now();
auto mc = std::chrono::time_point_cast<std::chrono::milliseconds>(tim);
auto epoh = mc.time_since_epoch();
#ifdef QT_DEBUG
qDebug() << epoh.count();
#endif
return epoh.count();
}
Clock ChronoTime::from(const milliseconds& mc){
std::chrono::milliseconds dur(mc);
return Clock(dur);
}
milliseconds ChronoTime::abs(milliseconds number){
return (number << 1) >> 1;
}

35
sync/chronotime.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef CHRONOTIME_H
#define CHRONOTIME_H
#include <chrono>
#include "config.h"
/**
* @brief Time_point on nanosecunds (uint64_t)
*/
typedef long long milliseconds;
typedef std::chrono::time_point<std::chrono::high_resolution_clock> Clock;
class ChronoTime
{
public:
ChronoTime();
/**
* @brief now - get now time on microsecunds
* @return - count of microsecunds
*/
static milliseconds now();
/**
* @brief from cast to chrono secunds
* @param mcrs microseconds of uint_64
* @return microseconds of chrono
*/
static Clock from(const milliseconds &mcrs);
/**
* @brief abs
* @return module of numver
*/
static milliseconds abs(milliseconds number);
};
#endif // CHRONOTIME_H

View File

@ -20,6 +20,6 @@
#define DEEP_SCANER_INTERVAL 10000 // 10 sec #define DEEP_SCANER_INTERVAL 10000 // 10 sec
// sync // sync
#define MIN_DIFFERENCE 100 // millisec #define MIN_DIFFERENCE 10 // millisec
#endif // CONFIG_H #endif // CONFIG_H

View File

@ -71,12 +71,4 @@ public:
} }
}; };
class feedbackError:public std::exception
{
public:
QString what(){
return QObject::tr("Could not create synchronization confirmation packet.");
}
};
#endif // EXAPTIONS_H #endif // EXAPTIONS_H

View File

@ -3,12 +3,7 @@
#include <QString> #include <QString>
#include <QByteArray> #include <QByteArray>
#include <QDataStream> #include <QDataStream>
#include "config.h" #include "chronotime.h"
/**
* @brief Time_point on nanosecunds (uint64_t)
*/
typedef quint64 milliseconds;
namespace syncLib { namespace syncLib {
@ -23,7 +18,7 @@ struct Syncer
*/ */
milliseconds seek; milliseconds seek;
/** /**
* @brief run when is play media file (int) * @brief run when is play media file (milliseconds)
*/ */
milliseconds run; milliseconds run;
}; };

View File

@ -41,10 +41,6 @@ Sync::Sync(const QString address, int port, const QString &datadir):
connect(player, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(endPlay(QMediaPlayer::State))); connect(player, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(endPlay(QMediaPlayer::State)));
} }
int Sync::abs(int number) const{
return (number << 1) >> 1;
}
bool Sync::findHeader(const Song &song){ bool Sync::findHeader(const Song &song){
for(SongHeader & header: playList){ for(SongHeader & header: playList){
@ -179,26 +175,6 @@ bool Sync::load(const SongHeader &song,Song &result){
return true; return true;
} }
/*
* information about chrono
* https://stackoverflow.com/questions/31255486/c-how-do-i-convert-a-stdchronotime-point-to-long-and-back
*/
milliseconds Sync::now(){
auto tim = std::chrono::system_clock::now();
auto mc = std::chrono::time_point_cast<std::chrono::milliseconds>(tim);
auto epoh = mc.time_since_epoch();
#ifdef QT_DEBUG
qDebug() << epoh.count();
#endif
return epoh.count();
}
Clock Sync::from(const milliseconds& mc){
std::chrono::milliseconds dur(mc);
return Clock(dur);
}
bool Sync::play(const SongHeader &header, const Syncer *syncdata){ bool Sync::play(const SongHeader &header, const Syncer *syncdata){
if(!header.isValid()){ if(!header.isValid()){
@ -296,13 +272,16 @@ void Sync::jump(const qint64 seek){
} }
bool Sync::sync(const Syncer &sync){ bool Sync::sync(const Syncer &sync){
milliseconds sync_time = sync.run - now(); milliseconds sync_time = sync.run - ChronoTime::now();
if(sync_time > MAX_SYNC_TIME && sync_time <= 0) if(sync_time > MAX_SYNC_TIME && sync_time <= 0)
return false; return false;
Clock run_time = from(sync.run);
Clock run_time = ChronoTime::from(sync.run);
do { do {
std::this_thread::yield(); std::this_thread::yield();
} while (std::chrono::high_resolution_clock::now() < run_time); } while (std::chrono::high_resolution_clock::now() < run_time);
player->setPosition(sync.seek); player->setPosition(sync.seek);
return true; return true;
} }
@ -348,14 +327,14 @@ bool Sync::createPackage(Type type, package &pac){
if(type & TypePackage::t_sync && fbroadcaster){ if(type & TypePackage::t_sync && fbroadcaster){
pac.playdata.run = now() + SYNC_TIME; pac.playdata.run = ChronoTime::now() + SYNC_TIME;
pac.playdata.seek = player->position() + SYNC_TIME; pac.playdata.seek = player->position() + SYNC_TIME;
} }
if( type & TypePackage::t_feedback && !fbroadcaster){ if( type & TypePackage::t_feedback && !fbroadcaster){
pac.playdata.run = now(); pac.playdata.run = ChronoTime::now();
pac.playdata.seek = player->position(); pac.playdata.seek = player->position();
} }
@ -467,7 +446,7 @@ void Sync::packageRender(ETcpSocket *socket){
return ; return ;
} }
unsigned int diff = abs(static_cast<unsigned int>(player->position() - (pkg.getPlayData().seek + (now() - pkg.getPlayData().run)))); unsigned int diff = ChronoTime::abs(player->position() - (pkg.getPlayData().seek + (ChronoTime::now() - pkg.getPlayData().run)));
#ifdef QT_DEBUG #ifdef QT_DEBUG
qDebug() << "diff " << socket->name() <<": " << diff; qDebug() << "diff " << socket->name() <<": " << diff;

View File

@ -13,7 +13,6 @@ class QSqlQuery;
class QBuffer; class QBuffer;
namespace syncLib { namespace syncLib {
typedef std::chrono::time_point<std::chrono::high_resolution_clock> Clock;
class Node; class Node;
@ -37,11 +36,6 @@ private:
LocalScanner deepScaner; LocalScanner deepScaner;
int port; int port;
QString dataBaseName; QString dataBaseName;
/**
* @brief abs
* @return module of numver
*/
int abs(int number)const;
/** /**
* @brief findHeader set curent song if playList have playng song * @brief findHeader set curent song if playList have playng song
@ -87,17 +81,7 @@ private:
* @return song drom local database. * @return song drom local database.
*/ */
Song fromDataBase(const int id); Song fromDataBase(const int id);
/**
* @brief now - get now time on microsecunds
* @return - count of microsecunds
*/
milliseconds now();
/**
* @brief from cast to chrono secunds
* @param mcrs microseconds of uint_64
* @return microseconds of chrono
*/
Clock from(const milliseconds &mcrs);
/** /**
* @brief createPackage - Create a package that shows current state of the node * @brief createPackage - Create a package that shows current state of the node
* @param type - Type of an answer * @param type - Type of an answer