ImClient.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #pragma once
  2. #include "Protocol.h"
  3. #include <QByteArray>
  4. #include <QHash>
  5. #include <QJsonObject>
  6. #include <QObject>
  7. #include <QVector>
  8. #include <functional>
  9. class QTcpSocket;
  10. class QTimer;
  11. class ImClient : public QObject
  12. {
  13. Q_OBJECT
  14. public:
  15. using Reply = std::function<void(const QJsonObject &)>;
  16. static ImClient &instance();
  17. bool isConnected() const;
  18. qint64 uid() const { return m_uid; }
  19. QString account() const { return m_account; }
  20. QString nickname() const { return m_nickname; }
  21. QString phone() const { return m_phone; }
  22. QString signature() const { return m_signature; }
  23. int avatarVer() const { return m_avatarVer; }
  24. QString sessionPassword() const { return m_sessionPassword; }
  25. bool isIntentionalClose() const { return m_intentionalClose; }
  26. void connectToServer();
  27. void disconnectFromServer();
  28. void clearProfile();
  29. void login(const QString &account, const QString &password, Reply cb);
  30. void logout(Reply cb);
  31. void registerUser(const QString &nickname, const QString &account, const QString &phone,
  32. const QString &smsCode, const QString &password, Reply cb);
  33. void sendCode(const QString &phone, const QString &scene, Reply cb);
  34. void resetPassword(qint64 uid, const QString &phone, const QString &smsCode,
  35. const QString &password, Reply cb);
  36. void changePassword(const QString &oldPassword, const QString &password, Reply cb);
  37. void friendList(Reply cb);
  38. void searchUser(const QString &keyword, Reply cb);
  39. void addFriend(qint64 uid, Reply cb);
  40. void addFriend(qint64 uid, const QString &message, Reply cb);
  41. void addFriendAccount(const QString &account, Reply cb);
  42. void friendRequestList(Reply cb);
  43. void handleFriendRequest(qint64 id, int action, Reply cb);
  44. void getPrivacy(Reply cb);
  45. void setPrivacy(int allowSearchAccount, int allowSearchPhone, int allowAddFriend, Reply cb);
  46. void stickerPackList(Reply cb);
  47. void stickerPack(qint64 packId, Reply cb);
  48. void getSticker(qint64 packId, const QString &code, Reply cb);
  49. void convList(Reply cb);
  50. void msgHistory(qint64 peerUid, qint64 lastId, int limit, Reply cb);
  51. void deleteConv(qint64 peerUid, Reply cb);
  52. void deleteMsgs(qint64 peerUid, const QVector<qint64> &ids, Reply cb);
  53. void setUnread(qint64 peerUid, int unread, Reply cb);
  54. void deleteFriend(qint64 uid, Reply cb);
  55. void setRemark(qint64 uid, const QString &remark, Reply cb);
  56. void getProfile(qint64 uid, Reply cb);
  57. void setProfile(const QString &nickname, const QString &signature, const QByteArray &avatarJpeg,
  58. Reply cb);
  59. void getAvatar(qint64 uid, Reply cb);
  60. void putFile(const QString &name, const QString &mime, qint64 size, Reply cb);
  61. void putFile(const QString &name, const QString &mime, qint64 size, const QString &purpose,
  62. Reply cb);
  63. void getFile(qint64 fileId, Reply cb);
  64. void favoriteAdd(const QJsonObject &body, Reply cb, int timeoutMs = 15000);
  65. void favoriteList(Reply cb);
  66. void favoriteGet(qint64 id, Reply cb);
  67. void favoriteUpdate(qint64 id, const QString &content, Reply cb);
  68. void favoriteDelete(qint64 id, Reply cb);
  69. void chat(qint64 toUid, const QString &content, Reply cb);
  70. void chat(qint64 toUid, int msgType, const QString &content, Reply cb);
  71. void applyLocalProfile(const QString &nickname, const QString &signature, int avatarVer);
  72. static bool ok(const QJsonObject &reply);
  73. static QString messageOf(const QJsonObject &reply);
  74. signals:
  75. void connected();
  76. void disconnected();
  77. void connectFailed(const QString &reason);
  78. void kicked();
  79. void limitsUpdated();
  80. void chatNotify(const QJsonObject &msg);
  81. void friendRequestNotify(const QJsonObject &msg);
  82. void friendAcceptedNotify(const QJsonObject &msg);
  83. private:
  84. explicit ImClient(QObject *parent = nullptr);
  85. ~ImClient() override;
  86. struct Pending
  87. {
  88. Reply cb;
  89. };
  90. void request(Proto::Type type, Proto::Cmd cmd, const QJsonObject &body, Reply cb,
  91. int timeoutMs = 15000);
  92. void flushQueue();
  93. void failAll(const QString &reason);
  94. void sendRaw(Proto::Type type, Proto::Cmd cmd, quint32 seq, const QByteArray &body);
  95. void onReadyRead();
  96. void onConnected();
  97. void onDisconnected();
  98. void onSocketError();
  99. void onHeartbeat();
  100. void handlePacket(const Proto::Packet &pkt);
  101. void applyLoginProfile(const QJsonObject &reply);
  102. void applyLimitsFromReply(const QJsonObject &reply);
  103. QJsonObject netError(const QString &msg) const;
  104. QTcpSocket *m_socket = nullptr;
  105. QTimer *m_heartbeat = nullptr;
  106. Proto::PacketCodec *m_codec = nullptr;
  107. quint32 m_seq = 0;
  108. bool m_intentionalClose = false;
  109. bool m_configReady = false;
  110. qint64 m_uid = 0;
  111. QString m_account;
  112. QString m_nickname;
  113. QString m_phone;
  114. QString m_signature;
  115. int m_avatarVer = 0;
  116. QString m_sessionPassword;
  117. QHash<quint32, Pending> m_pending;
  118. struct Queued
  119. {
  120. quint16 type = 0;
  121. quint16 cmd = 0;
  122. QJsonObject body;
  123. Reply cb;
  124. int timeoutMs = 15000;
  125. };
  126. QVector<Queued> m_queue;
  127. };