beerservice.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #include "beerservice.h"
  2. #include <QJsonDocument>
  3. #include <QJsonObject>
  4. #include "settingsservice.h"
  5. BeerService::BeerService()
  6. : QObject{nullptr}
  7. {
  8. m_actions = {
  9. { ActionGet, "get" },
  10. { ActionAdd, "add" },
  11. { ActionDelete, "del" },
  12. { ActionModify, "mod" }
  13. };
  14. m_dumpService.setEntityName("command");
  15. restoreStash();
  16. connect(&m_socket, &QWebSocket::textMessageReceived, this, [this](QString message) {
  17. QJsonParseError err;
  18. QJsonDocument doc = QJsonDocument::fromJson(message.toLocal8Bit(), &err);
  19. if (err.error != QJsonParseError::NoError) {
  20. qWarning() << "Json parse error:" << err.errorString() << message;
  21. return;
  22. }
  23. QString entity = doc.object().value("entity").toString();
  24. const QList<QObject *> listeners = m_listeners.values(entity);
  25. for (QObject *listener : listeners) {
  26. QString event = doc.object().value("event").toString();
  27. QVariant data = doc.object().value("data").toVariant();
  28. QMetaObject::invokeMethod(listener, event.toLatin1(), Qt::QueuedConnection, Q_ARG(QVariant, data));
  29. }
  30. });
  31. connect(&m_socket, &QWebSocket::errorOccurred, this, [this](QAbstractSocket::SocketError error) {
  32. qInfo() << error << m_socket.errorString();
  33. });
  34. connect(&m_socket, &QWebSocket::connected, this, [this]() {
  35. while (!m_commandStash.isEmpty()) {
  36. sendCommand(m_commandStash.takeFirst().toMap());
  37. }
  38. });
  39. connect(&m_socket, &QWebSocket::stateChanged, this, &BeerService::connectedChanged);
  40. connect(settings(), &SettingsService::serverAddressChanged, this, &BeerService::reconnect);
  41. connect(settings(), &SettingsService::selectedUserIdChanged, this, &BeerService::reconnect);
  42. reconnect();
  43. }
  44. BeerService::~BeerService()
  45. {
  46. m_dumpService.dump(m_commandStash);
  47. m_socket.close();
  48. }
  49. SettingsService *BeerService::settings() const
  50. {
  51. return SettingsService::instance();
  52. }
  53. void BeerService::sendCommand(const QString &entity, Action action, const QVariantMap &data)
  54. {
  55. Q_ASSERT(action != ActionUndefined);
  56. sendCommand(QVariantMap {
  57. { "entity", entity },
  58. { "action", m_actions[action] },
  59. { "data", data }
  60. });
  61. }
  62. void BeerService::connectListener(QObject *listener)
  63. {
  64. QString entity = listener->property("entity").toString();
  65. m_listeners.insert(entity, listener);
  66. }
  67. void BeerService::removeListener(QObject *listener)
  68. {
  69. QString entity = listener->property("entity").toString();
  70. m_listeners.remove(entity, listener);
  71. }
  72. void BeerService::restoreStash()
  73. {
  74. m_commandStash = m_dumpService.loadList();
  75. m_dumpService.clear();
  76. }
  77. void BeerService::reconnect()
  78. {
  79. if (connected()) {
  80. m_socket.close();
  81. }
  82. QString userId = settings()->selectedUserId();
  83. QUrl serverUrl(QString("ws://%1").arg(settings()->serverAddress()));
  84. QNetworkRequest request(serverUrl);
  85. request.setRawHeader("Authorization", "Basic " + QString("%1:pass").arg(userId).toLatin1().toBase64());
  86. m_socket.open(request);
  87. }
  88. void BeerService::sendCommand(const QVariantMap &command)
  89. {
  90. if (connected()) {
  91. QJsonDocument doc = QJsonDocument::fromVariant(command);
  92. m_socket.sendTextMessage(doc.toJson(QJsonDocument::Compact));
  93. } else {
  94. m_commandStash << command;
  95. }
  96. }
  97. bool BeerService::connected() const
  98. {
  99. return QAbstractSocket::ConnectedState == m_socket.state();
  100. }