Added configurable timeouts and overridable version string

此提交包含在:
Andrew Montgomery-Hurrell
2014-02-09 10:20:58 +00:00
父節點 a1d207d5fa
當前提交 c0e6d50e0c
共有 3 個檔案被更改,包括 47 行新增 和 9 行删除
+41 -8
查看文件
@@ -23,7 +23,21 @@ func (irc *Connection) readLoop() {
br := bufio.NewReaderSize(irc.socket, 512) br := bufio.NewReaderSize(irc.socket, 512)
for { for {
// Set a read deadline based on the combined timeout and ping frequency
// We should ALWAYS have received a response from the server within the timeout
// after our own pings
if irc.socket != nil {
irc.socket.SetReadDeadline(time.Now().Add(irc.Timeout + irc.PingFreq))
}
msg, err := br.ReadString('\n') msg, err := br.ReadString('\n')
// We got past our blocking read, so bin timeout
if irc.socket != nil {
var zero time.Time
irc.socket.SetReadDeadline(zero)
}
if err != nil { if err != nil {
irc.Error <- err irc.Error <- err
break break
@@ -77,7 +91,16 @@ func (irc *Connection) writeLoop() {
if irc.Debug { if irc.Debug {
irc.log.Printf("--> %s\n", b) irc.log.Printf("--> %s\n", b)
} }
// Set a write deadline based on the time out
irc.socket.SetWriteDeadline(time.Now().Add(irc.Timeout))
_, err := irc.socket.Write([]byte(b)) _, err := irc.socket.Write([]byte(b))
// Past blocking write, bin timeout
var zero time.Time
irc.socket.SetWriteDeadline(zero)
if err != nil { if err != nil {
irc.Error <- err irc.Error <- err
break break
@@ -86,19 +109,19 @@ func (irc *Connection) writeLoop() {
irc.writerExit <- true irc.writerExit <- true
} }
//Pings the server if we have not recived any messages for 5 minutes //Pings the server if we have not received any messages for 5 minutes
func (irc *Connection) pingLoop() { func (irc *Connection) pingLoop() {
ticker := time.NewTicker(1 * time.Minute) //Tick every minute. ticker := time.NewTicker(1 * time.Minute) // Tick every minute for monitoring
ticker2 := time.NewTicker(15 * time.Minute) //Tick every 15 minutes. ticker2 := time.NewTicker(irc.PingFreq) // Tick at the ping frequency.
for { for {
select { select {
case <-ticker.C: case <-ticker.C:
//Ping if we haven't received anything from the server within 4 minutes //Ping if we haven't received anything from the server within the keep alive period
if time.Since(irc.lastMessage) >= (4 * time.Minute) { if time.Since(irc.lastMessage) >= irc.KeepAlive {
irc.SendRawf("PING %d", time.Now().UnixNano()) irc.SendRawf("PING %d", time.Now().UnixNano())
} }
case <-ticker2.C: case <-ticker2.C:
//Ping every 15 minutes. //Ping at the ping frequency
irc.SendRawf("PING %d", time.Now().UnixNano()) irc.SendRawf("PING %d", time.Now().UnixNano())
//Try to recapture nickname if it's not as configured. //Try to recapture nickname if it's not as configured.
if irc.nick != irc.nickcurrent { if irc.nick != irc.nickcurrent {
@@ -192,6 +215,10 @@ func (irc *Connection) Disconnect() {
<-irc.pingerExit <-irc.pingerExit
irc.socket.Close() irc.socket.Close()
irc.socket = nil irc.socket = nil
if irc.netsock != nil {
irc.netsock.Close()
irc.netsock = nil
}
} }
func (irc *Connection) Reconnect() error { func (irc *Connection) Reconnect() error {
@@ -204,9 +231,11 @@ func (irc *Connection) Connect(server string) error {
var err error var err error
if irc.UseTLS { if irc.UseTLS {
irc.socket, err = tls.Dial("tcp", irc.server, irc.TLSConfig) if irc.netsock, err = net.DialTimeout("tcp", irc.server, irc.Timeout); err == nil {
irc.socket = tls.Client(irc.netsock, irc.TLSConfig)
}
} else { } else {
irc.socket, err = net.Dial("tcp", irc.server) irc.socket, err = net.DialTimeout("tcp", irc.server, irc.Timeout)
} }
if err != nil { if err != nil {
return err return err
@@ -238,6 +267,10 @@ func IRC(nick, user string) *Connection {
writerExit: make(chan bool), writerExit: make(chan bool),
pingerExit: make(chan bool), pingerExit: make(chan bool),
endping: make(chan bool), endping: make(chan bool),
Version: VERSION,
KeepAlive: 4 * time.Minute,
Timeout: 1 * time.Minute,
PingFreq: 15 * time.Minute,
} }
irc.setupCallbacks() irc.setupCallbacks()
return irc return irc
+1 -1
查看文件
@@ -84,7 +84,7 @@ func (irc *Connection) setupCallbacks() {
//Version handler //Version handler
irc.AddCallback("CTCP_VERSION", func(e *Event) { irc.AddCallback("CTCP_VERSION", func(e *Event) {
irc.SendRawf("NOTICE %s :\x01VERSION %s\x01", e.Nick, VERSION) irc.SendRawf("NOTICE %s :\x01VERSION %s\x01", e.Nick, irc.Version)
}) })
irc.AddCallback("CTCP_USERINFO", func(e *Event) { irc.AddCallback("CTCP_USERINFO", func(e *Event) {
+5
查看文件
@@ -17,8 +17,13 @@ type Connection struct {
Password string Password string
UseTLS bool UseTLS bool
TLSConfig *tls.Config TLSConfig *tls.Config
Version string
Timeout time.Duration
PingFreq time.Duration
KeepAlive time.Duration
socket net.Conn socket net.Conn
netsock net.Conn
pread, pwrite chan string pread, pwrite chan string
readerExit, writerExit, pingerExit chan bool readerExit, writerExit, pingerExit chan bool
endping chan bool endping chan bool