]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Ping websocket to ensure connect remains online.
authorJustin M <37273682+DigitalAlchemist@users.noreply.github.com>
Tue, 5 Jan 2021 05:40:44 +0000 (05:40 +0000)
committerMatt Joiner <anacrolix@gmail.com>
Wed, 6 Jan 2021 03:30:01 +0000 (14:30 +1100)
OpenWebTorrent disconnects clients after two minutes of inactivity. In a scenario where an
announce occurs and no other activity occurs for the (default) 120-second idle timer, the
websocket will be torn down by OpenWebTorrent. This in turn causes the tracker client to wait one
minute, reconnect, and reannounce its peers.

This patch sends a websocket.PingMessage every 60 seconds to maintain the connection.

webtorrent/tracker_client.go

index 47267e0ebe3b3bf3ccc6d53eaeaa049ea6784ab8..c5aacaf25f36b7234d95fba430757bf48a29cbfb 100644 (file)
@@ -35,6 +35,7 @@ type TrackerClient struct {
        wsConn         *websocket.Conn
        closed         bool
        stats          TrackerClientStats
+       pingTicker     *time.Ticker
 }
 
 func (me *TrackerClient) Stats() TrackerClientStats {
@@ -78,7 +79,23 @@ func (tc *TrackerClient) doWebsocket() error {
        tc.cond.Broadcast()
        tc.mu.Unlock()
        tc.announceOffers()
+       closeChan := make(chan struct{})
+       go func() {
+               for {
+                       select {
+                       case <-tc.pingTicker.C:
+                               err := c.WriteMessage(websocket.PingMessage, []byte{})
+                               if err != nil {
+                                       return
+                               }
+                       case <-closeChan:
+                               return
+                       default:
+                       }
+               }
+       }()
        err = tc.trackerReadLoop(tc.wsConn)
+       close(closeChan)
        tc.mu.Lock()
        c.Close()
        tc.mu.Unlock()
@@ -86,6 +103,7 @@ func (tc *TrackerClient) doWebsocket() error {
 }
 
 func (tc *TrackerClient) Run() error {
+       tc.pingTicker = time.NewTicker(60 * time.Second)
        tc.cond.L = &tc.mu
        tc.mu.Lock()
        for !tc.closed {
@@ -112,6 +130,7 @@ func (tc *TrackerClient) Close() error {
                tc.wsConn.Close()
        }
        tc.closeUnusedOffers()
+       tc.pingTicker.Stop()
        tc.mu.Unlock()
        tc.cond.Broadcast()
        return nil