package main import ( "net" "time" ) // Connection represents a network socket. type Connection struct { dialer net.Dialer socket net.Conn connectTimeout time.Duration sendTimeout time.Duration recvTimeout time.Duration protocol string } func init() { registerParam("connect-timeout-ms", 3000, "") registerParam("send-timeout-ms", 2000, "") registerParam("recv-timeout-ms", 1000, "") } // NewConnection creates a Connection object and optionally connects to an Endpoint. func NewConnection(endpoint *Endpoint) (*Connection, error) { conn := Connection{} conn.connectTimeout = getParamDurationMS("connect-timeout-ms") conn.sendTimeout = getParamDurationMS("send-timeout-ms") conn.recvTimeout = getParamDurationMS("recv-timeout-ms") conn.protocol = "tcp" if endpoint != nil { return &conn, conn.Connect(endpoint) } else { return &conn, nil } } func (conn *Connection) Close() { if conn.socket != nil { conn.socket.Close() conn.socket = nil } } // Connect initiates a connection to an Endpoint. func (conn *Connection) Connect(endpoint *Endpoint) (err error) { conn.dialer = net.Dialer{Timeout: conn.connectTimeout, KeepAlive: -1} conn.socket, err = conn.dialer.Dial(conn.protocol, endpoint.String()) if err != nil { log("conn", 2, "cannot connect to \"%v\": %v", endpoint, err.Error()) } return } // SetConnectTimeout sets a custom connect timeout on a Connection. func (conn *Connection) SetConnectTimeout(timeout time.Duration) { conn.connectTimeout = timeout } // Send writes data to a Connection. func (conn *Connection) Send(data []byte) (err error) { if len(data) == 0 { log("conn", 1, "tried to send empty buffer to a socket, ignoring") return nil } conn.socket.SetWriteDeadline(time.Now().Add(conn.sendTimeout)) _, err = conn.socket.Write(data) return } // Recv receives data from a Connection. func (conn *Connection) Recv() (data []byte, err error) { conn.socket.SetReadDeadline(time.Now().Add(conn.recvTimeout)) data = make([]byte, 1024) n, err := conn.socket.Read(data) if err != nil { return nil, err } data = data[:n] return }