Skip to content
/ netpoll Public

Package netpoll implements a network poller based on epoll/kqueue.

License

Notifications You must be signed in to change notification settings

hslam/netpoll

Folders and files

NameName
Last commit message
Last commit date

Latest commit

32b5991 · Nov 14, 2023
Dec 18, 2020
Aug 13, 2020
Aug 13, 2020
Jan 7, 2021
Nov 14, 2023
Nov 14, 2023
Oct 28, 2021
Sep 26, 2021
Dec 22, 2020
Feb 19, 2023
Jan 7, 2021
May 14, 2023
Feb 19, 2023
May 14, 2023
May 14, 2023
May 14, 2023
Oct 12, 2021
May 14, 2023
Feb 19, 2023

Repository files navigation

netpoll

PkgGoDev Build Status codecov Go Report Card LICENSE

Package netpoll implements a network poller based on epoll/kqueue.

Features

  • Epoll/kqueue
  • TCP/UNIX
  • Compatible with the net.Conn interface.
  • Upgrade connection
  • Non-blocking I/O
  • Splice/sendfile
  • Rescheduling workers

Comparison to other packages.

Package net netpoll gnet evio
Low memory usage No Yes Yes Yes
Non-blocking I/O No Yes Yes Yes
Splice/sendfile Yes Yes No No
Rescheduling Yes Yes No No
Compatible with the net.Conn interface Yes Yes No No

mock 0msmock 1ms

Get started

Install

go get github.com/hslam/netpoll

Import

import "github.com/hslam/netpoll"

Usage

Simple Example

package main

import "github.com/hslam/netpoll"

func main() {
	var handler = &netpoll.DataHandler{
		NoShared:   true,
		NoCopy:     true,
		BufferSize: 1024,
		HandlerFunc: func(req []byte) (res []byte) {
			res = req
			return
		},
	}
	if err := netpoll.ListenAndServe("tcp", ":9999", handler); err != nil {
		panic(err)
	}
}

TLS Example

package main

import (
	"crypto/tls"
	"github.com/hslam/netpoll"
	"github.com/hslam/socket"
	"net"
)

func main() {
	var handler = &netpoll.DataHandler{
		NoShared:   true,
		NoCopy:     true,
		BufferSize: 1024,
		HandlerFunc: func(req []byte) (res []byte) {
			res = req
			return
		},
	}
	handler.SetUpgrade(func(conn net.Conn) (net.Conn, error) {
		tlsConn := tls.Server(conn, socket.DefalutTLSConfig())
		if err := tlsConn.Handshake(); err != nil {
			return nil, err
		}
		return tlsConn, nil
	})
	if err := netpoll.ListenAndServe("tcp", ":9999", handler); err != nil {
		panic(err)
	}
}

Websocket Example

package main

import (
	"github.com/hslam/netpoll"
	"github.com/hslam/websocket"
	"net"
)

func main() {
	var handler = &netpoll.ConnHandler{}
	handler.SetUpgrade(func(conn net.Conn) (netpoll.Context, error) {
		return websocket.Upgrade(conn, nil)
	})
	handler.SetServe(func(context netpoll.Context) error {
		ws := context.(*websocket.Conn)
		msg, err := ws.ReadMessage()
		if err != nil {
			return err
		}
		return ws.WriteMessage(msg)
	})
	if err := netpoll.ListenAndServe("tcp", ":9999", handler); err != nil {
		panic(err)
	}
}

HTTP Example

package main

import (
	"bufio"
	"github.com/hslam/mux"
	"github.com/hslam/netpoll"
	"github.com/hslam/response"
	"net"
	"net/http"
	"sync"
)

func main() {
	m := mux.New()
	m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello World"))
	})
	ListenAndServe(":8080", m)
}

func ListenAndServe(addr string, handler http.Handler) error {
	var h = &netpoll.ConnHandler{}
	type Context struct {
		reader  *bufio.Reader
		rw      *bufio.ReadWriter
		conn    net.Conn
		serving sync.Mutex
	}
	h.SetUpgrade(func(conn net.Conn) (netpoll.Context, error) {
		reader := bufio.NewReader(conn)
		rw := bufio.NewReadWriter(reader, bufio.NewWriter(conn))
		return &Context{reader: reader, conn: conn, rw: rw}, nil
	})
	h.SetServe(func(context netpoll.Context) error {
		ctx := context.(*Context)
		ctx.serving.Lock()
		req, err := http.ReadRequest(ctx.reader)
		if err != nil {
			ctx.serving.Unlock()
			return err
		}
		res := response.NewResponse(req, ctx.conn, ctx.rw)
		handler.ServeHTTP(res, req)
		res.FinishRequest()
		ctx.serving.Unlock()
		response.FreeResponse(res)
		return nil
	})
	return netpoll.ListenAndServe("tcp", addr, h)
}

License

This package is licensed under a MIT license (Copyright (c) 2020 Meng Huang)

Author

netpoll was written by Meng Huang.