multistream

package
v0.0.0-...-8b9b725 Latest Latest
Warning

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

Go to latest
Published: Apr 7, 2019 License: MIT, MIT Imports: 7 Imported by: 34

README

go-multistream

GoDoc Travis CI codecov.io

an implementation of the multistream protocol in go

This package implements a simple stream router for the multistream-select protocol. The protocol is defined here.

Table of Contents

Install

go-multistream is a standard Go module which can be installed with:

go get github.com/multiformats/go-multistream

Note that go-multistream is packaged with Gx, so it is recommended to use Gx to install and use it (see Usage section).

Usage

Using Gx and Gx-go

This module is packaged with Gx. In order to use it in your own project do:

go get -u github.com/whyrusleeping/gx
go get -u github.com/whyrusleeping/gx-go
cd <your-project-repository>
gx init
gx import github.com/multiformats/go-multistream
gx install --global
gx-go --rewrite

Please check Gx and Gx-go documentation for more information.

Example

This example shows how to use a multistream muxer. A muxer uses user-added handlers to handle different "protocols". The first step when interacting with a connection handler by the muxer is to select the protocol (the example uses SelectProtoOrFail). This will then let the muxer use the right handler.

package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"net"

	ms "github.com/multiformats/go-multistream"
)

// This example creates a multistream muxer, adds handlers for the protocols
// "/cats" and "/docs" and exposes it on a localhost:8765. It then opens connections
// to that port, selects the protocols and tests that the handlers are working.
func main() {
	mux := ms.NewMultistreamMuxer()
	mux.AddHandler("/cats", func(proto string, rwc io.ReadWriteCloser) error {
		fmt.Fprintln(rwc, proto, ": HELLO I LIKE CATS")
		return rwc.Close()
	})
	mux.AddHandler("/dogs", func(proto string, rwc io.ReadWriteCloser) error {
		fmt.Fprintln(rwc, proto, ": HELLO I LIKE DOGS")
		return rwc.Close()
	})

	list, err := net.Listen("tcp", ":8765")
	if err != nil {
		panic(err)
	}

	go func() {
		for {
			con, err := list.Accept()
			if err != nil {
				panic(err)
			}

			go mux.Handle(con)
		}
	}()

	// The Muxer is ready, let's test it
	conn, err := net.Dial("tcp", ":8765")
	if err != nil {
		panic(err)
	}

	// Create a new multistream to talk to the muxer
	// which will negotiate that we want to talk with /cats
	mstream := ms.NewMSSelect(conn, "/cats")
	cats, err := ioutil.ReadAll(mstream)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%s", cats)
	mstream.Close()

	// A different way of talking to the muxer
	// is to manually selecting the protocol ourselves
	conn, err = net.Dial("tcp", ":8765")
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	err = ms.SelectProtoOrFail("/dogs", conn)
	if err != nil {
		panic(err)
	}
	dogs, err := ioutil.ReadAll(conn)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%s", dogs)
	conn.Close()
}

Maintainers

Captain: @whyrusleeping.

Contribute

Contributions welcome. Please check out the issues.

Check out our contributing document for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS Code of Conduct.

Small note: If editing the README, please conform to the standard-readme specification.

License

MIT © 2016 Jeromy Johnson

Documentation

Overview

Package multistream implements a simple stream router for the multistream-select protocoli. The protocol is defined at https://github.com/multiformats/multistream-select

Index

Constants

View Source
const ProtocolID = "/multistream/1.0.0"

ProtocolID identifies the multistream protocol itself and makes sure the multistream muxers on both sides of a channel can work with each other.

Variables

View Source
var ErrIncorrectVersion = errors.New("client connected with incorrect version")

ErrIncorrectVersion is an error reported when the muxer protocol negotiation fails because of a ProtocolID mismatch.

View Source
var ErrNotSupported = errors.New("protocol not supported")

ErrNotSupported is the error returned when the muxer does not support the protocol specified for the handshake.

View Source
var ErrTooLarge = errors.New("incoming message was too large")

ErrTooLarge is an error to signal that an incoming message was too large

Functions

func Ls

func Ls(rw io.ReadWriter) ([]string, error)

Ls is a Multistream muxer command which returns the list of handler names available on a muxer.

func ReadNextToken

func ReadNextToken(rw io.ReadWriter) (string, error)

ReadNextToken extracts a token from a ReadWriter. It is used during protocol negotiation and returns a string.

func ReadNextTokenBytes

func ReadNextTokenBytes(rw io.ReadWriter) ([]byte, error)

ReadNextTokenBytes extracts a token from a ReadWriter. It is used during protocol negotiation and returns a byte slice.

func SelectOneOf

func SelectOneOf(protos []string, rwc io.ReadWriteCloser) (string, error)

SelectOneOf will perform handshakes with the protocols on the given slice until it finds one which is supported by the muxer.

func SelectProtoOrFail

func SelectProtoOrFail(proto string, rwc io.ReadWriteCloser) error

SelectProtoOrFail performs the initial multistream handshake to inform the muxer of the protocol that will be used to communicate on this ReadWriteCloser. It returns an error if, for example, the muxer does not know how to handle this protocol.

Types

type Handler

type Handler struct {
	MatchFunc func(string) bool
	Handle    HandlerFunc
	AddName   string
}

Handler is a wrapper to HandlerFunc which attaches a name (protocol) and a match function which can optionally be used to select a handler by other means than the name.

type HandlerFunc

type HandlerFunc func(protocol string, rwc io.ReadWriteCloser) error

HandlerFunc is a user-provided function used by the MultistreamMuxer to handle a protocol/stream.

type Multistream

type Multistream interface {
	io.ReadWriteCloser
}

Multistream represents in essense a ReadWriteCloser, or a single communication wire which supports multiple streams on it. Each stream is identified by a protocol tag.

func NewMSSelect

func NewMSSelect(c io.ReadWriteCloser, proto string) Multistream

NewMSSelect returns a new Multistream which is able to perform protocol selection with a MultistreamMuxer.

func NewMultistream

func NewMultistream(c io.ReadWriteCloser, proto string) Multistream

NewMultistream returns a multistream for the given protocol. This will not perform any protocol selection. If you are using a MultistreamMuxer, use NewMSSelect.

type MultistreamMuxer

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

MultistreamMuxer is a muxer for multistream. Depending on the stream protocol tag it will select the right handler and hand the stream off to it.

func NewMultistreamMuxer

func NewMultistreamMuxer() *MultistreamMuxer

NewMultistreamMuxer creates a muxer.

func (*MultistreamMuxer) AddHandler

func (msm *MultistreamMuxer) AddHandler(protocol string, handler HandlerFunc)

AddHandler attaches a new protocol handler to the muxer.

func (*MultistreamMuxer) AddHandlerWithFunc

func (msm *MultistreamMuxer) AddHandlerWithFunc(protocol string, match func(string) bool, handler HandlerFunc)

AddHandlerWithFunc attaches a new protocol handler to the muxer with a match. If the match function returns true for a given protocol tag, the protocol will be selected even if the handler name and protocol tags are different.

func (*MultistreamMuxer) Handle

func (msm *MultistreamMuxer) Handle(rwc io.ReadWriteCloser) error

Handle performs protocol negotiation on a ReadWriteCloser (i.e. a connection). It will find a matching handler for the incoming protocol and pass the ReadWriteCloser to it.

func (*MultistreamMuxer) Ls

func (msm *MultistreamMuxer) Ls(w io.Writer) error

Ls implements the "ls" command which writes the list of supported protocols to the given Writer.

func (*MultistreamMuxer) Negotiate

func (msm *MultistreamMuxer) Negotiate(rwc io.ReadWriteCloser) (string, HandlerFunc, error)

Negotiate performs protocol selection and returns the protocol name and the matching handler function for it (or an error).

func (*MultistreamMuxer) NegotiateLazy

func (msm *MultistreamMuxer) NegotiateLazy(rwc io.ReadWriteCloser) (Multistream, string, HandlerFunc, error)

NegotiateLazy performs protocol selection and returns a multistream, the protocol used, the handler and an error. It is lazy because the write-handshake is performed on a subroutine, allowing this to return before that handshake is completed.

func (*MultistreamMuxer) Protocols

func (msm *MultistreamMuxer) Protocols() []string

Protocols returns the list of handler-names added to this this muxer.

func (*MultistreamMuxer) RemoveHandler

func (msm *MultistreamMuxer) RemoveHandler(protocol string)

RemoveHandler removes the handler with the given name from the muxer.

Jump to

Keyboard shortcuts

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