Browse Source

add WebSocketClient::setPingInterval

hewei.it 4 years ago
parent
commit
ae0dbc27ad
3 changed files with 53 additions and 0 deletions
  1. 25 0
      evpp/Channel.h
  2. 20 0
      http/client/WebSocketClient.cpp
  3. 8 0
      http/client/WebSocketClient.h

+ 25 - 0
evpp/Channel.h

@@ -156,6 +156,7 @@ class SocketChannel : public Channel {
 public:
     // for TcpClient
     std::function<void()>   onconnect;
+    std::function<void()>   heartbeat;
 
     SocketChannel(hio_t* io) : Channel(io) {
     }
@@ -166,9 +167,26 @@ public:
     }
 
     void setConnectTimeout(int timeout_ms) {
+        if (io_ == NULL) return;
         hio_set_connect_timeout(io_, timeout_ms);
     }
 
+    void setCloseTimeout(int timeout_ms) {
+        if (io_ == NULL) return;
+        hio_set_close_timeout(io_, timeout_ms);
+    }
+
+    void setKeepaliveTimeout(int timeout_ms) {
+        if (io_ == NULL) return;
+        hio_set_keepalive_timeout(io_, timeout_ms);
+    }
+
+    void setHeartbeat(int interval_ms, std::function<void()> fn) {
+        if (io_ == NULL) return;
+        heartbeat = fn;
+        hio_set_heartbeat(io_, interval_ms, send_heartbeat);
+    }
+
     int startConnect(int port, const char* host = "127.0.0.1") {
         sockaddr_u peeraddr;
         memset(&peeraddr, 0, sizeof(peeraddr));
@@ -225,6 +243,13 @@ private:
             }
         }
     }
+
+    static void send_heartbeat(hio_t* io) {
+        SocketChannel* channel = (SocketChannel*)hio_context(io);
+        if (channel && channel->heartbeat) {
+            channel->heartbeat();
+        }
+    }
 };
 
 typedef std::shared_ptr<Channel>        ChannelPtr;

+ 20 - 0
http/client/WebSocketClient.cpp

@@ -3,12 +3,16 @@
 #include "base64.h"
 #include "hlog.h"
 
+#define DEFAULT_WS_PING_INTERVAL    3000 // ms
+
 namespace hv {
 
 WebSocketClient::WebSocketClient()
     : TcpClientTmpl<WebSocketChannel>()
 {
     state = WS_CLOSED;
+    ping_interval = DEFAULT_WS_PING_INTERVAL;
+    ping_cnt = 0;
 }
 
 WebSocketClient::~WebSocketClient() {
@@ -119,6 +123,7 @@ int WebSocketClient::open(const char* _url) {
                     }
                     case WS_OPCODE_PONG:
                         // printf("recv pong\n");
+                        ping_cnt = 0;
                         break;
                     case WS_OPCODE_TEXT:
                     case WS_OPCODE_BINARY:
@@ -129,6 +134,21 @@ int WebSocketClient::open(const char* _url) {
                     }
                 };
                 state = WS_OPENED;
+                // ping
+                if (ping_interval > 0) {
+                    ping_cnt = 0;
+                    channel->setHeartbeat(ping_interval, [this](){
+                        auto& channel = this->channel;
+                        if (channel == NULL) return;
+                        if (ping_cnt++ == 3) {
+                            hloge("websocket no pong!");
+                            channel->close();
+                            return;
+                        }
+                        // printf("send ping\n");
+                        channel->write(WS_CLIENT_PING_FRAME, WS_CLIENT_MIN_FRAME_SIZE);
+                    });
+                }
                 if (onopen) onopen();
             }
         } else {

+ 8 - 0
http/client/WebSocketClient.h

@@ -32,6 +32,11 @@ public:
     int send(const std::string& msg);
     int send(const char* buf, int len, enum ws_opcode opcode = WS_OPCODE_BINARY);
 
+    // setConnectTimeout / setPingInterval / setReconnect
+    void setPingInterval(int ms) {
+        ping_interval = ms;
+    }
+
 private:
     enum State {
         CONNECTING,
@@ -44,6 +49,9 @@ private:
     HttpRequestPtr      http_req_;
     HttpResponsePtr     http_resp_;
     WebSocketParserPtr  ws_parser_;
+    // ping/pong
+    int                 ping_interval;
+    int                 ping_cnt;
 };
 
 }