0

XML データを送り返すサーバー (XMPP) と通信しようとしているとします。使用できます

conn, err := net.Dial("tcp", s.Addr+":5222")
//...
r := bufio.NewReader(conn)
//...
s, err := s.R.ReadString(10) // to read a string

ただし、サーバーが \10 (改行) 記号を送信しないという問題が 1 つあります。私も12を試しましたが、運がありませんでした。\10 にも依存しているため、readLine 関数にも同じことが言えます。では、サーバーから送信されたデータを読み取るにはどうすればよいでしょうか。「>」を区切り文字として使用してみましたが、メッセージの一部のみを受信することに成功しました (予測可能)。エラーがゼロのときにループして区切り文字「>」を使用するというアイデアがありましたが、うまくいきませんでした。私の調査によると、メッセージの最後の記号は実際には '>' (62) であり、最後には何もありません。

4

1 に答える 1

1

xml.Decoderを使用して、XMPP ストリームからスタンザを読み取ります。

conn, err := net.Dial("tcp", s.Addr+":5222")
if err != nil {
    // handle error
}
dec := xml.NewDecoder(conn)

ルート ドキュメント要素を読み取り、スタンザ間の文字データをスキップするには、decoder Tokenメソッドを使用します。

func readStartElement(dec *xml.Decoder) (xml.StartElement, error) {
    for {
        t, err := dec.Token()
        if err != nil {
            return xml.StartElement{}, err
        }
        switch t := t.(type) {
        case xml.StartElement:
            return t, nil
        }
    }
}

デコーダーのDecodeElementメソッドを使用して、スタンザを読み取ります。

func readStanza(dec *xml.Decoder) (interface{}, error) {
    se, err := readStartElement(dec)
    if err != nil {
        return nil, err
    }
    var v interface{}
    switch  se.Name.Space + " " + se.Name.Local {
    case "jabber:client message":
        v = &jabberMessage{} // jabberMessage is struct type defined by app for messages
    // Add other stanza types here.        
    default:
        v = &struct{}{}
    }
    if err := dec.DecodeElement(v, &se); err != nil {
        return nil, err
    }
    return v, nil
}

readStanza からの戻り値にswitchを入力して、さまざまなタイプの受信スタンザを処理します。

クライアントはスタンザを同期的に読み取ります。大まかな概要は次のとおりです(認証を無視するなど)。

conn, err := net.Dial("tcp", s.Addr+":5222")
if err != nil {
    // handle error
}
dec := xml.NewDecoder(conn)

// read and discard root element
_, err := readStartElement(dec)
if err != nil {
     // handle error
}

// read stanzas
for {
   v, err := readStanza(dec)
   if err != nil {
       // handle error 
       // must break out of loop on error
   }
   switch v := v.(type) {
   case *jabberMessage:
        // handle message
   case *someOtherStanzaType:
        // handle other stanza types
        // ... and so on
   }
}
于 2016-03-19T18:30:54.217 に答える