binproto

package module
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: May 24, 2023 License: MIT Imports: 7 Imported by: 0

README

binproto

binproto implements low-level support for binary-based two-way communication protocols. You can use it to create your own low-latency binary protocols for things like game networking or file transfer.

Documentation

Overview

Package binproto implements low-level support for binary-based two-way communication protocols.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrMessageSizeExceeded = errors.New("binproto: message too big")
	ErrMessageMalformed    = errors.New("binproto: message malformed")
)

Functions

This section is empty.

Types

type Conn

type Conn struct {
	Reader
	Writer
	textproto.Pipeline
	// contains filtered or unexported fields
}

A Conn represents a binary network protocol connection. It consists of a Reader and Writer to manage I/O and a Pipeline (which is borrowed from textproto) to sequence concurrent requests on the connection.

func Dial

func Dial(network, addr string) (*Conn, error)

Dial connects to the given address on the given network using net.Dial and then returns a new Conn for the connection.

Example
package main

import (
	"fmt"
	"log"
	"net"
	"time"

	"github.com/onur1/binproto"
)

func main() {
	s := &server{}

	time.AfterFunc(time.Millisecond*1, func() {
		c, err := binproto.Dial("tcp", ":4242")
		if err != nil {
			log.Fatal(err)
		}

		go func() {
			for {
				msg, err := c.ReadMessage()
				if err != nil {
					log.Fatal(err)
					return
				}

				fmt.Printf("%d %d %s\n", msg.ID, msg.Channel, msg.Data)

				s.close()
			}
		}()

		_, err = c.Send(binproto.NewMessage(42, 3, []byte("hi")))
		if err != nil {
			log.Fatal(err)
		}
	})

	if err := s.serve("tcp", ":4242"); err != nil {
		log.Fatal(err)
	}

}

type server struct {
	listener net.Listener
}

func (s *server) handle(conn net.Conn) {
	defer conn.Close()

	c := binproto.NewConn(conn)

	for {
		msg, err := c.ReadMessage()
		if err != nil {
			fmt.Printf("error: %v", err)
			return
		}

		fmt.Printf("%d %d %s\n", msg.ID, msg.Channel, msg.Data)

		_, err = c.Send(binproto.NewMessage(112, 5, []byte("hey")))
		if err != nil {
			log.Fatal(err)
		}
	}
}

func (s *server) serve(network, address string) error {
	l, err := net.Listen(network, address)
	if err != nil {
		return err
	}

	s.listener = l

	for {
		if s.listener == nil {
			break
		}

		c, err := l.Accept()
		if err != nil {
			continue
		}

		go s.handle(c)
	}

	return nil
}

func (s *server) close() error {
	err := s.listener.Close()
	s.listener = nil
	return err
}
Output:

42 3 hi
112 5 hey

func NewConn

func NewConn(conn io.ReadWriteCloser) *Conn

NewConn returns a new Conn using conn for I/O.

func (*Conn) Close

func (c *Conn) Close() error

Close closes the connection.

func (*Conn) Send

func (c *Conn) Send(m ...*Message) (id uint, err error)

Send is a convenience method that sends a variable number of messages after waiting its turn in the pipeline. Send returns the id of the command, for use with StartResponse and EndResponse.

type Message

type Message struct {
	ID      int
	Channel rune
	Data    []byte
}

A Message represents a single binproto message.

Each message starts with an header which is a varint encoded unsigned 64-bit integer which consists of an ID (first 60-bits) and a Channel number (last 4-bits), the rest of the message is payload.

func NewMessage

func NewMessage(id int, ch rune, data []byte) *Message

NewMessage returns a new Message.

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

A Reader implements convenience methods for reading requests or responses from a binary protocol network connection.

func NewReader

func NewReader(rd io.Reader) *Reader

NewReader returns a new Reader reading from r.

By default, a Reader allocates `4096` bytes for its internal buffer, and will process what's inside the buffer as long as its size is greater than this limit.

func NewReaderSize

func NewReaderSize(rd io.Reader, size int) *Reader

NewReaderSize returns a new Reader with the specified buffer size.

func (*Reader) ReadMessage

func (b *Reader) ReadMessage() (message *Message, err error)

ReadMessage reads a single message from r.

func (*Reader) Reset

func (b *Reader) Reset(r io.Reader)

Reset resets this Reader with the new source r, using the existing buffer.

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

A Writer implements convenience methods for writing requests or responses to a binary protocol network connection.

func NewWriter

func NewWriter(wd *bufio.Writer) *Writer

NewWriter returns a new Writer writing to w.

func (*Writer) WriteMessage

func (w *Writer) WriteMessage(messages ...*Message) error

WriteMessage writes a variable number of messages to w.

Jump to

Keyboard shortcuts

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