Documentation ¶
Overview ¶
The GAS library provides auto-reconnecting TCP sockets in a tiny, fully tested, thread-safe API.
The `TCPClient` struct embeds a `net.TCPConn` and overrides its `Read()` and `Write()` methods, making it entirely compatible with the `net.Conn` interface and the rest of the `net` package. This means you should be able to use this library by just replacing `net.Dial` with `gas.Dial` in your code.
To test the library, you can run a local TCP server with:
$ ncat -l 9999 -k
and run this code:
package main import ( "log" "time" "github.com/teh-cmc/goautosocket" ) func main() { // connect to a TCP server conn, err := gas.Dial("tcp", "localhost:9999") if err != nil { log.Fatal(err) } // client sends "hello, world!" to the server every second for { _, err := conn.Write([]byte("hello, world!\n")) if err != nil { // if the client reached its retry limit, give up if err == gas.ErrMaxRetries { log.Println("client gave up, reached retry limit") return } // not a GAS error, just panic log.Fatal(err) } log.Println("client says hello!") time.Sleep(time.Second) } }
Then try to kill and reboot your server, the client will automatically reconnect and start sending messages again; unless it has reached its retry limit.
Index ¶
- func Dial(network, addr string) (net.Conn, error)
- type Error
- type TCPClient
- func (c *TCPClient) GetMaxRetries() int
- func (c *TCPClient) GetRetryInterval() time.Duration
- func (c *TCPClient) Read(b []byte) (int, error)
- func (c *TCPClient) ReadFrom(r io.Reader) (int64, error)
- func (c *TCPClient) SetMaxRetries(maxRetries int)
- func (c *TCPClient) SetRetryInterval(retryInterval time.Duration)
- func (c *TCPClient) Write(b []byte) (int, error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Error ¶
type Error int
Error is the error type of the GAS package.
It implements the error interface.
const ( // ErrMaxRetries is returned when the called function failed after the // maximum number of allowed tries. ErrMaxRetries Error = 0x01 )
type TCPClient ¶
TCPClient provides a TCP connection with auto-reconnect capabilities.
It embeds a *net.TCPConn and thus implements the net.Conn interface.
Use the SetMaxRetries() and SetRetryInterval() methods to configure retry values; otherwise they default to maxRetries=5 and retryInterval=100ms.
TCPClient can be safely used from multiple goroutines.
Example ¶
// open a server socket s, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } // save the original port addr := s.Addr() // connect a client to the server c, err := Dial("tcp", s.Addr().String()) if err != nil { log.Fatal(err) } defer c.Close() // shut down and boot up the server randomly var swg sync.WaitGroup swg.Add(1) go func() { defer swg.Done() for i := 0; i < 5; i++ { log.Println("server up") time.Sleep(time.Millisecond * 100 * time.Duration(rand.Intn(20))) if err := s.Close(); err != nil { log.Fatal(err) } log.Println("server down") time.Sleep(time.Millisecond * 100 * time.Duration(rand.Intn(20))) s, err = net.Listen("tcp", addr.String()) if err != nil { log.Fatal(err) } } }() // client writes to the server and reconnects when it has to // this is the interesting part var cwg sync.WaitGroup cwg.Add(1) go func() { defer cwg.Done() for { if _, err := c.Write([]byte("hello, world!\n")); err != nil { switch e := err.(type) { case Error: if e == ErrMaxRetries { log.Println("client leaving, reached retry limit") return } default: log.Fatal(err) } } } }() // terminates the server indefinitely swg.Wait() if err := s.Close(); err != nil { log.Fatal(err) } // wait for the client to give up cwg.Wait()
Output:
func DialTCP ¶
DialTCP returns a new *TCPClient.
The new client connects to the remote address `raddr` on the network `network`, which must be "tcp", "tcp4", or "tcp6". If `laddr` is not nil, it is used as the local address for the connection.
This overrides net.TCPConn's DialTCP function.
func (*TCPClient) GetMaxRetries ¶
GetMaxRetries gets the retry limit for the TCPClient.
Assuming i is the current retry iteration, the total sleep time is t = retryInterval * (2^i)
func (*TCPClient) GetRetryInterval ¶
GetRetryInterval gets the retry interval for the TCPClient.
Assuming i is the current retry iteration, the total sleep time is t = retryInterval * (2^i)
func (*TCPClient) Read ¶
Read wraps net.TCPConn's Read method with reconnect capabilities.
It will return ErrMaxRetries if the retry limit is reached.
func (*TCPClient) ReadFrom ¶
ReadFrom wraps net.TCPConn's ReadFrom method with reconnect capabilities.
It will return ErrMaxRetries if the retry limit is reached.
func (*TCPClient) SetMaxRetries ¶
SetMaxRetries sets the retry limit for the TCPClient.
Assuming i is the current retry iteration, the total sleep time is t = retryInterval * (2^i)
This function completely Lock()s the TCPClient.
func (*TCPClient) SetRetryInterval ¶
SetRetryInterval sets the retry interval for the TCPClient.
Assuming i is the current retry iteration, the total sleep time is t = retryInterval * (2^i)
This function completely Lock()s the TCPClient.