查看了一下官方实现里面write方法在结束的时候调用了close方法,但是read没有。

我对官方这个实现非常费解,因为websocket就是为了长连接而使用的啊,既然发送或者接收一次消息之后就关闭,这样编写的意图是什么?

type Conn struct {
    config  *Config
    request *http.Request

    buf *bufio.ReadWriter
    rwc io.ReadWriteCloser

    rio sync.Mutex
    frameReaderFactory
    frameReader

    wio sync.Mutex
    frameWriterFactory

    frameHandler
    PayloadType        byte
    defaultCloseStatus int

    // MaxPayloadBytes limits the size of frame payload received over Conn
    // by Codec's Receive method. If zero, DefaultMaxPayloadBytes is used.
    MaxPayloadBytes int
}

// Read implements the io.Reader interface:
// it reads data of a frame from the WebSocket connection.
// if msg is not large enough for the frame data, it fills the msg and next Read
// will read the rest of the frame data.
// it reads Text frame or Binary frame.
func (ws *Conn) Read(msg []byte) (n int, err error) {
    ws.rio.Lock()
    defer ws.rio.Unlock()
again:
    if ws.frameReader == nil {
        frame, err := ws.frameReaderFactory.NewFrameReader()
        if err != nil {
            return 0, err
        }
        ws.frameReader, err = ws.frameHandler.HandleFrame(frame)
        if err != nil {
            return 0, err
        }
        if ws.frameReader == nil {
            goto again
        }
    }
    n, err = ws.frameReader.Read(msg)
    if err == io.EOF {
        if trailer := ws.frameReader.TrailerReader(); trailer != nil {
            io.Copy(ioutil.Discard, trailer)
        }
        ws.frameReader = nil
        goto again
    }
    return n, err
}

// Write implements the io.Writer interface:
// it writes data as a frame to the WebSocket connection.
func (ws *Conn) Write(msg []byte) (n int, err error) {
    ws.wio.Lock()
    defer ws.wio.Unlock()
    w, err := ws.frameWriterFactory.NewFrameWriter(ws.PayloadType)
    if err != nil {
        return 0, err
    }
    n, err = w.Write(msg)
    w.Close()
    return n, err
}

// Close implements the io.Closer interface.
func (ws *Conn) Close() error {
    err := ws.frameHandler.WriteClose(ws.defaultCloseStatus)
    err1 := ws.rwc.Close()
    if err != nil {
        return err
    }
    return err1
}