func Dial(url string) (net.Conn, error) {
	ws, err := websocketjs.New(url)
	if err != nil {
		return nil, err
	}
	conn := &conn{
		WebSocket: ws,
		ch:        make(chan *messageEvent, 1),
	}
	conn.initialize()
	openCh := make(chan error, 1)
	var (
		openHandler  func(ev *js.Object)
		closeHandler func(ev *js.Object)
	)
	removeHandlers := func() {
		ws.RemoveEventListener("open", false, openHandler)
		ws.RemoveEventListener("close", false, closeHandler)
	}
	openHandler = beginHandlerOpen(openCh, removeHandlers)
	closeHandler = beginHandlerClose(openCh, removeHandlers)
	ws.AddEventListener("open", false, openHandler)
	ws.AddEventListener("close", false, closeHandler)
	err, ok := <-openCh
	if ok && err != nil {
		return nil, err
	}
	return conn, nil
}
TODO(nightexcessive): Add a Dial function that allows a deadline to be
specified.
Dial opens a new WebSocket connection. It will block until the connection is
established or fails to connect.
package websocket
import (
	"bytes"
	"fmt"
	"io"
	"net"
	"net/url"
	"time"
	"github.com/gopherjs/gopherjs/js"
	"github.com/gopherjs/websocket/websocketjs"
)
func beginHandlerOpen(ch chan error, removeHandlers func()) func(ev *js.Object) {
	return func(ev *js.Object) {
		removeHandlers()
		close(ch)
	}
}
type closeError struct {
	*js.Object
	Code     int    `js:"code"`
	Reason   string `js:"reason"`
	WasClean bool   `js:"wasClean"`
}
func (e *closeError) Error() string {
	var cleanStmt string
	if e.WasClean {
		cleanStmt = "clean"
	} else {
		cleanStmt = "unclean"
	}
	return fmt.Sprintf("CloseEvent: (%s) (%d) %s", cleanStmt, e.Code, e.Reason)
}
func beginHandlerClose(ch chan error, removeHandlers func()) func(ev *js.Object) {
	return func(ev *js.Object) {
		removeHandlers()
		go func() {
			ch <- &closeError{Object: ev}
			close(ch)
		}()
	}
}
type deadlineErr struct{}
func (e *deadlineErr) Error() string   { return "i/o timeout: deadline reached" }
func (e *deadlineErr) Timeout() bool   { return true }
func (e *deadlineErr) Temporary() bool { return true }
var errDeadlineReached = &deadlineErr{}