go/conn.go
func (c *conn) connect(w http.ResponseWriter, r *http.Request) error {
	//choose transport
	if r.Header.Get("Accept") == "text/event-stream" {
		c.transport = &eventSourceTransport{writeTimeout: c.state.WriteTimeout}
	} else if r.Header.Get("Upgrade") == "websocket" {
		c.transport = &websocketsTransport{writeTimeout: c.state.WriteTimeout}
	} else {
		return fmt.Errorf("Invalid sync request")
	}
	//non-blocking connect to client over set transport
	if err := c.transport.connect(w, r); err != nil {
		return err
	}
	//initial ping
	if err := c.send(&update{Ping: true}); err != nil {
		return fmt.Errorf("Failed to send initial event")
	}
	//successfully connected
	c.connected = true
	c.waiter.Add(1)
	//while connected, ping loop (every 25s, browser timesout after 30s)
	go func() {
		for {
			select {
			case <-time.After(c.state.PingInterval):
				if err := c.send(&update{Ping: true}); err != nil {
					goto disconnected
				}
			case <-c.connectedCh:
				goto disconnected
			}
		}
	disconnected:
		c.connected = false
		c.Close()
		//unblock waiters
		c.waiter.Done()
	}()
	//non-blocking wait on connection
	go func() {
		if err := c.transport.wait(); err != nil {
			//log error?
		}
		close(c.connectedCh)
	}()
	//now connected, consumer can connection.Wait()
	return nil
}
func (c *conn) connect(w http.ResponseWriter, r *http.Request) error {
	//choose transport
	if r.Header.Get("Accept") == "text/event-stream" {
		c.transport = &eventSourceTransport{writeTimeout: c.state.WriteTimeout}
	} else if r.Header.Get("Upgrade") == "websocket" {
		c.transport = &websocketsTransport{writeTimeout: c.state.WriteTimeout}
	} else {
		return fmt.Errorf("Invalid sync request")
	}
	//non-blocking connect to client over set transport
	if err := c.transport.connect(w, r); err != nil {
		return err
	}
	//initial ping
	if err := c.send(&update{Ping: true}); err != nil {
		return fmt.Errorf("Failed to send initial event")
	}
	//successfully connected
	c.connected = true
	c.waiter.Add(1)
	//while connected, ping loop (every 25s, browser timesout after 30s)
	go func() {
		for {
			select {
			case <-time.After(c.state.PingInterval):
				if err := c.send(&update{Ping: true}); err != nil {
					goto disconnected
				}
			case <-c.connectedCh:
				goto disconnected
			}
		}
	disconnected:
		c.connected = false
		c.Close()
		//unblock waiters
		c.waiter.Done()
	}()
	//non-blocking wait on connection
	go func() {
		if err := c.transport.wait(); err != nil {
			//log error?
		}
		close(c.connectedCh)
	}()
	//now connected, consumer can connection.Wait()
	return nil
}
//connect using the provided transport
//and block until connection is ready