github.com/gin-gonic/gin nhooyr.io/websocket github.com/docker/docker/client文件目录
├── docker │ ├── conn.go │ └── conn_test.go ├── go.mod ├── go.sum ├── html │ └── index.html └── main.go静态页面
代码展示
Title
>${ msgn }
前端 WebSocket 的核心是构造函数和几个回调函数。
- new WebSocket:创建一个 WebSocket 实例,提供服务端的 ws 地址,地址可以跟 HTTP 协议一样,加上请求参数。注意,如果你使用 HTTPS 协议,相应的 WebSocket 地址协议要改为 wss;
- WebSocket.onopen:用于指定连接成功后的回调函数;
- WebSocket.onerror:用于指定连接失败后的回调函数;
- WebSocket.onmessage:用于指定当从服务器接收到信息时的回调函数;
- WebSocket.onclose:用于指定连接关闭后的回调函数;
在用户点击进入聊天室时,根据 Vue 绑定的事件,会执行上面的代码,发起 WebSocket 连接,服务端会将相关信息通过 WebSocket 长连接返回给客户端,客户端通过 WebSocket.onmessage 回调进行处理。
得益于 Vue 的双向绑定,在数据显示、事件绑定等方面,处理起来很方便。
关于前端的实现,这里有几点提醒下读者:
- Vue 默认的分隔符是 {{}},和 Go 的一样,避免冲突进行了修改;
- WebSocket 有两个方法:send 和 close,一个用来发送消息,一个用于主动断开链接;
代码展示
获取容器日志(conn.go)
package docker
import (
"context"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"io"
"log"
)
func Conn() io.Reader {
//创建连接
client, err := client.NewClientWithOpts(client.WithHost("tcp://10.0.0.20:2375"))
if err != nil {
log.Println(err)
}
//使用连接获取容器日志,返回一个io.Reader
logs, err := client.ContainerLogs(context.TODO(), "xenodochial_blackburn", types.ContainerLogsOptions{
ShowStdout: true,
ShowStderr: true,
Follow: true,
})
return logs
}
方法 client.ContainerLogs(ctx context.Context, container string, options types.ContainerLogsOptions)返回一个io.Reader和错误,第一个参数为上下文,第二个参数为容器id或者容器名称,第三个参数是容器日志选项结构体,
type ContainerLogsOptions struct {
ShowStdout bool // 是否返回日志从stdout 默认false
ShowStderr bool // 是否返回日志从stderr 默认false
Since string // 从这个时间返回日志,时间类型为unix timestamp
Until string // 返回这个时间前的日志,时间类型为unix timestamp
Timestamps bool // 是否在日志行前显示时间戳,默认false
Follow bool // 是否返回日志流,默认false
Tail string // 返回日志行数,默认为all
Details bool
}
main.go
package main
import (
"bufio"
"github.com/gin-gonic/gin"
"kuludi-websocket/docker"
"log"
"net/http"
"nhooyr.io/websocket"
"nhooyr.io/websocket/wsjson"
)
func main() {
r := gin.Default()
r.LoadHTMLGlob("html/*")
r.GET("/", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", nil)
})
r.GET("/ws", func(c *gin.Context) {
//创建websocker连接
conn, err := websocket.Accept(c.Writer, c.Request, nil)
if err != nil {
log.Println("websocket accept error: ", err)
return
}
//获取容器日志的io.Reader
reader := docker.Conn()
//bufio新建Reader
r := bufio.NewReader(reader)
for {
//循环从reader中根据换行符读取并转换为string
s, err := r.ReadString('n')
if err != nil {
log.Println("read err: ", err)
}
//发送数据
err = wsjson.Write(c.Request.Context(), conn, &s)
if err != nil {
log.Println("wsjson.writer err: ", err)
}
}
})
r.Run()
}
访问测试
访问http://localhost:8080



