network

package
v0.0.0-...-df1ffc2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2020 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package network implements a communication layer with a server and a client. Clients can connect to servers and receive and send messages. Depending on the implementation, communication may differ.

srv := network.NewTCPServer(zerolog.Nop()) // or any other available server
srv.OnConnect(handleConnection)
if err := srv.Open(":3900"); err != nil {
    panic(err)
}

In the above example, handleConnection is a func that accepts a network.Conn as parameter. Do with this connection what you'd like. The connections have an ID.

func handleConnection(conn network.Conn) {
    loginMsg, err := conn.Receive() // receive a message
    // handle loginMsg and err
    // create loginResponse
    err = conn.Send(loginResponse) // send a message
    // handle err
    connectionPool.Add(conn) // remember the connection for further use
}

To connect to the above server, do as follows.

conn, err := network.DialTCP(":3900") // or any other available dial method
// handle err
defer conn.Close()
err = conn.Send(loginMsg) // send a message
// handle err
loginResponse, err := conn.Receive() // receive a message

Please note, that the dial functions will only work with the respective server, e.g. DialTCP will only work on TCPServers.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Conn

type Conn interface {
	io.Closer

	// ID returns the ID of this connection. It can be used to uniquely identify
	// this connection globally.
	ID() ID
	// Send sends the given payload to the remote part of this connection. The
	// message will not be chunked, and can be read with a single call to
	// Conn.Receive.
	Send(context.Context, []byte) error
	// Receive reads a whole message and returns it in a byte slice. A message
	// is a byte slice that was sent with a single call to Conn.Send.
	Receive(context.Context) ([]byte, error)
}

Conn describes a network connection. One can send a message with Conn.Send, and receive one with Conn.Receive. Unlike an io.Writer, the data that is passed into Send is guaranteed to be returned in a single Receive call on the other end, meaning that you don't have to worry about where your messages end. Maximum message length is 2GiB.

func DialTCP

func DialTCP(ctx context.Context, addr string) (Conn, error)

DialTCP dials to the given address, assuming a TCP network. The returned Conn is ready to use.

type ConnHandler

type ConnHandler func(Conn)

ConnHandler is a handler function for handling new connections. It will be called with a fully initialized Conn, and is used as a callback in the server.

type Error

type Error string

Error is a helper type for creating constant errors.

const (
	// ErrOpen indicates, that the component was already opened, and it is
	// unable to be opened another time.
	ErrOpen Error = "already open"
	// ErrClosed indicates, that the component is already closed, and it cannot
	// be used anymore.
	ErrClosed Error = "already closed"
	// ErrTimeout indicates, that a the operation took longer than allowed.
	// Maybe there was a deadline from a context.
	ErrTimeout Error = "timeout"
)

func (Error) Error

func (e Error) Error() string

type ID

type ID interface {
	fmt.Stringer
	Bytes() []byte
}

ID describes an identifier that is used for connections. An ID has to be unique application-wide. IDs must not be re-used.

type Server

type Server interface {
	io.Closer

	// Open opens the server on the given address. To make the server choose a
	// random free port for you, specify a port ":0".
	Open(string) error
	// Listening can be used to get a signal when the server has allocated a
	// port and is now actively listening for incoming connections.
	Listening() <-chan struct{}
	// Addr returns the address that this server is listening to.
	Addr() net.Addr

	// OnConnect sets a callback that will be executed whenever a new connection
	// connects to this server.
	OnConnect(ConnHandler)
}

Server describes a server component, that listens for connecting clients. Before opening, it is recommended that one sets a connect handler with Server.OnConnect. A server can only be opened once. Closing a server must not close the accepted connections, but must only stop accepting new connections and release the allocated address.

Example
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/rs/zerolog"
	"github.com/tomarrell/lbadd/internal/network"
)

func main() {
	// When using, please don't ignore all the errors as we do here.

	ctx := context.Background()

	srv := network.NewTCPServer(zerolog.Nop()) // or whatever server is available
	srv.OnConnect(func(conn network.Conn) {
		_ = conn.Send(ctx, []byte("Hello, World!"))
	})
	go func() {
		if err := srv.Open(":59513"); err != nil {
			log.Fatal(err)
		}
	}()

	<-srv.Listening() // wait for the server to come up

	client, _ := network.DialTCP(ctx, ":59513")
	defer func() {
		_ = client.Close()
	}()
	received, _ := client.Receive(ctx)
	fmt.Println(string(received))
}
Output:

Hello, World!

func NewTCPServer

func NewTCPServer(log zerolog.Logger) Server

NewTCPServer creates a new ready to use TCP server that uses the given logger.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL