gorilla/websocket
go get github.com/gorilla/websocket
Upgrader
Upgrader
指定用于将 HTTP 连接升级到 WebSocket 连接
type Upgrader struct {
HandshakeTimeout time.Duration
ReadBufferSize, WriteBufferSize int
WriteBufferPool BufferPool
Subprotocols []string
Error func(w http.ResponseWriter, r *http.Request, status int, reason error)
CheckOrigin func(r *http.Request) bool
EnableCompression bool
}
HandshakeTimeout:
握手完成的持续时间ReadBufferSize
和WriteBufferSize
:以字节为单位指定I/O缓冲区大小。如果缓冲区大小为零,则使用HTTP服务器分配的缓冲区CheckOrigin
: 函数应仔细验证请求来源 防止跨站点请求伪造
这里一般会设置下CheckOrigin来解决跨域问题,也可以var upgrader = websocket.Upgrader{} // use default options
使用默认配置。
Conn
Conn
类型表示WebSocket连接,这个结构体的组成包括两部分,写入字段(Write fields)和 读取字段(Read fields)
type Conn struct {
conn net.Conn
isServer bool
...
// Write fields
writeBuf []byte
writePool BufferPool
writeBufSize int
writer io.WriteCloser
isWriting bool
...
// Read fields
readRemaining int64
readFinal bool
readLength int64
messageReader *messageReader
...
}
isServer
字段来区分我们是否用Conn作为客户端还是服务端,也就是说说gorilla/websocket中同时编写客户端程序和服务器程序,但是一般是Web应用程序使用单独的前端作为客户端程序。
服务端示例
以gin框架为例
var upgrader = websocket.Upgrader{} // use default options
func main() {
route := gin.Default()
router.GET("/ws", func(c *gin.Context) {
wsHandler(c.Writer, c.Request)
})
route.Run("localhost:8080")
}
func wsHandler(w http.ResponseWriter, r *http.Request) {
//转换为升级为websocket
conn, err := upGrader.Upgrade(w, r, nil)
//释放连接
defer conn.Close()
for {
//接收消息
messageType, message, err := conn.ReadMessage()
log.Println("server receive messageType", messageType, "message", string(message))
//发送消息
err = conn.WriteMessage(messageType, []byte("pong"))
}
}
客户端示例
以gin框架为例
//服务器地址 websocket 统一使用 ws://
url := "ws://localhost:8080/ws"
//使用默认拨号器,向服务器发送连接请求
conn, _, err := websocket.DefaultDialer.Dial(url, nil)
//关闭连接
defer conn.Close()
//发送消息
go func() {
for {
err := conn.WriteMessage(websocket.BinaryMessage, []byte("ping"))
time.Sleep(time.Second * 2)
}
}()
//接收消息
for {
_, data, err := conn.ReadMessage()
fmt.Println("client receive message: ", string(data))
}