V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
swqslwl
V2EX  ›  Go 编程语言

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

  •  
  •   swqslwl · 2020-09-17 12:45:03 +08:00 · 3173 次点击
    这是一个创建于 1529 天前的主题,其中的信息可能已经有所发展或是发生改变。

    报错有时是 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
    			}
    		}
    	}
    }
    
    11 条回复    2020-09-21 10:48:58 +08:00
    xkeyideal
        1
    xkeyideal  
       2020-09-17 13:48:32 +08:00
    既然楼主大大方方的说要给酬劳了,那么就先说说能给多少吧。
    这段代码呢,在某些环境下没有问题,也看不出问题;但其实槽点慢慢,可以给你一份比较完整的 golang websocket 的处理代码,至于能不能解决你说的问题不清楚,你这种问题个人从来没遇到
    bjt
        2
    bjt  
       2020-09-17 13:57:38 +08:00
    楼主怕是想错了,这个不是丢包,就是网络中断。你本地送出去了并不代表对方能收到。
    est
        3
    est  
       2020-09-17 13:59:24 +08:00
    一般的设计不是解决丢包,而是在承认丢包的前提下再多发几遍。。。
    xx6412223
        4
    xx6412223  
       2020-09-17 14:00:49 +08:00
    先把逻辑写正确吧。还所有连接共用一个错误 channel
    sujin190
        5
    sujin190  
       2020-09-17 14:01:26 +08:00
    你手动这两错误本身就是正常的吧,你这个 for 是死循环的,又没有检查 websocket 连接是否断开的情况,如果前端有异常断开了你再写就会返回这个错误啊,前端断开一般会重连,所以你应该断开后数据就保存再 chan 中,重连之后再往新的连接中写,具体是不是这样和为啥断开不行可以抓包仔细看看
    des
        6
    des  
       2020-09-17 14:03:21 +08:00
    你这两个报错,就是网络连接断开了,不是前端丢包的问题
    joesonw
        7
    joesonw  
       2020-09-17 14:51:56 +08:00
    websocket 协议保证了你收到的 frame 就是完整的没拆开的 frame. 如果丢包了肯定不是代码的问题, 而是库的问题(发送端 /接收端)
    wysnylc
        8
    wysnylc  
       2020-09-17 14:57:16 +08:00
    xdeng
        9
    xdeng  
       2020-09-17 15:47:49 +08:00
    9999 就很不程序员了
    treblex
        10
    treblex  
       2020-09-18 10:53:37 +08:00
    bluetroy
        11
    bluetroy  
       2020-09-21 10:48:58 +08:00
    基于 tcp 协议的协议是不会丢包的。题主在开始编程工作之前应当好好学习计算机基础知识
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1009 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 18:59 · PVG 02:59 · LAX 10:59 · JFK 13:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.