fix sync nodes

This commit is contained in:
Andrei Yankovich 2017-12-17 02:05:07 +03:00
parent 17dabbaf6b
commit acd5191c0e
8 changed files with 54 additions and 85 deletions

View File

@ -40,6 +40,7 @@ void ETcpSocket::error_(QAbstractSocket::SocketError i){
}
void ETcpSocket::connected_(){
calibration();
emit Connected(this);
}

View File

@ -11,14 +11,14 @@ ChronoTime::ChronoTime()
* https://stackoverflow.com/questions/31255486/c-how-do-i-convert-a-stdchronotime-point-to-long-and-back
*/
milliseconds ChronoTime::now(){
milliseconds ChronoTime::now(int calibration){
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();
return epoh.count() + calibration;
}
Clock ChronoTime::from(const milliseconds& mc){

View File

@ -17,7 +17,7 @@ public:
* @brief now - get now time on microsecunds
* @return - count of microsecunds
*/
static milliseconds now();
static milliseconds now(int calibration = 0);
/**
* @brief from cast to chrono secunds
* @param mcrs microseconds of uint_64

View File

@ -67,8 +67,7 @@ class InitDBError:public std::exception
{
public:
QString what(){
return QObject::tr("Error creating database..");
return QObject::tr("Error creating database.");
}
};
#endif // EXAPTIONS_H

View File

@ -38,20 +38,16 @@ bool package::isValid() const{
}
if(type & TypePackage::t_feedback & TypePackage::t_sync){
return false;
if(type & TypePackage::t_play){
ret = ret && true;
}
if(type & TypePackage::t_sync && type & t_brodcaster){
if(type & TypePackage::t_sync && type & t_brodcaster){
ret = ret && (playdata.run > 0 && playdata.seek > 0);
}
if(type & TypePackage::t_feedback){
ret = ret && !(type & t_brodcaster) && (playdata.run > 0 && playdata.seek > 0);
}
if(type & TypePackage::t_song_h && type & t_brodcaster){
ret = ret && header.size > 0;
@ -80,8 +76,7 @@ QByteArray package::parseTo(){
if(isValid()){
stream << static_cast<unsigned char>(type);
if((type & TypePackage::t_sync && type & t_brodcaster) ||
(type & TypePackage::t_feedback && !(type & t_brodcaster))){
if(type & TypePackage::t_sync && type & t_brodcaster){
stream << playdata.run;
stream << playdata.seek;
@ -109,19 +104,18 @@ bool package::parseFrom(QByteArray &array){
stream >> temp_type;
type = static_cast<TypePackage> (temp_type);
if((type & TypePackage::t_sync && type & t_brodcaster) ||
(type & TypePackage::t_feedback && !(type & t_brodcaster))){
if(type & TypePackage::t_sync){
stream >> playdata.run;
stream >> playdata.seek;
}
if(type & TypePackage::t_song_h && type & t_brodcaster){
if(type & TypePackage::t_song_h){
stream >> header;
}
if(type & TypePackage::t_song && type & t_brodcaster){
if(type & TypePackage::t_song){
stream >> source;
}

View File

@ -12,7 +12,7 @@ typedef unsigned char Type;
/**
* @brief The TypePackage enum
* t_void = this package empty and not valid.
* t_feedback = feedback for synced.
* t_play = play curent audio file.
* t_song_h = the header of playing audio file.
* t_song = the package with this type is necessary for translite media data on network.
* t_sync = the infomation about sync playning media file on network.
@ -24,7 +24,7 @@ typedef unsigned char Type;
enum TypePackage{
t_void = 0x00,
t_feedback = 0x01,
t_play = 0x01,
t_song_h = 0x02,
t_song = 0x04,
t_sync = 0x08,

View File

@ -3,14 +3,11 @@
#include <QMultimedia>
#include <QSqlQuery>
#include "exaptions.h"
#include <ctime>
#include <thread>
#include <cmath>
#include "config.h"
#include "thread"
#include "chronotime.h"
#ifdef QT_DEBUG
#include <QDebug>
#include <iostream>
#endif
namespace syncLib{
@ -217,7 +214,7 @@ bool Sync::play(const Song &song, const Syncer *syncdata){
if(fbroadcaster){
package pac;
if(!createPackage(t_song_h | t_sync, pac)){
if(!createPackage(t_play, pac)){
throw CreatePackageExaption();
}
node->WriteAll(pac.parseTo());
@ -243,7 +240,7 @@ bool Sync::play(int id_song, Syncer *syncdata){
song.name = qyery->value(1).toString();
song.size = qyery->value(2).toInt();
song.source = qyery->value(3).toByteArray();
return Sync::play(song ,syncdata);
return Sync::play(song,syncdata);
}
bool Sync::play(QString url){
@ -251,6 +248,7 @@ bool Sync::play(QString url){
if(id < 0){
return false;
}
return Sync::play(id);
}
@ -275,13 +273,10 @@ bool Sync::sync(const Syncer &sync){
milliseconds sync_time = sync.run - ChronoTime::now();
if(sync_time > MAX_SYNC_TIME && sync_time <= 0)
return false;
Clock run_time = ChronoTime::from(sync.run);
do {
std::this_thread::yield();
} while (std::chrono::high_resolution_clock::now() < run_time);
player->setPosition(sync.seek);
return true;
}
@ -313,32 +308,29 @@ bool Sync::listen(ETcpSocket *server){
}
package pac;
if(!createPackage(t_sync,pac)){
if(!createPackage(t_sync, pac)){
return false;
}
return server->Write(pac.parseTo());
}
bool Sync::createPackage(Type type, package &pac){
bool Sync::createPackage(Type type, package &pac, const ETcpSocket *for_){
pac.clear();
pac.type = type;
if(type & TypePackage::t_sync && fbroadcaster){
if(type & TypePackage::t_sync && fbroadcaster){
pac.playdata.run = ChronoTime::now() + SYNC_TIME;
if(!for_ || !for_->isSynced()){
return false;
}
pac.playdata.run = ChronoTime::now(for_->getDifferenceTime()) + SYNC_TIME;
pac.playdata.seek = player->position() + SYNC_TIME;
}
if( type & TypePackage::t_feedback && !fbroadcaster){
pac.playdata.run = ChronoTime::now();
pac.playdata.seek = player->position();
}
if(type & TypePackage::t_song_h && fbroadcaster){
if(!curentSong)
return false;
@ -394,27 +386,27 @@ void Sync::packageRender(ETcpSocket *socket){
// if requst from server
if(pkg.getType() & t_sync){
if(!play(pkg.getHeader(), &pkg.getPlayData()) && !play(pkg.getSong(), &pkg.getPlayData())){
if(pkg.getType() & t_play){
Type requestType = t_song_h;
if(pkg.getType() & t_song_h)
requestType = t_song;
package answer;
if(!createPackage(requestType | t_sync, answer)){
throw CreatePackageExaption();
}
socket->Write(answer.parseTo());
}else{
package feedback;
if(!createPackage(t_feedback, feedback)){
throw feedbackError();
}
socket->Write(feedback.parseTo());
package answer;
if(!createPackage(t_sync, answer)){
throw CreatePackageExaption();
}
socket->Write(answer.parseTo());
}
if(pkg.getType() & t_sync && !play(pkg.getHeader(), &pkg.getPlayData()) && !play(pkg.getSong(), &pkg.getPlayData())){
Type requestType = t_song_h;
if(pkg.getType() & t_song_h)
requestType = t_song;
package answer;
if(!createPackage(requestType | t_sync, answer)){
throw CreatePackageExaption();
}
socket->Write(answer.parseTo());
}
if(pkg.getType() & t_close){
@ -434,33 +426,18 @@ void Sync::packageRender(ETcpSocket *socket){
}else{
if(pkg.getType() & t_sync ){
if(pkg.getType() & t_sync){
if(!curentSong){
return ;
}
}
Type responceType = pkg.getType();
if(pkg.getType() & t_feedback){
if(!curentSong){
return ;
throw SyncError();
}
unsigned int diff = ChronoTime::abs(player->position() - (pkg.getPlayData().seek + (ChronoTime::now() - pkg.getPlayData().run)));
#ifdef QT_DEBUG
qDebug() << "diff " << socket->name() <<": " << diff;
#endif
if(diff > 1){
responceType = responceType | t_sync;
}else{
std::cout<<"Synced!!"<<std::endl;
if(!socket->isSynced()){
socket->calibration();
}
}
package answer;
if(!createPackage(responceType & ~t_what & ~t_feedback & ~t_stop & ~t_brodcaster, answer)){
if(!createPackage(pkg.getType() & ~t_what & ~t_play & ~t_stop & ~t_brodcaster, answer, socket)){
throw CreatePackageExaption();
}
socket->Write(answer.parseTo());

View File

@ -13,6 +13,7 @@ class QSqlQuery;
class QBuffer;
namespace syncLib {
typedef std::chrono::time_point<std::chrono::high_resolution_clock> Clock;
class Node;
@ -36,7 +37,6 @@ private:
LocalScanner deepScaner;
int port;
QString dataBaseName;
/**
* @brief findHeader set curent song if playList have playng song
* @return true if all done
@ -81,14 +81,13 @@ private:
* @return song drom local database.
*/
Song fromDataBase(const int id);
/**
* @brief createPackage - Create a package that shows current state of the node
* @param type - Type of an answer
* @param pac - the resulting value
* @return true if everything's done
*/
bool createPackage(Type type ,package& pac);
bool createPackage(Type type , package& pac, const ETcpSocket *for_ = NULL);
private slots:
/**
@ -111,11 +110,10 @@ public:
/**
* @brief Play song in this device, if device has not supported playning media data this method throw MediaExcrption.
* @param header of song
* @param feedback - information about result of palying (cell default constructor if paying failed)
* @param syncdata data of synbced playning of media data.
* @return true if all done else false.
*/
bool play(const SongHeader &header, const Syncer *syncdata = nullptr);
bool play(const SongHeader &header, const Syncer *syncdata = nullptr);
/**
* @brief Play song in this device, if device has not supported playning media data this method throw MediaExcrption.
* @param song playning media data.