// (c) Bernhard Tittelbach, 2013 package r3xmppbot import ( "encoding/xml" "time" xmpp "code.google.com/p/goexmpp" ) // XMPP Ping type XMPPPing struct { XMLName xml.Name `xml:"urn:xmpp:ping ping"` } func HandleServerToClientPing(iq *xmpp.Iq, xmppout chan<- xmpp.Stanza) bool { /// if iq.Type != "get" { return false } for _, ele := range iq.Nested { if _, ok := ele.(*XMPPPing); ok { xmppout <- &xmpp.Iq{Header: xmpp.Header{To: iq.From, From: iq.To, Id: iq.Id, Type: "result"}} return true } } return false } func (botdata *XmppBot) PingServer(timeout_ms time.Duration) (is_up bool) { /// /// /// server_jid := new(xmpp.JID) server_jid.Set(botdata.my_jid_) iqping := &xmpp.Iq{Header: xmpp.Header{To: server_jid.Domain, From: botdata.my_jid_, Id: <-xmpp.Id, Type: "get", Nested: []interface{}{XMPPPing{}}}} pong := make(chan bool, 1) defer close(pong) f := func(v xmpp.Stanza) bool { defer recover() //recover from writing to possibly already closed chan let_others_handle_stanza := false iq, ok := v.(*xmpp.Iq) if !ok { Syslog_.Printf("response to iq ping wasn't iq: %s", v) pong <- false return true //let other handlers process reply } if iq.Type == "error" && iq.Error != nil && iq.Error.Type == "cancel" { Debug_.Printf("response to iq ping was cancel, server does not support ping") //server does not support ping, but at least we know server is still there } else if iq.Type != "result" { Syslog_.Printf("response to iq ping was not pong: %s", v) let_others_handle_stanza = true //let other handlers process reply } pong <- true return let_others_handle_stanza // return false so that Stanza v will not be appear in xmppclient_.Out() } botdata.xmppclient_.HandleStanza(iqping.Id, f) botdata.xmppclient_.Out <- iqping go func() { defer func() { if x := recover(); x == nil { Syslog_.Printf("response to iq ping timed out !!") } }() //recover from writing to possibly already closed chan. If we did not need to recover, then Handler did not receive reply time.Sleep(timeout_ms * time.Millisecond) pong <- false //xmpp ping timed out }() return <-pong }