blob: 314c07a2ba21d79517bd493c59fb263891ad4005 [file] [log] [blame]
package websocket
import (
"net"
"time"
"veyron.io/veyron/veyron2/ipc/stream"
)
var mapWebSocketToTCP = map[string]string{"ws": "tcp", "ws4": "tcp4", "ws6": "tcp6"}
func wsListener(protocol, address string) (net.Listener, error) {
tcp := mapWebSocketToTCP[protocol]
ln, err := net.Listen(tcp, address)
if err != nil {
return nil, err
}
return NewListener(ln)
}
func wsDialer(protocol, address string, timeout time.Duration) (net.Conn, error) {
// TODO(cnicolaou): implement timeout support.
return Dial(address)
}
func init() {
// ws, ws4, ws6 represent websocket protocol instances.
for _, p := range []string{"ws", "ws4", "ws6"} {
stream.RegisterProtocol(p, wsDialer, wsListener)
}
// TODO(cnicolaou): fully enable and test this 'hybrid mode'.
// hws, hws4, hws6 represent a 'hybrid' protocol that can accept
// both websockets and tcp, using a 'magic' byte to discriminate
// between the two. These are needed when a single network port must
// be use to serve both websocket and tcp clients, we prefer to use
// tcp whenever we can to avoid the overhead of websockets. Clients
// decide whether to use hybrid tcp or websockets by electing to dial
// using the hws protocol or the ws protocol respectively.
//for _, p := range []string{"wsh", "wsh4", "wsh6"} {
// stream.RegisterProtocol(p, tcpHybridDialer, wsHybridListener)
//}
// The implementation strategy is as follows:
// tcpHybridDialer will create and return a wrapped net.Conn which will
// write the 'magic' time the first time that its Write method is called
// but will otherwise be indistinguishable from the underlying net.Conn.
// This first write will require an extra copy, but avoid potentially
// sending two packets.
// wsHybridListener is essentially the same as the current wsTCPListener,
// but the magic byte handling implemented on a conditional basis.
}
/*
func dialer(network, address string, timeout time.Duration) (net.Conn, error) {
conn, err := net.DialTimeout(network, address, timeout)
if err != nil {
return nil, err
}
// For tcp connections we add an extra magic byte so we can differentiate between
// raw tcp and websocket on the same port.
switch n, err := conn.Write([]byte{websocket.BinaryMagicByte}); {
case err != nil:
return nil, err
case n != 1:
return nil, fmt.Errorf("Unable to write the magic byte")
}
return conn, nil
}
}
*/