binproto

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Feb 10, 2026 License: MIT Imports: 6 Imported by: 0

README

binproto

Simple binary messaging protocol with multiplexing support.

Go Reference

Message structure

┌──────────────────────────────────────────────┐
│ length | channel ID × message type │ payload │
└──────────────────────────────────────────────┘
           └─ 60-bits   └─ 4-bits

Benchmarks

goos: darwin
goarch: arm64
pkg: github.com/tetsuo/binproto
cpu: Apple M4 Pro
BenchmarkWriter_64B-12          98590449                12.05 ns/op     5309.66 MB/s           0 B/op          0 allocs/op
BenchmarkWriter_4KB-12          14346594                80.00 ns/op     51198.63 MB/s          0 B/op          0 allocs/op
BenchmarkWriter_1MB-12             74955             15931 ns/op        65819.47 MB/s         14 B/op          0 allocs/op
BenchmarkReader_64B-12          70582526                16.24 ns/op     3941.01 MB/s           0 B/op          0 allocs/op
BenchmarkReader_4KB-12          15629764                78.92 ns/op     51903.93 MB/s          0 B/op          0 allocs/op
BenchmarkReader_1MB-12             38365             31480 ns/op        33309.32 MB/s          0 B/op          0 allocs/op

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/tetsuo/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() {
			msg := &binproto.Message{}
			for {
				err := c.ReadMessage(msg)
				if err != nil {
					log.Fatal(err)
					return
				}

				fmt.Printf("%d %d %s\n", msg.ID, msg.Type, 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)

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

		fmt.Printf("%d %d %s\n", msg.ID, msg.Type, 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   uint64
	Type uint8
	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 a channel ID (first 60-bits) and a message type (last 4-bits), the rest of the message is payload.

func NewMessage

func NewMessage(id uint64, messageType uint8, 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.

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