gws: 兼顾性能与用户友好的go websocket server

lxzan · · 1108 次点击 · · 开始浏览    

#### 压测结果镇楼 - machine: Ubuntu 20.04LTS VM (4C8T) - client: tcpkali | Server | Connection | Send Speed(msg/s) | Payload size | Download / Upload Bandwidth(Mbps) | | ------- | ---------- | ----------------- | ------------ | --------------------------------- | | gws | 200 | 20000 | 2.34KiB | 11614.442↓ 11556.101↑ | | gorilla | 200 | 20000 | 2.34KiB | 4244.398↓ 4188.711↑ | | gws | 2000 | 500 | 2.34KiB | 7906.156↓ 7914.797↑ | | gorilla | 2000 | 500 | 2.34KiB | 4263.545↓ 4260.077↑ | | gws | 5000 | 50 | 2.34KiB | 4941.188↓ 4943.667↑ | | gorilla | 5000 | 50 | 2.34KiB | - | | gws | 10000 | 10 | 2.34KiB | 1980.124↓ 1977.561↑ | | gorilla | 10000 | 10 | 2.34KiB | 1972.556↓ 1979.981↑ | | gws | 10000 | 20 | 2.34KiB | 3952.788↓ 3959.341↑ | | gorilla | 10000 | 20 | 2.34KiB | - | > `-` means exception #### 亮点 - 无依赖 - 不需要额外开启协程监听消息, 处理各种事件 - 读写消息不返回错误, 它们在gws内部被适当的处理了 - 通过了 autobahn-testsuite 所有的WebSocket Protocol测试用例 #### 安装 ```bash go get -v github.com/lxzan/gws@latest ``` #### 核心接口 ```go type Event interface { OnOpen(socket *Conn) OnError(socket *Conn, err error) OnClose(socket *Conn, code uint16, reason []byte) OnPing(socket *Conn, payload []byte) OnPong(socket *Conn, payload []byte) OnMessage(socket *Conn, message *Message) } ``` ### 快速开始 (Autobahn Server) ```go package main import ( "fmt" "github.com/lxzan/gws" "net/http" ) func main() { var upgrader = gws.NewUpgrader(func(c *gws.Upgrader) { c.CompressEnabled = true c.CheckTextEncoding = true c.MaxContentLength = 32 * 1024 * 1024 c.EventHandler = new(WebSocket) }) http.HandleFunc("/connect", func(writer http.ResponseWriter, request *http.Request) { socket, err := upgrader.Accept(writer, request) if err != nil { return } socket.Listen() }) _ = http.ListenAndServe(":3000", nil) } type WebSocket struct{} func (c *WebSocket) OnClose(socket *gws.Conn, code uint16, reason []byte) { fmt.Printf("onclose: code=%d, payload=%s\n", code, string(reason)) } func (c *WebSocket) OnError(socket *gws.Conn, err error) { fmt.Printf("onerror: err=%s\n", err.Error()) } func (c *WebSocket) OnOpen(socket *gws.Conn) { println("connected") } func (c *WebSocket) OnPing(socket *gws.Conn, payload []byte) { fmt.Printf("onping: payload=%s\n", string(payload)) socket.WritePong(payload) } func (c *WebSocket) OnPong(socket *gws.Conn, payload []byte) {} func (c *WebSocket) OnMessage(socket *gws.Conn, message *gws.Message) { socket.WriteMessage(message.Typ(), message.Bytes()) message.Close() } ``` #### 测试 ```bash docker run -it --rm \ -v ${PWD}/config:/config \ -v ${PWD}/reports:/reports \ crossbario/autobahn-testsuite \ wstest -m fuzzingclient -s /config/fuzzingclient.json ``` ![image.png](https://static.golangjob.cn/230108/eb6c7644e96abbd6d7f387a43c2a66a5.png)

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1108 次点击  ∙  2 赞  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传