Skip to content

Instantly share code, notes, and snippets.

@auxten
Created June 27, 2018 08:03
Show Gist options
  • Save auxten/d728bdc1eae826efc66d85ab2f285432 to your computer and use it in GitHub Desktop.
Save auxten/d728bdc1eae826efc66d85ab2f285432 to your computer and use it in GitHub Desktop.
simple yamux io multiplexer demo
package main
import (
log "github.com/auxten/logrus"
"net"
"github.com/hashicorp/yamux"
"sync"
)
const LoopCount = 1000
func main() {
log.SetLevel(log.DebugLevel)
log.Println("Starting yamux demo")
localAddr := "127.0.0.1:4444"
wg := &sync.WaitGroup{}
go server(localAddr, wg)
if err := client(localAddr); err != nil {
log.Println(err)
}
wg.Wait()
}
func client(serverAddr string) error {
// Get a TCP connection
conn, err := net.Dial("tcp", serverAddr)
if err != nil {
return err
}
// Setup client side of yamux
log.Println("creating client session")
session, err := yamux.Client(conn, nil)
if err != nil {
return err
}
for i:=0;i<100;i++{
// Open a new stream
log.Println("opening stream")
stream, err := session.Open()
if err != nil {
log.Error(err)
return err
}
go func() {
// Stream implements net.Conn
for i:=0;i<LoopCount;i++ {
_, err = stream.Write([]byte("ping"))
}
}()
}
// Open a new stream
log.Println("opening stream2")
stream2, err := session.Open()
if err != nil {
return err
}
// Stream implements net.Conn
_, err = stream2.Write([]byte("ping2"))
// Accept a stream
log.Println("accepting stream3")
stream3, err := session.Accept()
if err != nil {
return err
}
// Listen for a message
buf2 := make([]byte, 5)
_, err = stream3.Read(buf2)
log.Printf("buf3 = %+v\n", string(buf2))
return err
}
func server(localAddr string, wg *sync.WaitGroup) error {
// Accept a TCP connection
listener, err := net.Listen("tcp", localAddr)
conn, err := listener.Accept()
if err != nil {
return err
}
wg.Add(1)
// Setup server side of yamux
log.Println("creating server session")
session, err := yamux.Server(conn, nil)
if err != nil {
return err
}
for i:=0;i<100;i++ {
// Accept a stream
log.Println("accepting stream")
stream, err := session.Accept()
if err != nil {
log.Error(err)
return err
}
go func(i int) {
wg.Add(1)
buf1 := make([]byte, 4)
// Stream implements net.Conn
for i := 0; i < LoopCount; i++ {
// Listen for a message
n, err := stream.Read(buf1)
if err != nil || n != len(buf1) || string(buf1) != "ping" {
log.Errorf("read error: %s",err)
}
}
wg.Done()
log.Debugf("buf#%d read done", i)
}(i)
}
// Accept a stream
log.Println("accepting stream2")
stream2, err := session.Accept()
if err != nil {
return err
}
// Listen for a message
buf2 := make([]byte, 5)
_, err = stream2.Read(buf2)
log.Printf("buf2 = %+v\n", string(buf2))
// Open a new stream
log.Println("opening stream3")
stream3, err := session.Open()
if err != nil {
return err
}
// Stream implements net.Conn
_, err = stream3.Write([]byte("pong3"))
wg.Done()
return err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment