The package tcp provides interfaces to create a TCP server.
To install it, you need to install Go and set your Go workspace first. Then, download and install it:
$ go get -u github.com/rvflash/tcpImport it in your code:
import "github.com/rvflash/tcp"tcp uses the Go modules that required Go 1.11 or later.
By using the RunTLS method instead of Run, you can specify a certificate and
a X509 key to create an TCP/TLS connection.
Just as Gin, a well done web framework whose provides functions based on HTTP methods,
tcp provides functions based on TCP segments.
Thus, it exposes a method for each of its segments:
- ACKto handle each new message.
- FINto handle when the connection is closed.
- SYNto handle each new connection.
More functions are available, see the godoc for more details.
Each of these methods take as parameter the HandlerFunc interface: func(c *Context).
You must implement this interface to create your own handler.
By analogy with the awesome standard HTTP package,
tcpexposes and implements the Handler interfaceServeTCP(ResponseWriter, *Request).
By using the Default method instead of the New to initiate a TCP server,
2 middlewares are defined on each segment.
The first allows to recover on panic, and the second enables logs.
The Next method on the Context should only be used inside middleware. Its allows to pass to the pending handlers.
See the Recovery or Logger methods as sample code.
By running the TCP server is in own go routine, you can gracefully shuts down the server without interrupting any active connections.
Shutdown works by first closing all open listeners and then waiting indefinitely for connections to return to idle and then shut down.
Assuming the following code that runs a server on port 9090:
package main
import (
    "context"
    "log"
    "os"
    "os/signal"
	"github.com/rvflash/tcp"
)
func main() {
	bye := make(chan os.Signal, 1)
	signal.Notify(bye, os.Interrupt, syscall.SIGTERM)
	// Creates a server with a logger and a recover on panic as middlewares.
	r := tcp.Default()
	r.ACK(func(c *tcp.Context) {
		// New message received
		// Gets the request body
		buf, err := c.ReadAll()
		if err != nil {
			c.Error(err)
			return
		}
		// Writes something as response
		c.String(string(buf))
	})
	go func() {
		err := r.Run(":9090")
		if err != nil {
			log.Printf("server: %q\n", err)
		}
	}()
	<-bye
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	err := r.Shutdown(ctx)
	cancel()
	if err != nil {
		log.Fatal(err)
	}
}