2016-03-19 22 views
0

XML verilerini geri gönderen bir sunucu (XMPP) ile iletişim kurmaya çalışalım. BizYeni satır göndermezse, sunucu tarafından gönderilen veri (xml) nasıl okunur?

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

kullanabilirsiniz Ama sunucu \ 10 (newline) sembolü göndermez bir sorun vardır. 12 tane de denedim ama şanssız. Aynı zamanda \ 10'a dayandığı için readLine fonksiyonu için de geçerli. Peki sunucu tarafından gönderilen verileri nasıl okurum? Bir sınırlayıcı olarak '>' kullanmayı denedim ve yalnızca mesajların bölümlerini (tahmin edilebilir) almayı başardım. Hata nil ise ve '>' sınırlayıcıyı kullanırken döngü yapmak için bir fikrim vardı ama aynı zamanda işe yaramadı. Araştırmam, mesajın son sembolünün gerçekten ">" (62) olduğunu ve sonunda herhangi bir şey olmadığını gösterdi.

cevap

1

Bir XMPP akışından stanzas okumak için xml.Decoder kullanın.

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

kök belge elemanı almak için dekoder Token yöntemi kullanarak ve stanzas arasında karakter verilerini atlamak:

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.DeocdeElement(v, &se); err != nil { 
     return nil, err 
    } 
    return v, nil 
} 
: bir dörtlük okuma

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 
     } 
    } 
} 

kullanımı kod çözücü DecodeElement yöntemi

Type switch, farklı tipteki stanzas'ları işlemek için readStanza'dan geri dönüş değeri.

Bir istemci, senkronize olarak stanzas okuyor. İşte kaba taslak (kimlik doğrulamasını göz ardı etme, vb.).

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 
    } 
} 
+0

Geri dönüş hatası '' dönüş yok, hata ''? –

+0

@ SanjayT.Sharma 'xml.StartElement {}, err' olmalıdır. Sorunu işaretlediğiniz için teşekkürler. –

İlgili konular