1. 程式人生 > >Qt應用Redis實現訊息佇列

Qt應用Redis實現訊息佇列

 

 

類似BS模式,客戶端傳送任務請求給服務端,服務端將處理結果返回給客戶端。 redis負責訊息的儲存和轉發。

模擬病人掛號看病,Patient程序進行掛號,Doctor程序進行看病 ,程式程式碼如下:

////////////////////////////////////////////Patient//////////////////////////////////////////// 

Patient.h:

 

  1.   #include <QObject>
  2.    
  3.   class QRedis;
  4.    
  5.   class Patient : public QObject
  6.   {
  7.   Q_OBJECT
  8.    
  9.   public:
  10.   Patient(QObject *parent = nullptr);
  11.   ~Patient();
  12.    
  13.   public slots:
  14.   void pushTask(); //push任務
  15.    
  16.   private:
  17.   void popResult(); //pop結果
  18.   QRedis * m_redis;
  19.   };
Patient.cpp

 

 

  1.   #include "patient.h"
  2.   #include "qredis.h"
  3.   #include <QTimer>
  4.   #include <QEventLoop>
  5.   #include <QThread>
  6.    
  7.   static const QString KEYTASK = "MARKTASK";
  8.   static const QString KEYRESULT = "MARKRESULT";
  9.    
  10.   Patient::Patient(QObject *parent)
  11.   : QObject(parent)
  12.   {
  13.   //初始化通道
  14.   m_redis = new QRedis(this);
  15.   m_redis->connectHost( "127.0.0.1", 6379);
  16.   m_redis->auth( "1234");
  17.    
  18.   qDebug() << "client thread id :" << int(QThread::currentThreadId());
  19.    
  20.   //輪詢任務
  21.   QTimer * timer = new QTimer(this);
  22.   connect(timer, &QTimer::timeout, this, &Patient::popResult);
  23.   timer->start( 20);
  24.    
  25.   m_redis->del(KEYRESULT);
  26.   m_redis->del(KEYTASK);
  27.   pushTask();
  28.   }
  29.    
  30.   Patient::~Patient()
  31.   {
  32.   }
  33.    
  34.   void Patient::pushTask()
  35.   {
  36.   static int i = 0;
  37.   QString task = QStringLiteral( "%1號,姓名:%2,狀態:%3").arg(++i).arg(QStringLiteral("病人%1").arg(i)).arg(QStringLiteral("掛號"));
  38.   qDebug() << "========================================================\n\n"<< task;
  39.   qDebug() << "thread id :" << int(QThread::currentThreadId());
  40.   qint64 ret = m_redis->rpush(KEYTASK, task);
  41.   }
  42.    
  43.   void Patient::popResult()
  44.   {
  45.   QString state;
  46.   QString taskData = m_redis->lpop(KEYRESULT);
  47.   if (taskData.compare("nil", Qt::CaseInsensitive) == 0 || taskData.isEmpty())
  48.   {
  49.   return;
  50.   }
  51.   QEventLoop loop;
  52.   QTimer::singleShot( 5000, &loop, &QEventLoop::quit);
  53.   loop.exec();
  54.   pushTask();
  55.   }
  56.    
main.cpp

 

 

  1.   #include <QtCore/QCoreApplication>
  2.   #include <QDebug>
  3.   #include <QThread>
  4.   #include "patient.h"
  5.    
  6.   int main(int argc, char *argv[])
  7.   {
  8.   QCoreApplication a(argc, argv);
  9.    
  10.   qDebug() << QString( "main thread id = : %1").arg(int(QThread::currentThreadId()));
  11.    
  12.   QThread patientThread;
  13.   Patient patient;
  14.   patient.moveToThread(&patientThread);
  15.   patientThread.start();
  16.   return a.exec();
  17.   }

/////////////////////////////////////////////////Docktor/////////////////////////////////////////////////

 

Docktor.h

 

  1.   #pragma once
  2.    
  3.   #include <QObject>
  4.    
  5.   class QRedis;
  6.    
  7.   class Docktor : public QObject
  8.   {
  9.   Q_OBJECT
  10.    
  11.   public:
  12.   Docktor(QObject *parent = nullptr);
  13.   ~Docktor();
  14.    
  15.   public slots:
  16.   void popTask(); //pop任務
  17.    
  18.   private:
  19.   void pushResult(const QString &task); //push結果
  20.    
  21.   QRedis * m_redis;
  22.   };

Docktor.cpp

 

 

  1.   #include "docktor.h"
  2.   #include "qredis.h"
  3.   #include <QTimer>
  4.   #include <QEventLoop>
  5.   #include <QThread>
  6.    
  7.   static const QString KEYTASK = "MARKTASK";
  8.   static const QString KEYRESULT = "MARKRESULT";
  9.    
  10.   Docktor::Docktor(QObject *parent)
  11.   : QObject(parent)
  12.   {
  13.   //初始化通道
  14.   m_redis = new QRedis(this);
  15.   m_redis->connectHost( "127.0.0.1", 6379);
  16.   m_redis->auth( "1234");
  17.    
  18.   QTimer * timer = new QTimer(this);
  19.   connect(timer, &QTimer::timeout, this, &Docktor::popTask);
  20.   timer->start( 20);
  21.   }
  22.    
  23.   Docktor::~Docktor()
  24.   {
  25.   }
  26.    
  27.   void Docktor::popTask()
  28.   {
  29.   //獲取任務
  30.   QString taskData = m_redis->lpop(KEYTASK);
  31.   if (taskData.compare("nil", Qt::CaseInsensitive) == 0 || taskData.isEmpty())
  32.   {
  33.   //qDebug() << QString("wait..............................");
  34.   return;
  35.   }
  36.   //處理任務
  37.   pushResult(taskData);
  38.   }
  39.    
  40.   void Docktor::pushResult(const QString &task)
  41.   {
  42.   QStringList taskDatas = task.split( ",");
  43.   QString state = taskDatas.at( 2);
  44.   taskDatas.removeLast();
  45.   taskDatas.append(QStringLiteral( "狀態:看病"));
  46.   //push處理結果
  47.   qDebug() << "========================================================\n\n" << taskDatas.join(",");
  48.   qDebug() << "thread id :" << int(QThread::currentThreadId());
  49.   qint64 ret = m_redis->rpush(KEYRESULT, taskDatas.join( ","));
  50.   }
  51.    
main.cpp

 

 

  1.   #include <QtCore/QCoreApplication>
  2.   #include <QDebug>
  3.   #include <QThread>
  4.   #include "docktor.h"
  5.    
  6.   int main(int argc, char *argv[])
  7.   {
  8.   QCoreApplication a(argc, argv);
  9.   qDebug() << QString( "main thread id = : %1").arg(int(QThread::currentThreadId()));
  10.    
  11.   QThread docktorThread;
  12.   Docktor docktor;
  13.   docktor.moveToThread(&docktorThread);
  14.   docktorThread.start();
  15.   return a.exec();
  16.   }

/////////////////截圖/////////////