func() interface{} { return bufio.NewReaderSize(nil, BufSize) }, } func (s Server) serveWebSocket(w http.ResponseWriter, req *http.Request) { rwc, _, err := w.(http.Hijacker).Hijack() rb := readBufPool.Get().(*bufio.Reader) wb := writeBufPool.Get().(*bufio.Writer) rb.Reset(rwc) wb.Reset(rwc) buf := bufio.NewReadWriter(rb, wb) conn, err := newServerConn(rwc, buf, req, &s.Config, s.Handshake) …… conn = newHybiConn(&s.Config, buf, rwc, req) go func() { s.Handler(conn) rwc.Close() readBufPool.Put(rb) }() 在s.Handler函数中,先设置⼼跳定时器,登录,启⼀个 读协程,本协程进⾏写操作。 func (sess *session) Serve() { // 设置⼼跳超时定时器…... go sess.SignIn() // 登录 <-sess.signInDone if sess.id == 0 { goto done } if sess.s.opts.Debug || sess.debug { log.Infof(“sess: sign in success, %s”, sess) } sess.resetHB() sess.s.putSession(sess) go sess.loopRead() // 读协程 sess.loopWrite() // 写协程 done: sess.clean() } 注:读协程会⼀直使⽤传⼊的bufio.Reader。 虽然读协程和写协程使⽤了同步设施,保证有⼀⽅退出, 另⼀⽅也会退出,但不保证退出的时序。 如果本协程(写协程)先退出,会先将rb归还到sync.pool, ⽽读协程可能还在使⽤rb对象,就会产⽣Race Condition。