2017-08-11 6 views
0

私はGoで、tcpを使用してXMPPホストに接続し、xmlデコーダを使ってXMPPと通信するアプリケーションを持っています。 tcp接続が切断された場合、どのようにnet.Dialを再接続できますか?接続が失われた場合は、Goの再接続でnet.Dialを作成するには?

接続が切断されたときにエラーチャンネルで次のエラーが表示されます。 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

再接続は 'Dial'の責任ではありません。接続するだけです。 'Dial'のユーザは、それがユースケースに適切であるなら、知的に再接続する責任があります。 – Adrian

+0

私はnet.Dial関数ではなく、上記のコードで自分のDial()関数を意味しました。 – Maklaus

+1

'Dial'から本当に再接続することはできません - ' Dial'が返ってきたら、 'Conn'の所有者を呼び出し側に渡すので、' Dial'はそれ以上何もしてはいけません。それはあらゆる種類の奇妙な問題を引き起こすでしょう。意図的に接続を閉じるとどうなりますか?どのように再接続するのかをConnは知っていますか?接続が失敗したときに書き込まれたデータを再送信する必要がありますか?これは、この機能で解決できなければならない問題のようには見えません。 – Adrian

答えて

0

これがわかりました。私はちょうど私のエラーチャンネルの任意のエラーで現在のTCP接続を閉じて、TCPとXMPP(auth + listen)接続の両方を再作成し始めました。

関連する問題