2017-08-11 74 views
0

我在Go上有一個應用程序,它使用tcp連接到XMPP主機,然後使用xml解碼器與XMPP對話。我怎樣才能使net.Dial重新連接,如果tcp連接被丟棄?如何使net.Dial在Go重新連接,如果連接丟失?

在連接斷開時,我的錯誤信道上出現以下錯誤: write tcp client:port->xmpp_server:5222: write: broken pipe。不過,我不確定如何在我的Dial函數中正確處理它,使其重新連接。

// package xmpp 
// Conn represents a connection 
type Conn struct { 
    incoming *xml.Decoder 
    outgoing net.Conn 
    errchan chan error 
} 

// SetErrorChannel sets the channel for handling errors 
func (c *Conn) SetErrorChannel(channel chan error) { 
    c.errchan = channel 
} 

// Dial dials an xmpp host 
func Dial(host string) (*Conn, error) { 
    c := new(Conn) 
    var err error 

    c.outgoing, err = net.Dial("tcp", host+":5222") 
    if err != nil { 
     log.Printf("Can't dial %s:5222: %s", host, err) 
     return c, err 
    } 

    // TCP Keep Alive 
    err = c.outgoing.(*net.TCPConn).SetKeepAlive(true) 
    if err != nil { 
     c.errchan <- err 
    } 
    err = c.outgoing.(*net.TCPConn).SetKeepAlivePeriod(30 * time.Second) 
    if err != nil { 
     c.errchan <- err 
    } 

    c.incoming = xml.NewDecoder(c.outgoing) 
    log.Printf("Connected to: %s", c.outgoing.RemoteAddr()) 
    return c, nil 
} 

// In a separate package 
func NewXMPPClient(config) (*Client, error) { 
    errchannel := make(chan error) 
    connection, err := xmpp.Dial(host) 

    if err != nil { 
     return nil, err 
    } 
    connection.SetErrorChannel(errchannel) 

    // Do XMPP auth, receive messages, etc... 
+1

重新連接不是「撥號」的責任;只有連接。撥號用戶負責智能地重新連接,如果這適合用例。 – Adrian

+0

我不是說net.Dial函數,而是我自己在上面的代碼中使用Dial()函數。 – Maklaus

+1

你無法真正地從你的'Dial'重新連接 - 當'Dial'返回時,它將'Conn'的所有權傳遞給它的調用者,所以'Dial'不應該用''Conn'做任何事*否則會造成各種奇怪的問題。當你有意關閉連接時會發生什麼?康恩將如何知道何時重新連接?它應該重新發送連接失敗時寫入的數據嗎?這似乎不是一個可以或應該在此功能中解決的問題。 – Adrian

回答

0

想通了。我剛剛開始關閉當前tcp連接,在我的錯誤通道中發生任何錯誤,並重新創建TCP和XMPP(auth + listen)連接。

相關問題