Skip to content

Commit 6dd8ee5

Browse files
committed
feat(heartbeat): added heartbeat mechanism
1 parent 487d08a commit 6dd8ee5

4 files changed

Lines changed: 26 additions & 3 deletions

File tree

client/network_manager.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ bool NetworkManager::Connect(const std::string& host, int port) {
2525
connected_ = true;
2626
running_ = true;
2727
listener_thread_ = std::thread(&NetworkManager::ListenerLoop, this);
28+
heartbeat_thread_ = std::thread(&NetworkManager::HeartbeatLoop, this);
2829
return true;
2930
}
3031

@@ -39,6 +40,9 @@ void NetworkManager::Disconnect() {
3940
if (listener_thread_.joinable()) {
4041
listener_thread_.join();
4142
}
43+
if (heartbeat_thread_.joinable()) {
44+
heartbeat_thread_.join();
45+
}
4246
connected_ = false;
4347
}
4448

@@ -102,12 +106,10 @@ void NetworkManager::ListenerLoop() {
102106
if (msg_len > 10 * 1024 * 1024) { // 10MB limit
103107
if (running_) {
104108
if (on_error_callback_) on_error_callback_("Protocol Error: Packet too large");
105-
// Do not set running_ = false here immediately to allow error to be reported?
106-
// Actually safer to stop.
107109
running_ = false;
108110
connected_ = false;
109111
}
110-
return; // Exit thread
112+
return;
111113
}
112114

113115
std::string buffer;
@@ -154,6 +156,19 @@ void NetworkManager::ListenerLoop() {
154156
}
155157
}
156158

159+
void NetworkManager::HeartbeatLoop() {
160+
while (running_) {
161+
std::this_thread::sleep_for(std::chrono::seconds(15));
162+
if (!running_) break;
163+
if (connected_) {
164+
im::Envelope env;
165+
env.set_cmd(im::CMD_HEARTBEAT);
166+
env.set_timestamp(time(NULL));
167+
SendEnvelope(env);
168+
}
169+
}
170+
}
171+
157172
bool NetworkManager::Register(const std::string& username, const std::string& password, std::string& error_msg) {
158173
im::RegisterReq req;
159174
req.set_username(username);

client/network_manager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class NetworkManager {
5353
bool SendEnvelope(const im::Envelope& env);
5454
bool SendRequestAndWait(const im::Envelope& request, im::Envelope& response, im::CommandType expected_cmd);
5555
void ListenerLoop();
56+
void HeartbeatLoop();
5657
void ClearAuth();
5758
void Disconnect();
5859

@@ -71,6 +72,7 @@ class NetworkManager {
7172

7273
// Async Handling
7374
std::thread listener_thread_;
75+
std::thread heartbeat_thread_;
7476
std::atomic<bool> running_{false};
7577

7678
std::mutex mutex_;

proto/protocol.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ enum CommandType {
3434
CMD_P2P_MSG_REQ = 50;
3535
CMD_P2P_MSG_PUSH = 51;
3636
CMD_MSG_ACK = 52;
37+
38+
// Heartbeat
39+
CMD_HEARTBEAT = 99;
3740
}
3841

3942
message Envelope {

server/src/handler/protobuf_handler.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ void ProtobufHandler::Dispatch(const im::Envelope& request, im::Envelope& respon
8888
case im::CMD_P2P_MSG_REQ:
8989
HandleP2PMsg(request, response);
9090
break;
91+
case im::CMD_HEARTBEAT:
92+
// Heartbeat received, connection timer is already refreshed by OnRead_
93+
return;
9194
default:
9295
HandleUnknown(request, response);
9396
break;

0 commit comments

Comments
 (0)