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