nettyws是一款基于go-netty编写的高性能 websocket 库,底层协议编解码基于gobwas/ws
但是针对性进行了额外的性能优化,相比较直接使用gobwas/ws
库,nettyws
的接口更加易于使用,性能也明显优于它
仓库地址: https://github.com/go-netty/go-netty-ws
type Websocket
func NewWebsocket(options ...Option) *Websocket
func (ws *Websocket) Close() error
func (ws *Websocket) Listen(addr string) error
func (ws *Websocket) Open(addr string) error
func (ws *Websocket) UpgradeHTTP(w http.ResponseWriter, r *http.Request) (Conn, error)
type Option
func WithAsyncWrite(writeQueueSize int, writeForever bool) Option
func WithBinary() Option
func WithBufferSize(readBufferSize, writeBufferSize int) Option
func WithCompress(compressLevel int, compressThreshold int64) Option
func WithMaxFrameSize(maxFrameSize int64) Option
func WithNoDelay(noDelay bool) Option
func WithServeMux(serveMux *http.ServeMux) Option
func WithServeTLS(tls *tls.Config) Option
func WithValidUTF8() Option
Framework | TPS | Conns | Concurrency | Payload | CPU Avg | CPU Max | MEM Min | MEM Avg | MEM Max |
---|---|---|---|---|---|---|---|---|---|
gobwas | 510595 | 10000 | 10000 | 1024 | 762.87 | 785.80 | 361.89M | 364.79M | 366.24M |
nettyws | 637288 | 10000 | 10000 | 1024 | 636.00 | 643.86 | 173.52M | 178.02M | 182.52M |
详细性能压测数据来源: go-websocket-benchmark
// create websocket instance
var ws = nettyws.NewWebsocket()
// setup OnOpen handler
ws.OnOpen = func(conn nettyws.Conn) {
fmt.Println("OnOpen: ", conn.RemoteAddr())
}
// setup OnData handler
ws.OnData = func(conn nettyws.Conn, data []byte) {
fmt.Println("OnData: ", conn.RemoteAddr(), ", message: ", string(data))
conn.Write(data)
}
// setup OnClose handler
ws.OnClose = func(conn nettyws.Conn, err error) {
fmt.Println("OnClose: ", conn.RemoteAddr(), ", error: ", err)
}
fmt.Println("listening websocket connections ....")
// listen websocket server
if err := ws.Listen("ws://127.0.0.1:9527/ws"); nil != err {
panic(err)
}
// create websocket instance
var ws = nettyws.NewWebsocket()
// setup OnOpen handler
ws.OnOpen = func(conn nettyws.Conn) {
fmt.Println("OnOpen: ", conn.RemoteAddr())
conn.Write([]byte("hello world"))
}
// setup OnData handler
ws.OnData = func(conn nettyws.Conn, data []byte) {
fmt.Println("OnData: ", conn.RemoteAddr(), ", message: ", string(data))
}
// setup OnClose handler
ws.OnClose = func(conn nettyws.Conn, err error) {
fmt.Println("OnClose: ", conn.RemoteAddr(), ", error: ", err)
}
fmt.Println("open websocket connection ...")
// connect to websocket server
if err := ws.Open("ws://127.0.0.1:9527/ws"); nil != err {
panic(err)
}
// create websocket instance
var ws = nettyws.NewWebsocket()
// setup OnOpen handler
ws.OnOpen = func(conn nettyws.Conn) {
fmt.Println("OnOpen: ", conn.RemoteAddr())
}
// setup OnData handler
ws.OnData = func(conn nettyws.Conn, data []byte) {
fmt.Println("OnData: ", conn.RemoteAddr(), ", message: ", string(data))
conn.Write(data)
}
// setup OnClose handler
ws.OnClose = func(conn nettyws.Conn, err error) {
fmt.Println("OnClose: ", conn.RemoteAddr(), ", error: ", err)
}
fmt.Println("upgrade websocket connections ....")
// upgrade websocket connection from http server
serveMux := http.NewServeMux()
serveMux.HandleFunc("/ws", func(writer http.ResponseWriter, request *http.Request) {
ws.UpgradeHTTP(writer, request)
})
// listen http server
if err := http.ListenAndServe(":9527", serveMux); nil != err {
panic(err)
}
特别说明,nettyws
不支持混合数据数据模式,也就是说服务器启动时必须指定数据包格式(文本/二进制,默认文本格式)如果收到了非指定数据包格式则将会被丢弃,这样做的原因之一是nettyws
使用的底层传输层抽象成 io.ReadWriter 之后无法携带除数据之外的格式信息,同时真实业务场景上同时混用数据格式的情况比比较少见,因此直接放弃了混合数据格式的支持。
1
cian 2023-11-03 09:43:28 +08:00 via Android
不错已星
|
3
lifespy 2023-11-03 10:21:40 +08:00
看着好像很不错。我刚刚接触 go 不久,想问问,我举个例子。
如果说我想和 goframe 框架结合使用,这个路由该如何定义呢 |
4
limpo OP @lifespy 抱歉 我对 goframe 不是太熟悉,一般基于标准库 server 的路由都可以参考 **从标准 http 服务器升级** 这个例子进行适配
|
5
lifespy 2023-11-03 13:54:50 +08:00
|
7
yrzs 2023-11-03 16:48:39 +08:00
starred
|
9
lifespy 2023-11-06 11:09:00 +08:00
前端 js 发送文本消息,服务端接受时提示
OnClose: 127.0.0.1:52295 , error: flate: corrupt input before offset 6 但是用 apipost 模拟又没有问题 |