问答详情
源自:4-3 封装Websocket

单独一个websocket为什么会有线程安全问题?当有多个websocket连接的时候那个inchan和outchan是大家共用一个还是每人一个?

type Connection struct {

conn    *websocket.Conn

inChan  chan *Message

outChan chan *Message


mutex     sync.Mutex

closeChan chan byte

}



提问者:weixin_慕函数13881 2020-02-11 11:42

个回答

  • 慕标1126391
    2020-06-19 15:24:58

    1、一个连接建立后,3个协成是同一个结构体变量的方法,该结构体中的属性在3个协成中可见可操作。因为结构体的方法是引用传值【func (wsConn *wsConnection)】

    2、不是共用的,每个连接都是创建了一个局部结构体变量保存数据和方法调用。连接间没有共用数据。

    希望小鱼儿老师看看我理解的是否有偏差呢

    作者的程序是服务端启动后,就会监听一个端口等待客户端连接,每来一个客户端就会在wsHandler处理函数中

    建立连接。并使用局部结构体变量wsConn包含了连接和读写管道,读写管道和这个通信长连接都在这个局部结构体变量中,启动的处理、读、写协成都是调用的该结构体方法。且需引用传值,保证操作的是同一个地址空间,同一个结构体变量。

    打开多个客户端网页,会产生多个连接,每个连接对应自己的客户端。每个连接的处理都在自己的结构体方法中完成。从客户端发送消息,服务端读到什么再发回给对应客户端,不会跑到别的客户端网页上。

    如果服务端想给所有客户端群发消息,可以将wsConn局部变量保存在一个全局数组中或者redis等存储介质中,

    遍历所有连接发送数据。

    如果将读 写管道换成全局变量,某个客户端发送数据被对应连接协成放入到inchan管道后,会随机被某个连接的协成读取并放入全局outchan管道中,再被该连接的协成从outchan管道取走发送给该连接对应客户端。


  • 芒果和芒果柠檬
    2020-02-28 14:40:33

    个人理解

    原来的websocket的话,每来一个请求都会调用同一个conn对象writeMessage应答,此时会竞争写writeMessage发消息的缓冲区内容。就会有线程安全问题

    第二个问题的话。共用一个。因为用channel的话,确保每次我只处理一个消息(channel相当于一个管道,一个个投递数据,一个个处理)