【websocket】怎么终止websocket断开重连

介绍

代码是用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,再关闭连接。顺序最好别错。

相关推荐
cocoCola916672 小时前
validator库参数校验若干实用技巧
go
不会C语言的男孩3 小时前
第三章:流程控制
go
宠友信息5 小时前
MySQL复合索引与Druid优化仿小红书源码个人主页查询链路
数据库·spring boot·websocket·mysql·uni-app
cocoCola9166711 小时前
用户模块讲义
go
程序猿乐锅12 小时前
【苍穹外卖 day10|Spring Task、WebSocket 与来单提醒、催单铃声实现】
java·websocket·spring
Sinclair1 天前
安企CMS的安装-源码编译安装
运维·后端·go
wear工程师1 天前
Go 的 map 并发读写,面试里别上来就答「sync.Map」
面试·go
宠友信息1 天前
消息撤回与已读状态如何在即时通讯源码中统一管理
java·spring boot·websocket·mysql·uni-app
HokKeung2 天前
用 Cobra 写一个像样的 Go 命令行工具
go·命令行
黑贝是条狗2 天前
一个从零到一,全部由AI实现的开放平台
go·ai vibe coding