文档:https://godoc.org/github.com/gorilla/websocket

Constants

  1. const (
  2. CloseNormalClosure = 1000
  3. CloseGoingAway = 1001
  4. CloseProtocolError = 1002
  5. CloseUnsupportedData = 1003
  6. CloseNoStatusReceived = 1005
  7. CloseAbnormalClosure = 1006
  8. CloseInvalidFramePayloadData = 1007
  9. ClosePolicyViolation = 1008
  10. CloseMessageTooBig = 1009
  11. CloseMandatoryExtension = 1010
  12. CloseInternalServerErr = 1011
  13. CloseServiceRestart = 1012
  14. CloseTryAgainLater = 1013
  15. CloseTLSHandshake = 1015
  16. )

Variables

  1. // 默认拨号器
  2. var DefaultDialer = &Dialer{
  3. Proxy: http.ProxyFromEnvironment,
  4. HandshakeTimeout: 45 * time.Second,
  5. }
  6. // 握手失败错误
  7. var ErrBadHandshake = errors.New("websocket: bad handshake")
  8. // 向一个已关闭连接写入消息的错误
  9. var ErrCloseSent = errors.New("websocket: close sent")
  10. // 超出读取限制错误
  11. var ErrReadLimit = errors.New("websocket: read limit exceeded")

func FormatCloseMessage(closeCode int, text string) []byte 格式化为一条关闭消息
func IsCloseError(err error, codes …int) bool err是否为codes中的某个错误
func IsUnexpectedCloseError(err error, expectedCodes …int) bool err是否不为expectedCodes 中的某个错误
func IsWebSocketUpgrade(r *http.Request) bool 判断是否是websocket连接

type Conn

Conn类型表示一个WebSocket连接

  1. type Conn struct {
  2. // contains filtered or unexported fields
  3. }
  1. // 关闭连接
  2. func (c *Conn) Close() error
  3. //返回当前关闭处理程序
  4. func (c *Conn) CloseHandler() func(code int, text string) error
  5. //启用或关闭压缩
  6. func (c *Conn) EnableWriteCompression(enable bool)
  7. // 返回本地网络地址
  8. func (c *Conn) LocalAddr() net.Addr
  9. //返回远程网络地址
  10. func (c *Conn) RemoteAddr() net.Addr
  11. //返回当前ping处理器
  12. func (c *Conn) PingHandler() func(appData string) error
  13. //返回当前pong处理器
  14. func (c *Conn) PongHandler() func(appData string) error
  15. //读取josn消息
  16. func (c *Conn) ReadJSON(v interface{}) error
  17. //读取消息
  18. func (c *Conn) ReadMessage() (messageType int, p []byte, err error)
  19. //设置压缩级别
  20. func (c *Conn) SetCompressionLevel(level int) error
  21. //接收到ping消息后,处理机制,默认返回一个pong
  22. func (c *Conn) SetPingHandler(h func(appData string) error)
  23. //接收到pong消息后,处理机制,默认不处理
  24. func (c *Conn) SetPongHandler(h func(appData string) error)
  25. //设置读取超时
  26. //读取超时后,websocket连接状态被破坏,以后的读取都会返回一个错误
  27. //t的零值表示读取不会超时
  28. func (c *Conn) SetReadDeadline(t time.Time) error
  29. //设置读取最大字节数
  30. //如果消息超过了限制,连接将向对等方发送一条关闭消息,并向应用程序返回ErrReadLimit
  31. func (c *Conn) SetReadLimit(limit int64)
  32. //设置写入超时
  33. //写入超时后,websocket连接状态被破坏,以后的写入都会返回一个错误
  34. //t的零值表示写入不会超时
  35. func (c *Conn) SetWriteDeadline(t time.Time) error
  36. //写入json消息
  37. func (c *Conn) WriteJSON(v interface{}) error
  38. //写入消息
  39. func (c *Conn) WriteMessage(messageType int, data []byte) error
  40. // 写入已准备好的消息
  41. func (c *Conn) WritePreparedMessage(pm *PreparedMessage) error

type CloseError

  1. type CloseError struct {
  2. // Code is defined in RFC 6455, section 11.7.
  3. Code int
  4. // Text is the optional text payload.
  5. Text string
  6. }
  7. func (e *CloseError) Error() string

type Dialer

一个拨号器包含连接到WebSocket服务器的选项

  1. type Dialer struct {
  2. // NetDial指定用于创建TCP连接的拨号函数
  3. NetDial func(network, addr string) (net.Conn, error)
  4. // NetDialContext指定用于创建TCP连接的拨号函数
  5. NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error)
  6. // 设定代理,如果代理是nil或返回nil *URL,则不使用代理
  7. Proxy func(*http.Request) (*url.URL, error)
  8. // TLS配置
  9. TLSClientConfig *tls.Config
  10. // 握手超时
  11. HandshakeTimeout time.Duration
  12. // 读取缓冲区大小
  13. ReadBufferSize, WriteBufferSize int
  14. // 写入缓冲区大小
  15. WriteBufferPool BufferPool
  16. // Subprotocols specifies the client's requested subprotocols.
  17. Subprotocols []string
  18. // 开启压缩标志
  19. EnableCompression bool
  20. // 指定cookieJar
  21. Jar http.CookieJar
  22. }

func (d Dialer) Dial(urlStr string, requestHeader http.Header) (Conn, *http.Response, error)

  • 创建一个连接

func (d Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header) (Conn, *http.Response, error)

  • 创建一个连接

type PreparedMessage

PreparedMessage缓存在消息有效负载的连线表示上。使用PreparedMessage有效地向多个连接发送消息有效负载。在使用压缩时,PreparedMessage特别有用,因为CPU和内存昂贵的压缩操作可以对给定的一组压缩选项执行一次

  1. type PreparedMessage struct {
  2. // contains filtered or unexported fields
  3. }

func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error)

type Upgrader

Upgrader指定了将HTTP连接升级为WebSocket连接的参数

  1. type Upgrader struct {
  2. // 握手超时
  3. HandshakeTimeout time.Duration
  4. // 读取缓冲区大小
  5. ReadBufferSize, WriteBufferSize int
  6. // 写入缓冲区大小
  7. WriteBufferPool BufferPool
  8. // Subprotocols specifies the server's supported protocols in order of
  9. // preference. If this field is not nil, then the Upgrade method negotiates a
  10. // subprotocol by selecting the first match in this list with a protocol
  11. // requested by the client. If there's no match, then no protocol is
  12. // negotiated (the Sec-Websocket-Protocol header is not included in the
  13. // handshake response).
  14. Subprotocols []string
  15. // Error specifies the function for generating HTTP error responses. If Error
  16. // is nil, then http.Error is used to generate the HTTP response.
  17. Error func(w http.ResponseWriter, r *http.Request, status int, reason error)
  18. // Origin检测,以防止跨站点请求伪造。
  19. CheckOrigin func(r *http.Request) bool
  20. // 开启压缩标志
  21. EnableCompression bool
  22. }

func (u Upgrader) Upgrade(w http.ResponseWriter, r http.Request, responseHeader http.Header) (*Conn, error) 升级HTTP连接为WebSocket连接

举例

  1. package main
  2. import (
  3. "github.com/gin-gonic/gin"
  4. "github.com/gorilla/websocket"
  5. "net/http"
  6. )
  7. var upGrader = websocket.Upgrader{
  8. CheckOrigin: func (r *http.Request) bool {
  9. return true
  10. },
  11. }
  12. //webSocket请求ping 返回pong
  13. func ping(c *gin.Context) {
  14. //升级get请求为webSocket协议
  15. ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
  16. if err != nil {
  17. return
  18. }
  19. defer ws.Close()
  20. //读取ws中的数据,一定要,单独write会报错
  21. mt, message, err := ws.ReadMessage()
  22. if err != nil {
  23. return
  24. }
  25. // 一次read多次send
  26. for {
  27. message = []byte("test")
  28. //写入ws数据
  29. err = ws.WriteMessage(mt, message)
  30. if err != nil {
  31. break
  32. }
  33. time.Sleep(time.Second)
  34. }
  35. fmt.Println("wesocket 关闭," + ws.RemoteAddr().String())
  36. }
  37. func main() {
  38. bindAddress := "localhost:2303"
  39. r := gin.Default()
  40. r.GET("/ping", ping)
  41. r.Run(bindAddress)
  42. }

image.png