Search code examples
c#xmppwin-universal-appstream-socket-client

C# XMPP with StremSocket hangs after resource binding


I need to build a XMPP Client in C# for a UWP app.

I know there are some libraries .NET, but it seems that do not work very well (the ones free), so I decided to implement it on my own.

The server side is an ejabberd service.

I use a StreamSocket in this way (ref XMPP 3920bis):

            StreamSocket socket = new StreamSocket();

            await socket.ConnectAsync(new HostName("my.server.com"), "5222", SocketProtectionLevel.PlainSocket);

            DataWriter dw = new DataWriter(socket.OutputStream);
            DataReader dr = new DataReader(socket.InputStream);
            dr.InputStreamOptions = InputStreamOptions.Partial;

            // Open stream
            await XmppWrite("<?xml version='1.0'?><stream:stream to='my.server.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>", dw);
            var resp = await XmppRead(dr);

            // Auth
            var sasl = Base64Encode('\0' + SaslPrep("username") + '\0' + SaslPrep("password"));
            await XmppWrite("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>" + sasl + "</auth>", dw);
            resp = await XmppRead(dr);

            // Request bind
            await XmppWrite("<?xml version='1.0'?><stream:stream to='my.server.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>", dw);
            resp = await XmppRead(dr);

            // Resource binding
            await XmppWrite("<iq id='"+ObtainID()+"' type='set'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>", dw);
            resp = await XmppRead(dr);

            // Send initial presence
            await XmppWrite("<presence/>", dw);
            resp = await XmppRead(dr);

Everything works fine until I send the initial presence, the server is not responding and the connection is closed.

Any ideas?


Solution

  • The problem was in a missing step, "open session", after the resource binding.

    // Resource binding
    await XmppWrite("<iq id='"+ObtainID()+"' type='set'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>", dw);
    resp = await XmppRead(dr);
    
    // Open session
    await XmppWrite("<iq id='" + Guid.NewGuid() + "' type='set'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></iq>", dw);
    resp = await XmppRead(dr);
    
    // Send initial presence
    await XmppWrite("<presence/>", dw);
    resp = await XmppRead(dr);