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 之后无法携带除数据之外的格式信息,同时真实业务场景上同时混用数据格式的情况比比较少见,因此直接放弃了混合数据格式的支持。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.