gnet

package module
v1.3.2 Latest Latest
Warning

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

Go to latest
Published: Nov 16, 2020 License: MIT Imports: 4 Imported by: 1

README

gnet

Installation

go get -u github.com/izhw/gnet

Features

Building net service quickly with functional options

  • TCP Server and Client
  • Connection pools
  • gRPC Server and Client
  • WebSocket Server and Client

Quick start

Examples
TCP Server
package main

import (
    "fmt"
    
    "github.com/izhw/gnet"
    "github.com/izhw/gnet/gcore"
    "github.com/izhw/gnet/logger"
)

type ServerHandler struct {
    *gcore.NetEventHandler
}

func (h *ServerHandler) OnReadMsg(c gcore.Conn, data []byte) error {
    fmt.Println("server read msg:", string(data))
    c.Write(data)
    return nil
}

func main() {
    log := logger.GlobalSimpleLogger()
    svc := gnet.NewService(
        gcore.WithServiceType(gcore.SvcTypeTCPServer),
        gcore.WithAddr("0.0.0.0:7777"),
        gcore.WithEventHandler(&ServerHandler{}),
        gcore.WithLogger(log),
    )
    s := svc.Server()
    if err := s.Init(); err != nil {
        log.Fatal("server init error:", err)
    }
    log.Fatal("server exit:", s.Serve())
}
TCP Client
  • Sync mode
package main

import (
    "fmt"
    "os"
    
    "github.com/izhw/gnet"
    "github.com/izhw/gnet/gcore"
)

func main() {
    svc := gnet.NewService(
        gcore.WithServiceType(gcore.SvcTypeTCPClient),
        gcore.WithAddr("127.0.0.1:7777"),
    )
    c := svc.Client()
    if err := c.Init(); err != nil {
        fmt.Println("client init error:", err)
        os.Exit(1)
    }
    defer c.Close()
    // todo...
    data := []byte("Hello world")
    resp, err := c.WriteRead(data)
    if err != nil {
        fmt.Println("client WriteRead error:", err)
        os.Exit(1)
    }
    fmt.Println("client recv resp:", string(resp))
}
  • Async mode
package main

import (
    "fmt"
    "os"
    "time"
    
    "github.com/izhw/gnet"
    "github.com/izhw/gnet/gcore"
    "github.com/izhw/gnet/logger"
)

type AsyncHandler struct {
    *gcore.NetEventHandler
}

func (h *AsyncHandler) OnReadMsg(c gcore.Conn, data []byte) error {
    fmt.Println("async client read msg:", string(data))
    return nil
}

func main() {
    log := logger.GlobalSimpleLogger()
    svc := gnet.NewService(
        gcore.WithServiceType(gcore.SvcTypeTCPAsyncClient),
        gcore.WithAddr("127.0.0.1:7777"),
        gcore.WithEventHandler(&AsyncHandler{}),
        gcore.WithLogger(log),
    )
    c := svc.Client()
    if err := c.Init(); err != nil {
        log.Fatal("client init error:", err)
    }
    defer c.Close()
    
    data := []byte("Hello world")
    for i := 0; i < 10; i++ {
        if err := c.Write(data); err != nil {
            log.Fatal("client write err:", err)
        }
        time.Sleep(1 * time.Second)
    }
}
Connection pool
  • Sync mode
package main

import (
    "fmt"
    "os"
    
    "github.com/izhw/gnet"
    "github.com/izhw/gnet/gcore"
)

func main() {
    svc := gnet.NewService(
        gcore.WithServiceType(gcore.SvcTypeTCPPool),
        gcore.WithAddr("127.0.0.1:7777"),
        gcore.WithPoolSize(5, 10),
    )
    p := svc.Pool()
    if err := p.Init(); err != nil {
        fmt.Println("pool init error:", err)
        os.Exit(1)
    }
    defer p.Close()
    
    c, err := p.Get()
    if err != nil {
        fmt.Println("Pool Get error:", err)
        os.Exit(1)
    }
    defer p.Put(c)
    
    resp, err := c.WriteRead([]byte("Hello world"))
    if err != nil {
        fmt.Println("Pool WriteRead error:", err)
        os.Exit(1)
    }
    fmt.Println("Pool WriteRead:", string(resp))
}
  • Async mode
package main

import (
    "fmt"
    "os"
    "time"
    
    "github.com/izhw/gnet"
    "github.com/izhw/gnet/gcore"
    "github.com/izhw/gnet/logger"
)

type AsyncHandler struct {
    *gcore.NetEventHandler
}

func (h *AsyncHandler) OnReadMsg(c gcore.Conn, data []byte) error {
    fmt.Println("Pool read msg:", string(data))
    return nil
}

func main() {
    log := logger.GlobalSimpleLogger()
    svc := gnet.NewService(
        gcore.WithServiceType(gcore.SvcTypeTCPAsyncPool),
        gcore.WithAddr("127.0.0.1:7777"),
        gcore.WithEventHandler(&AsyncHandler{}),
        gcore.WithPoolSize(0, 10),
        gcore.WithPoolGetTimeout(5*time.Second),
        gcore.WithPoolIdleTimeout(30*time.Minute),
        //gcore.WithHeartbeat([]byte{0}, 30*time.Second),
    )
    p := svc.Pool()
    if err := p.Init(); err != nil {
        log.Fatal("pool init error:", err)
    }
    defer p.Close()
    
    c, err := p.Get()
    if err != nil {
        log.Fatal("Pool Get error:", err)
    }
    defer p.Put(c)
    
    if err = c.Write([]byte("Hello world")); err != nil {
        log.Fatal("Pool Write error:", err)
    }
    time.Sleep(3 * time.Second)
}
Multi

You can build server, client and pool in one service by setting the ServiceType: gcore.WithServiceType(gcore.ServiceTCPServer|gcore.ServiceTCPAsyncClient|gcore.ServiceTCPAsyncPool)

package main

import (
    "context"
    "fmt"
    "time"
    
    "github.com/izhw/gnet"
    "github.com/izhw/gnet/gcore"
    "github.com/izhw/gnet/logger"
)

type ServerHandler struct {
    *gcore.NetEventHandler
}

func (h *ServerHandler) OnReadMsg(c gcore.Conn, data []byte) error {
    fmt.Println("server read msg:", string(data))
    c.Write(data)
    return nil
}

type AsyncHandler struct {
    *gcore.NetEventHandler
}

func (h *AsyncHandler) OnReadMsg(c gcore.Conn, data []byte) error {
    fmt.Println("multi client read msg:", string(data))
    return nil
}

func main() {

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()
    
    log := logger.GlobalSimpleLogger()
    svc := gnet.NewService(
        gcore.WithServiceType(gcore.SvcTypeTCPServer|gcore.SvcTypeTCPAsyncClient),
        gcore.WithLogger(log),
    )
    
    // client
    c := svc.Client()
    err := c.Init(
        gcore.WithAddr("127.0.0.1:7777"),
        gcore.WithEventHandler(&AsyncHandler{}),
    )
    if err != nil {
        log.Fatal("client init error:", err)
    }
    defer c.Close()
    
    go StartClient(ctx, c)
    
    // server
    s := svc.Server()
    err = s.Init(
        gcore.WithAddr("0.0.0.0:7778"),
        gcore.WithEventHandler(&ServerHandler{}),
    )
    if err != nil {
        log.Fatal("server init error:", err)
    }
    log.Fatal("Exit:", s.Serve())
}

func StartClient(ctx context.Context, c gnet.Client) {
    log := logger.GlobalSimpleLogger()
    ticker := time.NewTicker(1 * time.Second)
    defer ticker.Stop()
    
    data := []byte("multi client")
    for i := 0; i < 1000; i++ {
        select {
        case <-ctx.Done():
            return
        case <-ticker.C:
            if err := c.Write(data); err != nil {
                log.Error("multi client write err:", err)
                return
            }
        }
    }
}
Functional options for gnet

for example:

    svc := gnet.NewService(
        gcore.WithServiceType(gcore.SvcTypeTCPServer),
        gcore.WithAddr("0.0.0.0:7777"),
        gcore.WithEventHandler(&ServerHandler{}),
        gcore.WithLogger(logger.GlobalSimpleLogger()),
        gcore.WithHeaderCodec(&codec.CodecProtoVarint{}),
        gcore.WithReadTimeout(2 * time.Minute),
        gcore.WithConnNumLimit(1000),
        gcore.WithHeartbeat([]byte{0}, 30 * time.Second)
        ...
    )

See gcore/options.go for more options

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client added in v1.3.1

type Client gcore.Conn

type Pool

type Pool gcore.Pool

type Server

type Server gcore.Server

type Service added in v1.3.1

type Service interface {
	Server() Server
	Client() Client
	Pool() Pool
}

Service is an interface that wraps the server, client and pool, for building and initialising services conveniently.

func NewService added in v1.3.1

func NewService(opts ...gcore.Option) Service

NewService creates a new Service with options.

Directories

Path Synopsis
examples
internal
tcp

Jump to

Keyboard shortcuts

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