diff --git a/conn.go b/conn.go index 2678e6d..1af4474 100644 --- a/conn.go +++ b/conn.go @@ -63,12 +63,12 @@ var errDeadlineReached = &deadlineErr{} // Dial opens a new WebSocket connection. It will block until the connection is // established or fails to connect. -func Dial(url string) (*Conn, error) { +func Dial(url string) (net.Conn, error) { ws, err := New(url) if err != nil { return nil, err } - conn := &Conn{ + conn := &conn{ WebSocket: ws, ch: make(chan *messageEvent, 1), } @@ -105,11 +105,8 @@ func Dial(url string) (*Conn, error) { return conn, nil } -// Conn is a high-level wrapper around WebSocket. It is intended to satisfy the -// net.Conn interface. -// -// To create a Conn, use Dial. Instantiating Conn without Dial will not work. -type Conn struct { +// conn is a high-level wrapper around WebSocket. It implements net.Conn interface. +type conn struct { *WebSocket ch chan *messageEvent @@ -123,13 +120,13 @@ type messageEvent struct { Data *js.Object `js:"data"` } -func (c *Conn) onMessage(event *js.Object) { +func (c *conn) onMessage(event *js.Object) { go func() { c.ch <- &messageEvent{Object: event} }() } -func (c *Conn) onClose(event *js.Object) { +func (c *conn) onClose(event *js.Object) { go func() { // We queue nil to the end so that any messages received prior to // closing get handled first. @@ -137,10 +134,10 @@ func (c *Conn) onClose(event *js.Object) { }() } -// initialize adds all of the event handlers necessary for a Conn to function. +// initialize adds all of the event handlers necessary for a conn to function. // It should never be called more than once and is already called if Dial was -// used to create the Conn. -func (c *Conn) initialize() { +// used to create the conn. +func (c *conn) initialize() { // We need this so that received binary data is in ArrayBufferView format so // that it can easily be read. c.BinaryType = "arraybuffer" @@ -151,7 +148,7 @@ func (c *Conn) initialize() { // handleFrame handles a single frame received from the channel. This is a // convenience funciton to dedupe code for the multiple deadline cases. -func (c *Conn) handleFrame(message *messageEvent, ok bool) (*messageEvent, error) { +func (c *conn) handleFrame(message *messageEvent, ok bool) (*messageEvent, error) { if !ok { // The channel has been closed return nil, io.EOF } else if message == nil { @@ -165,7 +162,7 @@ func (c *Conn) handleFrame(message *messageEvent, ok bool) (*messageEvent, error // receiveFrame receives one full frame from the WebSocket. It blocks until the // frame is received. -func (c *Conn) receiveFrame(observeDeadline bool) (*messageEvent, error) { +func (c *conn) receiveFrame(observeDeadline bool) (*messageEvent, error) { var deadlineChan <-chan time.Time // Receiving on a nil channel always blocks indefinitely if observeDeadline && !c.readDeadline.IsZero() { @@ -196,14 +193,13 @@ func (c *Conn) receiveFrame(observeDeadline bool) (*messageEvent, error) { func getFrameData(obj *js.Object) []byte { // Check if it's an array buffer. If so, convert it to a Go byte slice. if constructor := obj.Get("constructor"); constructor == js.Global.Get("ArrayBuffer") { - int8Array := js.Global.Get("Uint8Array").New(obj) - return int8Array.Interface().([]byte) + uint8Array := js.Global.Get("Uint8Array").New(obj) + return uint8Array.Interface().([]byte) } - return []byte(obj.String()) } -func (c *Conn) Read(b []byte) (n int, err error) { +func (c *conn) Read(b []byte) (n int, err error) { if c.readBuf != nil { n, err = c.readBuf.Read(b) if err == io.EOF { @@ -237,42 +233,30 @@ func (c *Conn) Read(b []byte) (n int, err error) { } // Write writes the contents of b to the WebSocket using a binary opcode. -func (c *Conn) Write(b []byte) (n int, err error) { - // []byte is converted to an (U)Int8Array by GopherJS, which fullfils the +func (c *conn) Write(b []byte) (n int, err error) { + // []byte is converted to an Uint8Array by GopherJS, which fullfils the // ArrayBufferView definition. err = c.Send(b) if err != nil { - return - } - n = len(b) - return -} - -// WriteString writes the contents of s to the WebSocket using a text frame -// opcode. -func (c *Conn) WriteString(s string) (n int, err error) { - err = c.Send(s) - if err != nil { - return + return 0, err } - n = len(s) - return + return len(b), nil } // LocalAddr would typically return the local network address, but due to // limitations in the JavaScript API, it is unable to. Calling this method will // cause a panic. -func (c *Conn) LocalAddr() net.Addr { - // BUG(nightexcessive): Conn.LocalAddr() panics because the underlying +func (c *conn) LocalAddr() net.Addr { + // BUG(nightexcessive): conn.LocalAddr() panics because the underlying // JavaScript API has no way of figuring out the local address. // TODO(nightexcessive): Find a more graceful way to handle this - panic("we are unable to implement websocket.Conn.LocalAddr() due to limitations in the underlying JavaScript API") + panic("we are unable to implement websocket.conn.LocalAddr() due to limitations in the underlying JavaScript API") } // RemoteAddr returns the remote network address, based on // websocket.WebSocket.URL. -func (c *Conn) RemoteAddr() net.Addr { +func (c *conn) RemoteAddr() net.Addr { wsURL, err := url.Parse(c.URL) if err != nil { // TODO(nightexcessive): Should we be panicking for this? @@ -285,20 +269,20 @@ func (c *Conn) RemoteAddr() net.Addr { // It is equivalent to calling both SetReadDeadline and SetWriteDeadline. // // A zero value for t means that I/O operations will not time out. -func (c *Conn) SetDeadline(t time.Time) error { +func (c *conn) SetDeadline(t time.Time) error { c.readDeadline = t return nil } // SetReadDeadline sets the deadline for future Read calls. A zero value for t // means Read will not time out. -func (c *Conn) SetReadDeadline(t time.Time) error { +func (c *conn) SetReadDeadline(t time.Time) error { c.readDeadline = t return nil } // SetWriteDeadline sets the deadline for future Write calls. Because our writes // do not block, this function is a no-op. -func (c *Conn) SetWriteDeadline(t time.Time) error { +func (c *conn) SetWriteDeadline(t time.Time) error { return nil }