https://github.com/Allenxuxu/gev
gev 是一个轻量、快速、高性能的基于 Reactor 模式的非阻塞网络库,底层并不使用 golang net 库,而是使用 epoll 和 kqueue。
现在它支持 WebSocket 啦!
支持定时任务,延时任务!
测试环境 Ubuntu18.04
限制 GOMAXPROCS=1,1 个 work 协程
限制 GOMAXPROCS=1,4 个 work 协程
限制 GOMAXPROCS=4,4 个 work 协程
go get -u github.com/Allenxuxu/gev
package main import ( "flag" "strconv" "log" "github.com/Allenxuxu/gev" "github.com/Allenxuxu/gev/connection" "github.com/Allenxuxu/ringbuffer" ) type example struct{} func (s *example) OnConnect(c *connection.Connection) { log.Println(" OnConnect: ", c.PeerAddr()) } func (s *example) OnMessage(c *connection.Connection, buffer *ringbuffer.RingBuffer) (out []byte) { //log.Println("OnMessage") first, end := buffer.PeekAll() out = first if len(end) > 0 { out = append(out, end...) } buffer.RetrieveAll() return } func (s *example) OnClose() { log.Println("OnClose") } func main() { handler := new(example) var port int var loops int flag.IntVar(&port, "port", 1833, "server port") flag.IntVar(&loops, "loops", -1, "num loops") flag.Parse() s, err := gev.NewServer(handler, gev.Network("tcp"), gev.Address(":"+strconv.Itoa(port)), gev.NumLoops(loops)) if err != nil { panic(err) } s.Start() }
package main import ( "flag" "github.com/Allenxuxu/gev/ws" "log" "math/rand" "strconv" "github.com/Allenxuxu/gev" "github.com/Allenxuxu/gev/connection" ) type example struct{} func (s *example) OnConnect(c *connection.Connection) { log.Println(" OnConnect: ", c.PeerAddr()) } func (s *example) OnMessage(c *connection.Connection, data []byte) (messageType ws.MessageType, out []byte) { log.Println("OnMessage:", string(data)) messageType = ws.MessageBinary switch rand.Int() % 3 { case 0: out = data case 1: if err := c.SendWebsocketData(ws.MessageText, data); err != nil { if e := c.CloseWebsocket(err.Error()); e != nil { panic(e) } } case 2: if e := c.CloseWebsocket("close"); e != nil { panic(e) } } return } func (s *example) OnClose(c *connection.Connection) { log.Println("OnClose") } func main() { handler := new(example) var port int var loops int flag.IntVar(&port, "port", 1833, "server port") flag.IntVar(&loops, "loops", -1, "num loops") flag.Parse() s, err := gev.NewWebSocketServer(handler, gev.Network("tcp"), gev.Address(":"+strconv.Itoa(port)), gev.NumLoops(loops)) if err != nil { panic(err) } s.Start() }
1 zeromake 2019-10-24 10:45:20 +08:00 能解释一下为啥要内置定时能力,而不是让调用方使用外部库来实现呢? |
![]() | 7 codehz 2019-10-24 21:44:02 +08:00 定时任务似乎没有使用 timerfd,这样就不能利用单一 epoll 的优势了( |
![]() | 8 Aether 2019-10-25 12:03:30 +08:00 定时内容都是放在内存里的,可能会丢失,是这样吗? |