WebSocket 示例界面

websocket.png

第三方包

websocket 链接时支持配置项:

  1. type Upgrader struct {
  2. // 指定升级 websocket 握手完成的超时时间
  3. HandshakeTimeout time.Duration
  4. // 指定 io 操作的缓存大小,如果不指定就会自动分配。
  5. ReadBufferSize, WriteBufferSize int
  6. // 写数据操作的缓存池,如果没有设置值,write buffers 将会分配到链接生命周期里。
  7. WriteBufferPool BufferPool
  8. //按顺序指定服务支持的协议,如值存在,则服务会从第一个开始匹配客户端的协议。
  9. Subprotocols []string
  10. // 指定 http 的错误响应函数,如果没有设置 Error 则,会生成 http.Error 的错误响应。
  11. Error func(w http.ResponseWriter, r *http.Request, status int, reason error)
  12. // 请求检查函数,用于统一的链接检查,以防止跨站点请求伪造。如果不检查,就设置一个返回值为 true 的函数。
  13. // 如果请求 Origin 标头可以接受,CheckOrigin 将返回 true。 如果 CheckOrigin 为nil,则使用安全默认值:如果 Origin 请求头存在且原始主机不等于请求主机头,则返回 false
  14. CheckOrigin func(r *http.Request) bool
  15. // EnableCompression 指定服务器是否应尝试协商每个邮件压缩(RFC 7692)。
  16. // 将此值设置为true并不能保证将支持压缩。
  17. // 目前仅支持“无上下文接管”模式
  18. EnableCompression bool
  19. }

Upgrade 函数可将 http 升级到 WebSocket 协议:

  1. // responseHeader 包含在对客户端升级请求的响应中。
  2. // 使用 responseHeader 指定 cookie(Set-Cookie)和应用程序协商的子协议(Sec-WebSocket-Protocol)。
  3. // 如果升级失败,则升级将使用 HTTP 错误响应回复客户端
  4. // 返回一个 Conn 指针,拿到他后,可使用 Conn 读写数据与客户端通信。
  5. func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error)

代码封装

封装一个 socket_server,同时支持使用日志、数据库、缓存等操作:

  1. type Server interface {
  2. // OnMessage 接收消息
  3. OnMessage()
  4. // OnSend 发送消息
  5. OnSend(message []byte) error
  6. // OnClose 关闭
  7. OnClose()
  8. }
  9. func New(logger *zap.Logger, db db.Repo, cache cache.Repo, conn *websocket.Conn) (Server, error) {
  10. ...
  11. }

封装一个 socket_conn

  1. func (h *handler) Connect() core.HandlerFunc {
  2. var upGrader = websocket.Upgrader{
  3. HandshakeTimeout: 5 * time.Second,
  4. CheckOrigin: func(r *http.Request) bool {
  5. return true
  6. },
  7. }
  8. return func(ctx core.Context) {
  9. ws, err := upGrader.Upgrade(ctx.ResponseWriter(), ctx.Request(), nil)
  10. if err != nil {
  11. return
  12. }
  13. server, err = socket_server.New(h.logger, h.db, h.cache, ws)
  14. if err != nil {
  15. return
  16. }
  17. go server.OnMessage()
  18. }
  19. }

socket_conn 是一个 HandlerFunc,可直接在路由中使用。

项目中 websocket 链接地址为:/socket/system/message,发送消息的接口为:/api/tool/send_message

JavaScript 示例代码:

  1. const ws = new WebSocket("ws://127.0.0.1:9999/socket/system/message");
  2. //连接打开时触发
  3. ws.onopen = function (evt) {
  4. ...
  5. };
  6. //接收到消息时触发
  7. ws.onmessage = function (evt) {
  8. ...
  9. };
  10. //连接关闭时触发
  11. ws.onclose = function (evt) {
  12. ...
  13. };

在项目中 实用工具箱 -> WebSocket 界面,右侧请求接口发送消息,在左侧可以实时收到消息。

小结

本文纯属抛砖引玉,有问题,欢迎批评指正。

go-gin-api 项目开箱即用,支持 WEB 界面一键安装,赶快去试试吧。

推荐阅读