mirror of
https://github.com/golang/go.git
synced 2024-09-30 06:47:04 +00:00
websocket: add mutex to make websocket full-duplex
One benefit of websocket is that it is full-duplex so that it could send and receive at the same time. This CL makes websocket goroutine safe, so user could use websocket both on goroutine for read and on goroutine for write. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/5058043
This commit is contained in:
parent
3dc3fa0d8c
commit
e4790b5fa4
@ -235,6 +235,8 @@ func (handler *hixiFrameHandler) HandleFrame(frame frameReader) (r frameReader,
|
||||
}
|
||||
|
||||
func (handler *hixiFrameHandler) WriteClose(_ int) (err os.Error) {
|
||||
handler.conn.wio.Lock()
|
||||
defer handler.conn.wio.Unlock()
|
||||
closingFrame := []byte{'\xff', '\x00'}
|
||||
handler.conn.buf.Write(closingFrame)
|
||||
return handler.conn.buf.Flush()
|
||||
|
@ -288,6 +288,8 @@ func (handler *hybiFrameHandler) HandleFrame(frame frameReader) (r frameReader,
|
||||
}
|
||||
|
||||
func (handler *hybiFrameHandler) WriteClose(status int) (err os.Error) {
|
||||
handler.conn.wio.Lock()
|
||||
defer handler.conn.wio.Unlock()
|
||||
w, err := handler.conn.frameWriterFactory.NewFrameWriter(CloseFrame)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -300,6 +302,8 @@ func (handler *hybiFrameHandler) WriteClose(status int) (err os.Error) {
|
||||
}
|
||||
|
||||
func (handler *hybiFrameHandler) WritePong(msg []byte) (n int, err os.Error) {
|
||||
handler.conn.wio.Lock()
|
||||
defer handler.conn.wio.Unlock()
|
||||
w, err := handler.conn.frameWriterFactory.NewFrameWriter(PongFrame)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"json"
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"url"
|
||||
)
|
||||
|
||||
@ -147,9 +148,11 @@ type Conn struct {
|
||||
buf *bufio.ReadWriter
|
||||
rwc io.ReadWriteCloser
|
||||
|
||||
rio sync.Mutex
|
||||
frameReaderFactory
|
||||
frameReader
|
||||
|
||||
wio sync.Mutex
|
||||
frameWriterFactory
|
||||
|
||||
frameHandler
|
||||
@ -163,6 +166,8 @@ type Conn struct {
|
||||
// will read the rest of the frame data.
|
||||
// it reads Text frame or Binary frame.
|
||||
func (ws *Conn) Read(msg []byte) (n int, err os.Error) {
|
||||
ws.rio.Lock()
|
||||
defer ws.rio.Unlock()
|
||||
again:
|
||||
if ws.frameReader == nil {
|
||||
frame, err := ws.frameReaderFactory.NewFrameReader()
|
||||
@ -191,6 +196,8 @@ again:
|
||||
// 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 os.Error) {
|
||||
ws.wio.Lock()
|
||||
defer ws.wio.Unlock()
|
||||
w, err := ws.frameWriterFactory.NewFrameWriter(ws.PayloadType)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@ -279,6 +286,8 @@ func (cd Codec) Send(ws *Conn, v interface{}) (err os.Error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ws.wio.Lock()
|
||||
defer ws.wio.Unlock()
|
||||
w, err := ws.frameWriterFactory.NewFrameWriter(payloadType)
|
||||
_, err = w.Write(data)
|
||||
w.Close()
|
||||
@ -287,6 +296,8 @@ func (cd Codec) Send(ws *Conn, v interface{}) (err os.Error) {
|
||||
|
||||
// Receive receives single frame from ws, unmarshaled by cd.Unmarshal and stores in v.
|
||||
func (cd Codec) Receive(ws *Conn, v interface{}) (err os.Error) {
|
||||
ws.rio.Lock()
|
||||
defer ws.rio.Unlock()
|
||||
if ws.frameReader != nil {
|
||||
_, err = io.Copy(ioutil.Discard, ws.frameReader)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user