golang 使用 websocket 发送数据给前端,总是会有丢包的情况发生

2020-09-17 12:45:03 +08:00
 swqslwl

报错有时是 write:broken pipe. 有时是 An established connection was aborted by the software in your host machine. 有时不报错,wrieshark 抓包发现包全部发出去了,但前端就是会丢包。

上个帖子犯了个低级错误用了共享内存变量,现在改为用 channel 了,想知道是不是还是我后端代码的问题。

如果有提供很大帮助思路的,小弟可以给予一定的酬谢。

var dataTmp = make(chan []byte, 9999)
var t = make(chan []byte, 9999)

var upgrader = websocket.Upgrader{
	//	ReadBufferSize: 1024,
	WriteBufferSize: 1024,
	// 允许所有的 CORS 跨域请求,正式环境可以关闭
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

func init() {
	http.HandleFunc("/ws", wsHandler)
	go http.ListenAndServe("173.10.10.100:88", nil)
}

func wsHandler(resp http.ResponseWriter, req *http.Request) {
	// 答客户端告知升级连接为 websocket
	wsSocket, err := upgrader.Upgrade(resp, req, nil)
	if err != nil {
		fmt.Println("升级为 websocket 失败", err.Error())
		return
	}
	go wsWriteLoop(wsSocket)
}

// 发送消息给客户端
func wsWriteLoop(wsConn *websocket.Conn) {
	for {
		select {
		case terror := <-t:
			fmt.Println("错误重新发送")
			fmt.Println(terror)
			err := wsConn.WriteMessage(websocket.TextMessage, terror)
			if err != nil {
				fmt.Println("再次发送", err.Error())
				t <- terror
				return
			}

		case tmp := <-dataTmp:
			err := wsConn.WriteMessage(websocket.TextMessage, tmp)
			if err != nil {
				fmt.Println("发送消息给客户端发生错误", err.Error())
				t <- tmp
				return
			}
		}
	}
}
3198 次点击
所在节点    Go 编程语言
11 条回复
xkeyideal
2020-09-17 13:48:32 +08:00
既然楼主大大方方的说要给酬劳了,那么就先说说能给多少吧。
这段代码呢,在某些环境下没有问题,也看不出问题;但其实槽点慢慢,可以给你一份比较完整的 golang websocket 的处理代码,至于能不能解决你说的问题不清楚,你这种问题个人从来没遇到
bjt
2020-09-17 13:57:38 +08:00
楼主怕是想错了,这个不是丢包,就是网络中断。你本地送出去了并不代表对方能收到。
est
2020-09-17 13:59:24 +08:00
一般的设计不是解决丢包,而是在承认丢包的前提下再多发几遍。。。
xx6412223
2020-09-17 14:00:49 +08:00
先把逻辑写正确吧。还所有连接共用一个错误 channel
sujin190
2020-09-17 14:01:26 +08:00
你手动这两错误本身就是正常的吧,你这个 for 是死循环的,又没有检查 websocket 连接是否断开的情况,如果前端有异常断开了你再写就会返回这个错误啊,前端断开一般会重连,所以你应该断开后数据就保存再 chan 中,重连之后再往新的连接中写,具体是不是这样和为啥断开不行可以抓包仔细看看
des
2020-09-17 14:03:21 +08:00
你这两个报错,就是网络连接断开了,不是前端丢包的问题
joesonw
2020-09-17 14:51:56 +08:00
websocket 协议保证了你收到的 frame 就是完整的没拆开的 frame. 如果丢包了肯定不是代码的问题, 而是库的问题(发送端 /接收端)
wysnylc
2020-09-17 14:57:16 +08:00
xdeng
2020-09-17 15:47:49 +08:00
9999 就很不程序员了
treblex
2020-09-18 10:53:37 +08:00
bluetroy
2020-09-21 10:48:58 +08:00
基于 tcp 协议的协议是不会丢包的。题主在开始编程工作之前应当好好学习计算机基础知识

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/707885

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX