gosocketio/vendor/github.com/googollee/go-socket.io/engineio/dialer.go

85 lines
1.4 KiB
Go

package engineio
import (
"errors"
"io"
"net/http"
"net/url"
"github.com/googollee/go-socket.io/engineio/packet"
"github.com/googollee/go-socket.io/engineio/transport"
)
// Dialer is dialer configure.
type Dialer struct {
Transports []transport.Transport
}
// Dial returns a connection which dials to url with requestHeader.
func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (Conn, error) {
u, err := url.Parse(urlStr)
if err != nil {
return nil, err
}
query := u.Query()
query.Set("EIO", "3")
u.RawQuery = query.Encode()
var conn transport.Conn
for i := len(d.Transports) - 1; i >= 0; i-- {
if conn != nil {
conn.Close()
}
t := d.Transports[i]
conn, err = t.Dial(u, requestHeader)
if err != nil {
continue
}
var params transport.ConnParameters
if p, ok := conn.(Opener); ok {
params, err = p.Open()
if err != nil {
continue
}
} else {
var pt packet.Type
var r io.ReadCloser
_, pt, r, err = conn.NextReader()
if err != nil {
continue
}
func() {
defer r.Close()
if pt != packet.OPEN {
err = errors.New("invalid open")
return
}
params, err = transport.ReadConnParameters(r)
if err != nil {
return
}
}()
}
if err != nil {
continue
}
ret := &client{
conn: conn,
params: params,
transport: t.Name(),
close: make(chan struct{}),
}
go ret.serve()
return ret, nil
}
return nil, err
}