介绍
代码是用go语言实现的。go语言实现websocket,常用第三方库github.com/gorilla/websocket。
不过只要明白了思路,不管哪个语言实现起来都是一样的。
问题
在生产环境,websocket客户端一般都会实现断开重连的逻辑,如果直接通过Conn.Close()函数关闭连接会触发重连。
怎么终止websocket重连呢?
解决方式
这是一段websocket客户端的实现代码,实现了终止重连的功能。
Go
package test
import (
"fmt"
"testing"
"time"
"github.com/gorilla/websocket"
)
type Session struct {
Conn *websocket.Conn
Url string
IsStop bool
}
// NewSession 创建会话
func NewSession(url string) *Session {
return &Session{
Url: url,
}
}
// Start 开始会话
// 创建websocket连接,支持失败重连
func (s *Session) Start() {
for !s.IsStop {
// for {
conn, _, err := websocket.DefaultDialer.Dial(s.Url, nil)
if err != nil {
// 2s后重连
time.Sleep(2 * time.Second)
continue
}
fmt.Println("连接成功")
s.Conn = conn
for {
messageType, message, err := conn.ReadMessage()
if err != nil {
fmt.Println("读取失败:", err)
break
}
switch messageType {
case websocket.TextMessage:
// 处理消息
fmt.Println("message:", string(message))
}
}
if !s.IsStop {
return
}
// 2s后重连
time.Sleep(2 * time.Second)
}
}
// Close 关闭会话
// 关闭websocket连接
func (s *Session) Close() {
fmt.Println("关闭连接")
s.IsStop = true
if s.Conn != nil {
s.Conn.Close()
}
}
// 测试代码
func TestSession(t *testing.T) {
var session *Session
go func() {
url := "ws://127.0.0.1:7776"
session = NewSession(url)
session.Start()
fmt.Println("连接已关闭")
}()
time.Sleep(10 * time.Second)
session.Close()
time.Sleep(20 * time.Second)
}
用Session结构体及其方法来封装websocket连接和关闭,并在结构体中添加了IsStop属性,作为是否要关闭连接,不再重连的标识。
把IsStop作为外层for循环的判断条件,当调用Conn.Close()函数关闭连接的时候,conn.ReadMessage()会中断阻塞,并返回一个error,我们捕捉到error会跳到外层循环,只要我们把IsStop设置为true,外层循环就会终止,结束重连逻辑。
在Session.Close()方法中,先把IsStop设置为true,再关闭连接。顺序最好别错。