Implement reconnection retry on disconnect.
This fixes a problem when trying to download multiple files from same servermain
parent
d2c8df3593
commit
0c6b340499
70
xdcc.go
70
xdcc.go
|
|
@ -118,36 +118,25 @@ func (transfer *XdccTransfer) Start() error {
|
||||||
return transfer.conn.Connect()
|
return transfer.conn.Connect()
|
||||||
}
|
}
|
||||||
|
|
||||||
type XdccEvent interface{}
|
type TransferEvent interface{}
|
||||||
|
|
||||||
type TransferAbortedEvent struct {
|
type TransferAbortedEvent struct {
|
||||||
Error string
|
Error string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const maxConnAttempts = 5
|
||||||
|
|
||||||
type XdccTransfer struct {
|
type XdccTransfer struct {
|
||||||
filePath string
|
filePath string
|
||||||
url IRCFileURL
|
url IRCFileURL
|
||||||
conn *irc.Conn
|
conn *irc.Conn
|
||||||
started bool
|
connAttempts int
|
||||||
events chan XdccEvent
|
started bool
|
||||||
}
|
events chan TransferEvent
|
||||||
|
|
||||||
type TransferManager struct {
|
|
||||||
transfers map[IRCBot]*XdccTransfer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tm *TransferManager) addTransfer(fileUrl *IRCFileURL, filePath string) {
|
|
||||||
transfer, ok := tm.transfers[fileUrl.GetBot()]
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
transfer = NewXdccTransfer(*fileUrl, filePath)
|
|
||||||
tm.transfers[fileUrl.GetBot()] = transfer
|
|
||||||
// add transfer
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewXdccTransfer(url IRCFileURL, filePath string) *XdccTransfer {
|
func NewXdccTransfer(url IRCFileURL, filePath string) *XdccTransfer {
|
||||||
|
rand.Seed(time.Now().UTC().UnixNano())
|
||||||
conn := irc.SimpleClient(IRCClientUserName + strconv.Itoa(int(rand.Uint32())))
|
conn := irc.SimpleClient(IRCClientUserName + strconv.Itoa(int(rand.Uint32())))
|
||||||
conn.Config().Server = url.Network
|
conn.Config().Server = url.Network
|
||||||
conn.Config().NewNick = func(nick string) string {
|
conn.Config().NewNick = func(nick string) string {
|
||||||
|
|
@ -155,11 +144,12 @@ func NewXdccTransfer(url IRCFileURL, filePath string) *XdccTransfer {
|
||||||
}
|
}
|
||||||
|
|
||||||
t := &XdccTransfer{
|
t := &XdccTransfer{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
url: url,
|
url: url,
|
||||||
filePath: filePath,
|
filePath: filePath,
|
||||||
started: false,
|
started: false,
|
||||||
events: make(chan XdccEvent, defaultEventChanSize),
|
connAttempts: 0,
|
||||||
|
events: make(chan TransferEvent, defaultEventChanSize),
|
||||||
}
|
}
|
||||||
t.setupHandlers(url.Channel, url.UserName, url.Slot)
|
t.setupHandlers(url.Channel, url.UserName, url.Slot)
|
||||||
return t
|
return t
|
||||||
|
|
@ -175,22 +165,28 @@ func (transfer *XdccTransfer) setupHandlers(channel string, userName string, slo
|
||||||
// e.g. join channel on connect.
|
// e.g. join channel on connect.
|
||||||
conn.HandleFunc(irc.CONNECTED,
|
conn.HandleFunc(irc.CONNECTED,
|
||||||
func(conn *irc.Conn, line *irc.Line) {
|
func(conn *irc.Conn, line *irc.Line) {
|
||||||
fmt.Println("connected ", channel)
|
transfer.connAttempts = 0
|
||||||
conn.Join(channel)
|
conn.Join(channel)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
conn.HandleFunc(irc.ERROR, func(conn *irc.Conn, line *irc.Line) {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
// send xdcc send on successfull join
|
// send xdcc send on successfull join
|
||||||
conn.HandleFunc(irc.JOIN,
|
conn.HandleFunc(irc.JOIN,
|
||||||
func(conn *irc.Conn, line *irc.Line) {
|
func(conn *irc.Conn, line *irc.Line) {
|
||||||
if line.Args[0] == channel && !transfer.started {
|
if line.Args[0] == channel && !transfer.started {
|
||||||
fmt.Println("contacting ", transfer.url.UserName)
|
|
||||||
transfer.send(&XdccSendReq{Slot: slot})
|
transfer.send(&XdccSendReq{Slot: slot})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
conn.HandleFunc(irc.PRIVMSG, func(conn *irc.Conn, line *irc.Line) {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
conn.HandleFunc(irc.CTCP,
|
conn.HandleFunc(irc.CTCP,
|
||||||
func(conn *irc.Conn, line *irc.Line) {
|
func(conn *irc.Conn, line *irc.Line) {
|
||||||
fmt.Println(line.Text())
|
|
||||||
res, err := parseCTCPRes(line.Text())
|
res, err := parseCTCPRes(line.Text())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
|
|
@ -201,13 +197,23 @@ func (transfer *XdccTransfer) setupHandlers(channel string, userName string, slo
|
||||||
|
|
||||||
conn.HandleFunc(irc.DISCONNECTED,
|
conn.HandleFunc(irc.DISCONNECTED,
|
||||||
func(conn *irc.Conn, line *irc.Line) {
|
func(conn *irc.Conn, line *irc.Line) {
|
||||||
if !transfer.started {
|
var err error = nil
|
||||||
|
|
||||||
|
if transfer.connAttempts < maxConnAttempts {
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
|
err = conn.Connect()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err != nil || transfer.connAttempts >= maxConnAttempts) && !transfer.started {
|
||||||
transfer.notifyEvent(&TransferAbortedEvent{Error: "disconnected from server"})
|
transfer.notifyEvent(&TransferAbortedEvent{Error: "disconnected from server"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transfer.connAttempts++
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (transfer *XdccTransfer) PollEvents() chan XdccEvent {
|
func (transfer *XdccTransfer) PollEvents() chan TransferEvent {
|
||||||
return transfer.events
|
return transfer.events
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,7 +231,7 @@ type TransferStartedEvent struct {
|
||||||
|
|
||||||
type TransferCompletedEvent struct{}
|
type TransferCompletedEvent struct{}
|
||||||
|
|
||||||
func (transfer *XdccTransfer) notifyEvent(e XdccEvent) {
|
func (transfer *XdccTransfer) notifyEvent(e TransferEvent) {
|
||||||
select {
|
select {
|
||||||
case transfer.events <- e:
|
case transfer.events <- e:
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue