1
0
mirror of https://gitee.com/drabel/LibQQt.git synced 2025-01-04 10:18:44 +08:00

update namedpipe and singleton

This commit is contained in:
tianduanrui 2018-07-14 10:31:56 +08:00
parent 24e7bebf80
commit 110a94d480
12 changed files with 525 additions and 475 deletions

View File

@ -9,7 +9,7 @@
TEMPLATE = subdirs
CONFIG += ordered
#SUBDIRS += test/singletonapptest
SUBDIRS += test/singletonapptest
SUBDIRS += test/namedpipetest
#SUBDIRS += demo/QQtClientCreator
#SUBDIRS += demo/QQtServerCreator

View File

@ -20,9 +20,12 @@ QQtNamedPipe::QQtNamedPipe ( const QString& key, QObject* parent )
connect ( c0, SIGNAL ( stateChanged ( QLocalSocket::LocalSocketState ) ),
this, SLOT ( slotSocketStateChanged ( QLocalSocket::LocalSocketState ) ) );
hasServer = true;
bAccepted = false;
eLoop = new QEventLoop ( this );
connect ( p0, SIGNAL ( signalSuccessCommand() ), eLoop, SLOT ( quit() ) );
}
QQtNamedPipe::~QQtNamedPipe()
@ -47,6 +50,7 @@ void QQtNamedPipe::write ( const QByteArray& bytes )
p0->sendCommand0x0b ( bytes );
c0->waitForBytesWritten();
pline();
eLoop->exec();
//c0->waitForReadyRead();
pline();
}
@ -56,6 +60,7 @@ QByteArray QQtNamedPipe::read ( int size )
p0->sendCommand0x0a ( size );
c0->waitForBytesWritten();
pline();
eLoop->exec();
//c0->waitForReadyRead();
pline();
return p0->bytes();
@ -63,14 +68,15 @@ QByteArray QQtNamedPipe::read ( int size )
bool QQtNamedPipe::create()
{
bool ret = false;
//准备连接到这个服务器
c0->setServerIPAddress ( "QQtNamedPipeServer" );
c0->sendConnectToHost();
c0->waitForConnected();
return true;
ret = c0->waitForConnected();
return ret;
//这一个server管理所有的pipe了。 第一次返回true后来返回false但是可以用。
bool ret = false;
if ( !s0->isListening() )
{
s0->listen ( "QQtNamedPipeServer" );
@ -88,6 +94,7 @@ bool QQtNamedPipe::attach()
pline();
ret = c0->waitForBytesWritten();
pline();
eLoop->exec();
//ret = c0->waitForReadyRead();
pline();
return ret;

View File

@ -62,8 +62,8 @@ public slots:
private:
protected:
bool create();
bool attach();
virtual bool create();
virtual bool attach();
private:
QQtNamedPipeClientProtocol* p0;
QQtLocalClient* c0;
@ -75,6 +75,8 @@ private:
bool hasServer;
bool bAccepted;
QEventLoop* eLoop;
};

View File

@ -69,6 +69,7 @@ QQtNamedPipeClientProtocol::~QQtNamedPipeClientProtocol()
void QQtNamedPipeClientProtocol::recvCommand0x01 ( const QQtNamedPipeMessage& msg )
{
pline() << "client receive set key ack:" << msg.cmd();
emit signalSuccessCommand();
}
void QQtNamedPipeClientProtocol::recvCommand0x0a ( const QQtNamedPipeMessage& msg )
@ -76,6 +77,7 @@ void QQtNamedPipeClientProtocol::recvCommand0x0a ( const QQtNamedPipeMessage& ms
//what do you want to do?
pline() << "client receive read data ack:" << msg.cmd();
mBytes = msg.data();
emit signalSuccessCommand();
}
void QQtNamedPipeClientProtocol::recvCommand0x0b ( const QQtNamedPipeMessage& msg )
@ -83,6 +85,7 @@ void QQtNamedPipeClientProtocol::recvCommand0x0b ( const QQtNamedPipeMessage& ms
//what do you want to do?
pline() << "client receive write data ack:" << msg.cmd();
//不处理。
emit signalSuccessCommand();
}
void QQtNamedPipeClientProtocol::sendCommand0x01 ( QString key )

View File

@ -66,6 +66,7 @@ private:
signals:
//给业务层发的信号
void signalSendtoLogicLevelCode();
void signalSuccessCommand();
public slots:

View File

@ -1,328 +1,11 @@
#include <qqtsingletonapplication.h>
QQtSingleTonLocalClientMessage::QQtSingleTonLocalClientMessage ( QObject* parent )
{
mSize = 0x03;//报文定长
}
QQtSingleTonLocalClientMessage::~QQtSingleTonLocalClientMessage()
{
}
quint8& QQtSingleTonLocalClientMessage::size() { return mSize; }
const quint8& QQtSingleTonLocalClientMessage::size() const { return mSize; }
quint8& QQtSingleTonLocalClientMessage::cmd() { return mCmd; }
const quint8& QQtSingleTonLocalClientMessage::cmd() const { return mCmd; }
quint8& QQtSingleTonLocalClientMessage::data() { return mData; }
const quint8& QQtSingleTonLocalClientMessage::data() const { return mData; }
void QQtSingleTonLocalClientMessage::parser ( const QByteArray& l )
{
QByteArray _l = l;
_l >> mSize;
_l >> mCmd;
_l >> mData;
}
void QQtSingleTonLocalClientMessage::packer ( QByteArray& l ) const
{
l << mSize;
l << mCmd;
l << mData;
}
QDebug& operator << ( QDebug& dbg, const QQtSingleTonLocalClientMessage& msg )
{
//这里打印一下,报文里面到底有什么信息,
//一般到这里的都是被解析好的message。
dbg.nospace() << "{" << hex << msg.size() << "}";
return dbg.space();
}
QQtSingleTonLocalClientProtocol::QQtSingleTonLocalClientProtocol ( QObject* parent )
{
}
QQtSingleTonLocalClientProtocol::~QQtSingleTonLocalClientProtocol()
{
}
void QQtSingleTonLocalClientProtocol::recvCommand1 ( const QQtSingleTonLocalClientMessage& msg )
{
//what do you want to do?
pline() << "client receive accept:" << msg.cmd();
emit signalAccept();
}
void QQtSingleTonLocalClientProtocol::recvCommand2 ( const QQtSingleTonLocalClientMessage& msg )
{
//what do you want to do?
pline() << "client receive reject:" << msg.cmd();
emit signalReject();
}
void QQtSingleTonLocalClientProtocol::sendCommand1()
{
//what do you want to do?
QQtSingleTonLocalClientMessage msg;
msg.cmd() = 0x0a;
QByteArray l;
msg.packer ( l );
write ( l );
}
void QQtSingleTonLocalClientProtocol::sendCommand2()
{
//what do you want to do?
QQtSingleTonLocalClientMessage msg;
msg.cmd() = 0x0b;
QByteArray l;
msg.packer ( l );
write ( l );
}
quint16 QQtSingleTonLocalClientProtocol::minlength()
{
return 0x03;
}
quint16 QQtSingleTonLocalClientProtocol::maxlength()
{
return 0x07FF;
}
quint16 QQtSingleTonLocalClientProtocol::splitter ( const QByteArray& l ) //stream
{
QByteArray s0 = l.left ( 1 );
quint8 size = 0;
s0 >> size;
return size;
}
bool QQtSingleTonLocalClientProtocol::dispatcher ( const QByteArray& m ) //message
{
bool ret = true;
QQtSingleTonLocalClientMessage qMsg;
qMsg.parser ( m );
pline() << qMsg;
//0x0a.
switch ( qMsg.cmd() )
{
case 0x0a://protocol command 1
recvCommand1 ( qMsg );
break;
case 0x0b://protocol command 2
recvCommand2 ( qMsg );
break;
default:
ret = false;
pline() << "receive unknown command:" << hex << qMsg.cmd();
break;
}
return ret;
}
QQtLocalClient* QQtSingleTonLocalClientInstance ( QQtSingleTonLocalClientProtocol*& protocol, QObject* parent )
{
static QQtSingleTonLocalClientProtocol* p0 = NULL;
if ( !p0 )
{
p0 = new QQtSingleTonLocalClientProtocol ( parent );
}
protocol = p0;
static QQtLocalClient* s0 = NULL;
if ( !s0 )
{
s0 = new QQtLocalClient ( parent );
s0->installProtocol ( p0 );
s0->setServerIPAddress ( "QQtSingleTon" );
//现在不连接。
//s0->sendConnectToHost();
}
return s0;
}
QQtSingleTonLocalServerMessage::QQtSingleTonLocalServerMessage ( QObject* parent )
{
mSize = 0x03;//报文定长
}
QQtSingleTonLocalServerMessage::~QQtSingleTonLocalServerMessage()
{
}
quint8& QQtSingleTonLocalServerMessage::size() { return mSize; }
const quint8& QQtSingleTonLocalServerMessage::size() const { return mSize; }
quint8& QQtSingleTonLocalServerMessage::cmd() { return mCmd; }
const quint8& QQtSingleTonLocalServerMessage::cmd() const { return mCmd; }
quint8& QQtSingleTonLocalServerMessage::data() { return mData; }
const quint8& QQtSingleTonLocalServerMessage::data() const { return mData; }
void QQtSingleTonLocalServerMessage::parser ( const QByteArray& l )
{
QByteArray _l = l;
_l >> mSize;
_l >> mCmd;
_l >> mData;
}
void QQtSingleTonLocalServerMessage::packer ( QByteArray& l ) const
{
l << mSize;
l << mCmd;
l << mData;
}
QDebug& operator << ( QDebug& dbg, const QQtSingleTonLocalServerMessage& msg )
{
//这里打印一下,报文里面到底有什么信息,
//一般到这里的都是被解析好的message。
dbg.nospace() << "{" << hex << msg.size() << "}";
return dbg.space();
}
QQtSingleTonLocalServerProtocol::QQtSingleTonLocalServerProtocol ( QObject* parent )
{
}
QQtSingleTonLocalServerProtocol::~QQtSingleTonLocalServerProtocol()
{
}
void QQtSingleTonLocalServerProtocol::recvCommand1 ( const QQtSingleTonLocalServerMessage& msg )
{
//what do you want to do?
sendCommand1();
}
void QQtSingleTonLocalServerProtocol::recvCommand2 ( const QQtSingleTonLocalServerMessage& msg )
{
//what do you want to do?
sendCommand2();
}
void QQtSingleTonLocalServerProtocol::sendCommand1()
{
//what do you want to do?
QQtSingleTonLocalServerMessage msg;
msg.cmd() = 0x0a;
QByteArray l;
msg.packer ( l );
write ( l );
pline() << "server send accept:" << msg.cmd();
}
void QQtSingleTonLocalServerProtocol::sendCommand2()
{
//what do you want to do?
QQtSingleTonLocalServerMessage msg;
msg.cmd() = 0x0b;
QByteArray l;
msg.packer ( l );
write ( l );
pline() << "server send reject:" << msg.cmd();
}
quint16 QQtSingleTonLocalServerProtocol::minlength()
{
return 0x03;
}
quint16 QQtSingleTonLocalServerProtocol::maxlength()
{
return 0x07FF;
}
quint16 QQtSingleTonLocalServerProtocol::splitter ( const QByteArray& l ) //stream
{
QByteArray s0 = l.left ( 1 );
quint8 size = 0;
s0 >> size;
return size;
}
bool QQtSingleTonLocalServerProtocol::dispatcher ( const QByteArray& m ) //message
{
bool ret = true;
QQtSingleTonLocalServerMessage qMsg;
qMsg.parser ( m );
pline() << qMsg;
switch ( qMsg.cmd() )
{
case 0x0a://protocol command 1
recvCommand1 ( qMsg );
break;
case 0x0b://protocol command 2
recvCommand2 ( qMsg );
break;
default:
ret = false;
pline() << "receive unknown command:" << hex << qMsg.cmd();
break;
}
return ret;
}
QQtLocalServer* QQtSingleTonLocalServerInstance ( QQtProtocolManager*& protocolManager, QObject* parent )
{
static QQtProtocolManager* pm0 = 0;
if ( !pm0 )
{
pm0 = new QQtProtocolManager ( parent );
pm0->registerProtocol<QQtSingleTonLocalServerProtocol>();
}
protocolManager = pm0;
static QQtLocalServer* s0 = NULL;
if ( !s0 )
{
s0 = new QQtLocalServer ( parent );
s0->installProtocolManager ( pm0 ) ;
//现在不监听。
//s0->listen("QQtSingleTon");
}
return s0;
}
#include <qqtsingletonapplicationprivate.h>
QQtSingleTonApplication::QQtSingleTonApplication ( int& argc, char** argv ) : QQtApplication ( argc, argv )
{
QQtApplication::setOrganizationName ( "QQtSingleTon" );
QQtApplication::setOrganizationDomain ( "www.qqt.singleton.com" ); //
//无论如何都要设置。
QQtApplication::setApplicationName ( "QQtSingleTon" );
hasServer = true;
@ -348,8 +31,6 @@ QQtSingleTonApplication::QQtSingleTonApplication ( int& argc, char** argv ) : QQ
connect ( c0, SIGNAL ( stateChanged ( QLocalSocket::LocalSocketState ) ),
this, SLOT ( slotSocketStateChanged ( QLocalSocket::LocalSocketState ) ) );
c0->sendConnectToHost();
}
QQtSingleTonApplication::~QQtSingleTonApplication()
@ -358,10 +39,17 @@ QQtSingleTonApplication::~QQtSingleTonApplication()
#else
//linux下如果被接受的app不删除这个server那么无法启动了吆。
if ( bAccepted )
QLocalServer::removeServer ( "QQtSingleTon" );
QLocalServer::removeServer ( qqtApp->applicationName() );
#endif
}
void QQtSingleTonApplication::startSingleTonInstance()
{
c0->setServerIPAddress ( qqtApp->applicationName() );
c0->sendConnectToHost();
c0->waitForConnected();
}
void QQtSingleTonApplication::slotSocketStateChanged ( QLocalSocket::LocalSocketState eSocketState )
{
switch ( eSocketState )
@ -382,7 +70,7 @@ void QQtSingleTonApplication::slotSocketStateChanged ( QLocalSocket::LocalSocket
if ( !hasServer )
return;
hasServer = false;
s0->listen ( "QQtSingleTon" );
s0->listen ( qqtApp->applicationName() );
c0->sendConnectToHost();
#endif
break;
@ -428,16 +116,17 @@ void QQtSingleTonApplication::slotConnectFail()
pline() << "fail";
#ifdef Q_OS_WIN
hasServer = false;
s0->listen ( "QQtSingleTon" );
s0->listen ( qqtApp->applicationName() );
c0->sendConnectToHost();
#else
//refused or notfound
if ( c0->error() == QLocalSocket::ConnectionRefusedError )
{
//这个的错误很严重被启动的那个App走的时候没有关闭server。在这里关闭。
QLocalServer::removeServer ( "QQtSingleTon" );
QLocalServer::removeServer ( qqtApp->applicationName() );
}
c0->sendDisConnectFromHost();
//waitfordisconnnect也可以在这里监听和开始连接。
#endif
}

View File

@ -20,6 +20,13 @@ QQtLocalServer* QQtSingleTonLocalServerInstance ( QQtProtocolManager*& protocol,
/**
* @brief The QQtSingleApplication class
* Application
*
* 使
*
* QQtApplication::setOrganizationName ( "AppName" );
* QQtApplication::setOrganizationDomain ( "www.appname.com" ); //
* QQtApplication::setApplicationName ( "AppName" ); //必要。
* startSingleTonInstance();
*/
class QQTSHARED_EXPORT QQtSingleTonApplication : public QQtApplication
{
@ -28,6 +35,8 @@ public:
explicit QQtSingleTonApplication ( int& argc, char** argv );
virtual ~QQtSingleTonApplication();
void startSingleTonInstance();
protected slots:
void slotSocketStateChanged ( QLocalSocket::LocalSocketState );
void slotConnectSuccess();
@ -47,145 +56,4 @@ private:
};
#include <qqtmessage.h>
#include <qqtprotocol.h>
#include <qqtlocalclient.h>
class QQtSingleTonLocalClientMessage : public QQtMessage
{
Q_OBJECT
public:
explicit QQtSingleTonLocalClientMessage ( QObject* parent = nullptr );
~QQtSingleTonLocalClientMessage();
quint8& size();
const quint8& size() const;
quint8& cmd();
const quint8& cmd() const;
quint8& data();
const quint8& data() const;
private:
//格式
//|quint8 size|quint8 cmd|quint8 data|
quint8 mSize;
quint8 mCmd;
quint8 mData;
// QQtMessage interface
public:
//把报文这条流解析出字段
virtual void parser ( const QByteArray& l ) override;
//把报文字段组装成流
virtual void packer ( QByteArray& l ) const override;
};
QDebug& operator << ( QDebug&, const QQtSingleTonLocalClientMessage& msg );
//业务层总是用这个协议工作,读来到的,写出去的。
class QQtSingleTonLocalClientProtocol : public QQtProtocol
{
Q_OBJECT
public:
explicit QQtSingleTonLocalClientProtocol ( QObject* parent = nullptr );
~QQtSingleTonLocalClientProtocol();
//没连接上创建Server发送I Create you (0x0a). Server回复I Accept you (0x0a)。
//连接上了发送I Find you (0x0b)。Server回复存在Server (0x0b),告诉上层,关闭程序。
//收到外部发来的很多命令,处理一下告诉业务层干点什么。
void recvCommand1 ( const QQtSingleTonLocalClientMessage& msg );
void recvCommand2 ( const QQtSingleTonLocalClientMessage& msg );
void sendCommand1();
void sendCommand2();
signals:
//给业务层发的信号
void signalSendtoLogicLevelCode();
void signalAccept();
void signalReject();
public slots:
// QQtProtocol interface
protected:
//报文的最小长度
virtual quint16 minlength() override;
//报文的最大长度
virtual quint16 maxlength() override;
//报文现在在流里第一个字节就是size读出来通过返回值告诉QQtProtocol
virtual quint16 splitter ( const QByteArray& l ) override;
//报文现在被切开发了进来第二个字节是cmd解析出来在函数里处理处理数据告诉业务层拿到数据了干点什么。
virtual bool dispatcher ( const QByteArray& m ) override;
};
#include <qqtprotocolmanager.h>
#include <qqtlocalserver.h>
class QQtSingleTonLocalServerMessage : public QQtMessage
{
Q_OBJECT
public:
explicit QQtSingleTonLocalServerMessage ( QObject* parent = nullptr );
~QQtSingleTonLocalServerMessage();
quint8& size();
const quint8& size() const;
quint8& cmd();
const quint8& cmd() const;
quint8& data();
const quint8& data() const;
private:
//格式
//|quint8 size|quint8 cmd|quint8 data|
quint8 mSize;
quint8 mCmd;
quint8 mData;
// QQtMessage interface
public:
//把报文这条流解析出字段
virtual void parser ( const QByteArray& l ) override;
//把报文字段组装成流
virtual void packer ( QByteArray& l ) const override;
};
QDebug& operator << ( QDebug&, const QQtSingleTonLocalServerMessage& msg );
//业务层总是用这个协议工作,读来到的,写出去的。
class QQtSingleTonLocalServerProtocol : public QQtProtocol
{
Q_OBJECT
public:
explicit QQtSingleTonLocalServerProtocol ( QObject* parent = nullptr );
~QQtSingleTonLocalServerProtocol();
//收到外部发来的很多命令,处理一下告诉业务层干点什么。
void recvCommand1 ( const QQtSingleTonLocalServerMessage& msg );
void recvCommand2 ( const QQtSingleTonLocalServerMessage& msg );
void sendCommand1();
void sendCommand2();
signals:
//给业务层发的信号
void signalSendtoLogicLevelCode();
public slots:
// QQtProtocol interface
protected:
//报文的最小长度
virtual quint16 minlength() override;
//报文的最大长度
virtual quint16 maxlength() override;
//报文现在在流里第一个字节就是size读出来通过返回值告诉QQtProtocol
virtual quint16 splitter ( const QByteArray& l ) override;
//报文现在被切开发了进来第二个字节是cmd解析出来在函数里处理处理数据告诉业务层拿到数据了干点什么。
virtual bool dispatcher ( const QByteArray& m ) override;
};
#endif // QQTSINGLETONAPPLICATION_H

View File

@ -0,0 +1,321 @@
#include <qqtsingletonapplicationprivate.h>
QQtSingleTonLocalClientMessage::QQtSingleTonLocalClientMessage ( QObject* parent )
{
mSize = 0x03;//报文定长
}
QQtSingleTonLocalClientMessage::~QQtSingleTonLocalClientMessage()
{
}
quint8& QQtSingleTonLocalClientMessage::size() { return mSize; }
const quint8& QQtSingleTonLocalClientMessage::size() const { return mSize; }
quint8& QQtSingleTonLocalClientMessage::cmd() { return mCmd; }
const quint8& QQtSingleTonLocalClientMessage::cmd() const { return mCmd; }
quint8& QQtSingleTonLocalClientMessage::data() { return mData; }
const quint8& QQtSingleTonLocalClientMessage::data() const { return mData; }
void QQtSingleTonLocalClientMessage::parser ( const QByteArray& l )
{
QByteArray _l = l;
_l >> mSize;
_l >> mCmd;
_l >> mData;
}
void QQtSingleTonLocalClientMessage::packer ( QByteArray& l ) const
{
l << mSize;
l << mCmd;
l << mData;
}
QDebug& operator << ( QDebug& dbg, const QQtSingleTonLocalClientMessage& msg )
{
//这里打印一下,报文里面到底有什么信息,
//一般到这里的都是被解析好的message。
dbg.nospace() << "{" << hex << msg.size() << "}";
return dbg.space();
}
QQtSingleTonLocalClientProtocol::QQtSingleTonLocalClientProtocol ( QObject* parent )
{
}
QQtSingleTonLocalClientProtocol::~QQtSingleTonLocalClientProtocol()
{
}
void QQtSingleTonLocalClientProtocol::recvCommand1 ( const QQtSingleTonLocalClientMessage& msg )
{
//what do you want to do?
pline() << "client receive accept:" << msg.cmd();
emit signalAccept();
}
void QQtSingleTonLocalClientProtocol::recvCommand2 ( const QQtSingleTonLocalClientMessage& msg )
{
//what do you want to do?
pline() << "client receive reject:" << msg.cmd();
emit signalReject();
}
void QQtSingleTonLocalClientProtocol::sendCommand1()
{
//what do you want to do?
QQtSingleTonLocalClientMessage msg;
msg.cmd() = 0x0a;
QByteArray l;
msg.packer ( l );
write ( l );
}
void QQtSingleTonLocalClientProtocol::sendCommand2()
{
//what do you want to do?
QQtSingleTonLocalClientMessage msg;
msg.cmd() = 0x0b;
QByteArray l;
msg.packer ( l );
write ( l );
}
quint16 QQtSingleTonLocalClientProtocol::minlength()
{
return 0x03;
}
quint16 QQtSingleTonLocalClientProtocol::maxlength()
{
return 0x07FF;
}
quint16 QQtSingleTonLocalClientProtocol::splitter ( const QByteArray& l ) //stream
{
QByteArray s0 = l.left ( 1 );
quint8 size = 0;
s0 >> size;
return size;
}
bool QQtSingleTonLocalClientProtocol::dispatcher ( const QByteArray& m ) //message
{
bool ret = true;
QQtSingleTonLocalClientMessage qMsg;
qMsg.parser ( m );
pline() << qMsg;
//0x0a.
switch ( qMsg.cmd() )
{
case 0x0a://protocol command 1
recvCommand1 ( qMsg );
break;
case 0x0b://protocol command 2
recvCommand2 ( qMsg );
break;
default:
ret = false;
pline() << "receive unknown command:" << hex << qMsg.cmd();
break;
}
return ret;
}
QQtLocalClient* QQtSingleTonLocalClientInstance ( QQtSingleTonLocalClientProtocol*& protocol, QObject* parent )
{
static QQtSingleTonLocalClientProtocol* p0 = NULL;
if ( !p0 )
{
p0 = new QQtSingleTonLocalClientProtocol ( parent );
}
protocol = p0;
static QQtLocalClient* s0 = NULL;
if ( !s0 )
{
s0 = new QQtLocalClient ( parent );
s0->installProtocol ( p0 );
//现在不设置。
//s0->setServerIPAddress ( qqtApp->applicationName() );
//现在不连接。
//s0->sendConnectToHost();
}
return s0;
}
QQtSingleTonLocalServerMessage::QQtSingleTonLocalServerMessage ( QObject* parent )
{
mSize = 0x03;//报文定长
}
QQtSingleTonLocalServerMessage::~QQtSingleTonLocalServerMessage()
{
}
quint8& QQtSingleTonLocalServerMessage::size() { return mSize; }
const quint8& QQtSingleTonLocalServerMessage::size() const { return mSize; }
quint8& QQtSingleTonLocalServerMessage::cmd() { return mCmd; }
const quint8& QQtSingleTonLocalServerMessage::cmd() const { return mCmd; }
quint8& QQtSingleTonLocalServerMessage::data() { return mData; }
const quint8& QQtSingleTonLocalServerMessage::data() const { return mData; }
void QQtSingleTonLocalServerMessage::parser ( const QByteArray& l )
{
QByteArray _l = l;
_l >> mSize;
_l >> mCmd;
_l >> mData;
}
void QQtSingleTonLocalServerMessage::packer ( QByteArray& l ) const
{
l << mSize;
l << mCmd;
l << mData;
}
QDebug& operator << ( QDebug& dbg, const QQtSingleTonLocalServerMessage& msg )
{
//这里打印一下,报文里面到底有什么信息,
//一般到这里的都是被解析好的message。
dbg.nospace() << "{" << hex << msg.size() << "}";
return dbg.space();
}
QQtSingleTonLocalServerProtocol::QQtSingleTonLocalServerProtocol ( QObject* parent )
{
}
QQtSingleTonLocalServerProtocol::~QQtSingleTonLocalServerProtocol()
{
}
void QQtSingleTonLocalServerProtocol::recvCommand1 ( const QQtSingleTonLocalServerMessage& msg )
{
//what do you want to do?
sendCommand1();
}
void QQtSingleTonLocalServerProtocol::recvCommand2 ( const QQtSingleTonLocalServerMessage& msg )
{
//what do you want to do?
sendCommand2();
}
void QQtSingleTonLocalServerProtocol::sendCommand1()
{
//what do you want to do?
QQtSingleTonLocalServerMessage msg;
msg.cmd() = 0x0a;
QByteArray l;
msg.packer ( l );
write ( l );
pline() << "server send accept:" << msg.cmd();
}
void QQtSingleTonLocalServerProtocol::sendCommand2()
{
//what do you want to do?
QQtSingleTonLocalServerMessage msg;
msg.cmd() = 0x0b;
QByteArray l;
msg.packer ( l );
write ( l );
pline() << "server send reject:" << msg.cmd();
}
quint16 QQtSingleTonLocalServerProtocol::minlength()
{
return 0x03;
}
quint16 QQtSingleTonLocalServerProtocol::maxlength()
{
return 0x07FF;
}
quint16 QQtSingleTonLocalServerProtocol::splitter ( const QByteArray& l ) //stream
{
QByteArray s0 = l.left ( 1 );
quint8 size = 0;
s0 >> size;
return size;
}
bool QQtSingleTonLocalServerProtocol::dispatcher ( const QByteArray& m ) //message
{
bool ret = true;
QQtSingleTonLocalServerMessage qMsg;
qMsg.parser ( m );
pline() << qMsg;
switch ( qMsg.cmd() )
{
case 0x0a://protocol command 1
recvCommand1 ( qMsg );
break;
case 0x0b://protocol command 2
recvCommand2 ( qMsg );
break;
default:
ret = false;
pline() << "receive unknown command:" << hex << qMsg.cmd();
break;
}
return ret;
}
QQtLocalServer* QQtSingleTonLocalServerInstance ( QQtProtocolManager*& protocolManager, QObject* parent )
{
static QQtProtocolManager* pm0 = 0;
if ( !pm0 )
{
pm0 = new QQtProtocolManager ( parent );
pm0->registerProtocol<QQtSingleTonLocalServerProtocol>();
}
protocolManager = pm0;
static QQtLocalServer* s0 = NULL;
if ( !s0 )
{
s0 = new QQtLocalServer ( parent );
s0->installProtocolManager ( pm0 ) ;
//现在不监听。
//s0->listen("QQtSingleTon");
}
return s0;
}

View File

@ -0,0 +1,151 @@
#ifndef QQTSINGLETONAPPLICATIONPRIVATE_H
#define QQTSINGLETONAPPLICATIONPRIVATE_H
#include <qqt-local.h>
#include <qqtcore.h>
#include <qlocalsocket.h>
#include <qlocalserver.h>
#include <qqtmessage.h>
#include <qqtprotocol.h>
#include <qqtlocalclient.h>
class QQtSingleTonLocalClientMessage : public QQtMessage
{
Q_OBJECT
public:
explicit QQtSingleTonLocalClientMessage ( QObject* parent = nullptr );
~QQtSingleTonLocalClientMessage();
quint8& size();
const quint8& size() const;
quint8& cmd();
const quint8& cmd() const;
quint8& data();
const quint8& data() const;
private:
//格式
//|quint8 size|quint8 cmd|quint8 data|
quint8 mSize;
quint8 mCmd;
quint8 mData;
// QQtMessage interface
public:
//把报文这条流解析出字段
virtual void parser ( const QByteArray& l ) override;
//把报文字段组装成流
virtual void packer ( QByteArray& l ) const override;
};
QDebug& operator << ( QDebug&, const QQtSingleTonLocalClientMessage& msg );
//业务层总是用这个协议工作,读来到的,写出去的。
class QQtSingleTonLocalClientProtocol : public QQtProtocol
{
Q_OBJECT
public:
explicit QQtSingleTonLocalClientProtocol ( QObject* parent = nullptr );
~QQtSingleTonLocalClientProtocol();
//没连接上创建Server发送I Create you (0x0a). Server回复I Accept you (0x0a)。
//连接上了发送I Find you (0x0b)。Server回复存在Server (0x0b),告诉上层,关闭程序。
//收到外部发来的很多命令,处理一下告诉业务层干点什么。
void recvCommand1 ( const QQtSingleTonLocalClientMessage& msg );
void recvCommand2 ( const QQtSingleTonLocalClientMessage& msg );
void sendCommand1();
void sendCommand2();
signals:
//给业务层发的信号
void signalSendtoLogicLevelCode();
void signalAccept();
void signalReject();
public slots:
// QQtProtocol interface
protected:
//报文的最小长度
virtual quint16 minlength() override;
//报文的最大长度
virtual quint16 maxlength() override;
//报文现在在流里第一个字节就是size读出来通过返回值告诉QQtProtocol
virtual quint16 splitter ( const QByteArray& l ) override;
//报文现在被切开发了进来第二个字节是cmd解析出来在函数里处理处理数据告诉业务层拿到数据了干点什么。
virtual bool dispatcher ( const QByteArray& m ) override;
};
#include <qqtprotocolmanager.h>
#include <qqtlocalserver.h>
class QQtSingleTonLocalServerMessage : public QQtMessage
{
Q_OBJECT
public:
explicit QQtSingleTonLocalServerMessage ( QObject* parent = nullptr );
~QQtSingleTonLocalServerMessage();
quint8& size();
const quint8& size() const;
quint8& cmd();
const quint8& cmd() const;
quint8& data();
const quint8& data() const;
private:
//格式
//|quint8 size|quint8 cmd|quint8 data|
quint8 mSize;
quint8 mCmd;
quint8 mData;
// QQtMessage interface
public:
//把报文这条流解析出字段
virtual void parser ( const QByteArray& l ) override;
//把报文字段组装成流
virtual void packer ( QByteArray& l ) const override;
};
QDebug& operator << ( QDebug&, const QQtSingleTonLocalServerMessage& msg );
//业务层总是用这个协议工作,读来到的,写出去的。
class QQtSingleTonLocalServerProtocol : public QQtProtocol
{
Q_OBJECT
public:
explicit QQtSingleTonLocalServerProtocol ( QObject* parent = nullptr );
~QQtSingleTonLocalServerProtocol();
//收到外部发来的很多命令,处理一下告诉业务层干点什么。
void recvCommand1 ( const QQtSingleTonLocalServerMessage& msg );
void recvCommand2 ( const QQtSingleTonLocalServerMessage& msg );
void sendCommand1();
void sendCommand2();
signals:
//给业务层发的信号
void signalSendtoLogicLevelCode();
public slots:
// QQtProtocol interface
protected:
//报文的最小长度
virtual quint16 minlength() override;
//报文的最大长度
virtual quint16 maxlength() override;
//报文现在在流里第一个字节就是size读出来通过返回值告诉QQtProtocol
virtual quint16 splitter ( const QByteArray& l ) override;
//报文现在被切开发了进来第二个字节是cmd解析出来在函数里处理处理数据告诉业务层拿到数据了干点什么。
virtual bool dispatcher ( const QByteArray& m ) override;
};
#endif //QQTSINGLETONAPPLICATIONPRIVATE_H

View File

@ -613,6 +613,10 @@ contains (DEFINES, __HIGHGRADE__) {
#singleton application
contains(DEFINES, __NAMEDPIPE_SUPPORT__){
SOURCES += \
$$PWD/highgrade/qqtsingletonapplicationprivate.cpp
HEADERS += \
$$PWD/highgrade/qqtsingletonapplicationprivate.h
#依赖local socket
SOURCES += \
$$PWD/highgrade/qqtsingletonapplication.cpp

View File

@ -8,7 +8,7 @@ MainWindow::MainWindow ( QWidget* parent ) :
ui ( new Ui::MainWindow )
{
ui->setupUi ( this );
QQtLocalServer::removeServer ( "QQtNamedPipeServer" );
//QQtLocalServer::removeServer ( "QQtNamedPipeServer" );
static QQtNamedPipe hold ( "mypipe0" );
hold.initializer();
}

View File

@ -6,10 +6,14 @@
int main ( int argc, char* argv[] )
{
QQtSingleTonApplication a ( argc, argv );
//QLocalServer::removeServer ( "QQtSingleTon" );
a.setApplicationName ( "singletonapptest" );
a.startSingleTonInstance();
//QLocalServer::removeServer ( "singletonapptest" );
QLocalServer b;
qDebug() << "listen:?" << b.listen ( "QQtSingleTon" );
qDebug() << "listen:?" << b.listen ( "singletonapptest" );
qDebug() << "listen:?" << b.isListening();
MainWindow w;
w.show();