# README
liblpc
High performance async network io library
First
if you have any good feature suggestions or bug fixed , any Pull Request or Issues are welcome!
Usage
# install liblpc v2
go get -u github.com/gen-iot/liblpc/v2@latest
// import
import "github.com/gen-iot/liblpc/v2"
Overview
- World Based On Event Loop π
- UnBuffered/Buffered Stream π
- Timers: IO Timeout, Delay... β°
- DNS Resolve π
- Lots Of Unix Socket API Toolbox π§
- Thread(Goroutine) Safe! π
Backend
Platform | Backend | Support |
---|---|---|
Linux family | Epoll | Done π |
mac OS (BSD family) | Kqueue | Done π |
Windows | IOCP | Maybe Never... π’ |
POSIX Like | Poll | Maybe Never... π₯Ί we already have epoll |
POSIX Like | Select | Coming Soon π€‘ |
liblpc
using interface Poller
and Watcher
as abstraction for any backend.
Getting Started
Create Pure EventLoop:
loop,err := liblpc.NewEventLoop()
std.AssertError(err, "new pure event loop")
Create IO EventLoop:
loop, err := liblpc.NewIOEvtLoop(1024 * 4)
std.AssertError(err, "new io event loop")
Loop Lifecycle:
exit a loop
// just call loop.Break in anywhere
loop.Break()
πLoop.'Close' can't stop a loop but Loop.'Break' can.
πLoop.'Close' use to cleanup a loop
Cleanup a loop
loop ,err := liblpc.NewEventLoop()
std.AssertError(err, "new event loop")
defer loop.Close()
Run loop synchronously
// block until break loop called
loop.Run()
Run loop asynchronouslyπππ
go func(){ loop.Run() }()
Create Listener:
// create listen fd first!
listenerFd, err := liblpc.NewListenerFd(
"127.0.0.1:12345", // serve at
1024, // backlog
true, // enable reuse addr
true, // enable reuse port
)
std.AssertError(err, "new listener fd")
// new listener
listener := liblpc.NewListener(loop, int(listenerFd), onAccept)
listener.Start()
Accept New Conn Stream:
// πNote: in accept callback
stream := liblpc.NewConnStream(
ln.Loop().(*liblpc.IOEvtLoop), // cast Loop to IOEventLoop
newFd, // incoming fd
onStreamRead, // read callback
)
stream.SetOnClose(onStreamClose) // register close callback
stream.Start()
Create Client Stream:
cliFd, err := liblpc.NewConnFd(addr)
std.AssertError(err, "new client fd failed")
stream := liblpc.NewConnStream(loop, int(cliFd), nil)
stream.SetOnConnect(func(sw liblpc.StreamWriter, err error) {
sw.Write([]byte("hello world!"), true)
})
stream.SetOnClose(func(sw liblpc.StreamWriter, err error) {
log.Println("client close :", err)
// break loop...
loop.Break()
})
stream.Start()
πStream.'Close' is safe to invoke multi times
πAnytime you can't find out whether if Stream is 'Closing' or really been 'Closed',Just invoke Stream.'Close'
Example: Simple Read/Write/Close
package main
import (
"github.com/gen-iot/liblpc"
"github.com/gen-iot/std"
"log"
)
func onStreamRead(sw liblpc.StreamWriter, data []byte, len int) {
// print client data in string format
log.Println("on read:", string(data[:len]))
_ = sw.Close()
}
func onStreamClose(sw liblpc.StreamWriter, err error) {
log.Println("conn closed,err:", err)
_ = sw.Close() // close remote client
}
func onAccept(ln *liblpc.Listener, newFd int, err error) {
if err != nil {
log.Printf("listener got error:%v\n", err)
return
}
stream := liblpc.NewConnStream(
ln.Loop().(*liblpc.IOEvtLoop), // cast Loop to IOEventLoop
newFd, // incoming fd
onStreamRead, // read callback
)
stream.SetOnClose(onStreamClose) // register close callback
stream.Start()
}
func simpleClient(loop *liblpc.IOEvtLoop, addr string) {
cliFd, err := liblpc.NewConnFd(addr)
std.AssertError(err, "new client fd failed")
stream := liblpc.NewConnStream(loop, int(cliFd), nil)
stream.SetOnConnect(func(sw liblpc.StreamWriter, err error) {
sw.Write([]byte("hello world!"), true)
})
stream.SetOnClose(func(sw liblpc.StreamWriter, err error) {
log.Println("client close :", err)
// close itself
_ = sw.Close()
// break loop...
loop.Break()
})
stream.Start()
}
func main() {
loop, err := liblpc.NewIOEvtLoop(1024 * 4)
std.AssertError(err, "new event loop")
defer std.CloseIgnoreErr(loop)
// create listen fd first!
listenerFd, err := liblpc.NewListenerFd(
"127.0.0.1:12345", // serve at
1024, // backlog
true, // enable reuse addr
true, // enable reuse port
)
std.AssertError(err, "new listener fd")
// new listener
listener := liblpc.NewListener(loop, int(listenerFd), onAccept)
defer std.CloseIgnoreErr(listener)
listener.Start()
// start simple client
simpleClient(loop, "127.0.0.1:12345")
//
loop.Run()
}
License
Released under the MIT License
# Packages
No description provided by the author
# Functions
No description provided by the author
fd[0] for parent process fd[1] for child process nonblock : set socket nonblock.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
fd with nonblock, cloexec default.
fd with nonblock, cloexec default.
No description provided by the author
No description provided by the author
No description provided by the author
create new socket , cloexec by default.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
# Constants
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
# Variables
No description provided by the author
No description provided by the author
No description provided by the author
# Structs
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
# Interfaces
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
# Type aliases
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author