package mtproto
import (
"context"
"github.com/go-faster/errors"
"github.com/gotd/td/bin"
"github.com/gotd/td/internal/crypto"
"github.com/gotd/td/internal/mt"
)
func (c *Conn ) Ping (ctx context .Context ) error {
pingID , err := crypto .RandInt64 (c .rand )
if err != nil {
return err
}
pong := c .pong (pingID )
defer c .removePong (pingID )
if err := c .writeServiceMessage (ctx , &mt .PingRequest {PingID : pingID }); err != nil {
return errors .Wrap (err , "write" )
}
select {
case <- pong :
return nil
case <- ctx .Done ():
return ctx .Err ()
}
}
func (c *Conn ) handlePong (b *bin .Buffer ) error {
var pong mt .Pong
if err := pong .Decode (b ); err != nil {
return errors .Errorf ("decode: %x" , err )
}
c .log .Debug ("Pong" )
c .pingMux .Lock ()
ch , ok := c .ping [pong .PingID ]
if ok {
close (ch )
delete (c .ping , pong .PingID )
}
c .pingMux .Unlock ()
return nil
}
func (c *Conn ) pingDelayDisconnect (ctx context .Context , delay int ) error {
pingID , err := crypto .RandInt64 (c .rand )
if err != nil {
return err
}
pong := c .pong (pingID )
defer c .removePong (pingID )
if err := c .writeServiceMessage (ctx , &mt .PingDelayDisconnectRequest {
PingID : pingID ,
DisconnectDelay : delay ,
}); err != nil {
return errors .Wrap (err , "write" )
}
select {
case <- pong :
return nil
case <- ctx .Done ():
return ctx .Err ()
}
}
func (c *Conn ) pong (pingID int64 ) chan struct {} {
ch := make (chan struct {})
c .pingMux .Lock ()
c .ping [pingID ] = ch
c .pingMux .Unlock ()
return ch
}
func (c *Conn ) removePong (pingID int64 ) {
c .pingMux .Lock ()
delete (c .ping , pingID )
c .pingMux .Unlock ()
}
func (c *Conn ) pingLoop (ctx context .Context ) error {
delay := c .pingInterval + c .pingTimeout
ticker := c .clock .Ticker (c .pingInterval )
defer ticker .Stop ()
for {
select {
case <- ctx .Done ():
return errors .Wrap (ctx .Err (), "ping loop" )
case <- ticker .C ():
if err := func () error {
ctx , cancel := context .WithTimeout (ctx , c .pingTimeout )
defer cancel ()
return c .pingDelayDisconnect (ctx , int (delay .Seconds ()))
}(); err != nil {
return errors .Wrap (err , "disconnect (pong missed)" )
}
}
}
}
The pages are generated with Golds v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .