Error Binding Resource while Connecting to Openfir

2019-05-26 14:48发布

My struggles with finding a C# xmpp library continues as I have now been force to rule out using both the Soapbox Studio SDK and aggXmpp / Matrix SDK. I have moved on to Jabber-net one of the few remaining C# libraries available and am thus far unable to connect to my Openfire Server. From what I understand this library like most xmpp libraries I have used thus far executes asynchronously so I am first calling the JabberClients 'Connect method' and bind a method that Logs into the server to the JabberClient's OnConnect handler.

Below is my Connect method that connects to the xmpp sever and binds the jabberClient's OnConnect handler to the Logon method.

public string Connect()
{
        try
        {
            jabberClient = new JabberClient();
            jabberClient.Connect();
            jabberClient.OnConnect += (o, e) => Logon();                
            jabberClient.OnAuthError += (o, e) => ThrowError("authError");
            jabberClient.OnStreamError += (o, e) => ThrowError("streamError");

            return "Connection Succesful";
        }
        catch (Exception ex)
        {
            _logger.LogError("SessionManager", "Connect", "Could not connect to Openfire Server", ex.ToString());
            return "Could not Connect to Openfire Server: " + ex;
        }
}

Which produces the following output SRV found: denjab2.jabber.com:5222, but this throws a first change exception of type 'System.FormatException' when it reaches the jabberClinet's Connect method. It then outputs 'ExecuteConnect'

Below is the Logon Method

private void Logon()
{
        JID jid = new JID(OPENFIRE_USER_NAME, OPENFIRE_SERVER, "protoTest");
        jabberClient.User = jid.User;
        jabberClient.Server = jid.Server;
        jabberClient.Password = OPENFIRE_PASSWORD;
        jabberClient.AutoLogin = true;
        jabberClient.AutoPresence = true;
        jabberClient.Login();  
}

This method throws no exceptions.

Additionally, The JabberClient's onStreamError handler get called and simply procudes an exception that reads "A Stream Error Occured" and provides no inner exception.

I have tried to research these errors both on the web and through the products documentation but there seem to be no guides to establishing a connection to the server. I have to assume that I am either missing a step, not providing all of the necessary credentials, or am simply executed the steps needed to log on to the server in the wrong order.

After looking into the sample application mentioned in Joe Hildebrand's answer, I modified my 'Connect' method to look like the following.

public void Connect()
{
        try
        {
            jabberClient = new JabberClient();              

            //Bind the JabberClient events to methods that handle those events.
            jabberClient.OnAuthError += (o, e) => ThrowError(ErrorType.AuthError);
            jabberClient.OnStreamError += (o, e) => ThrowError(ErrorType.StreamError);
            jabberClient.OnError += (o, e) => ThrowError(ErrorType.UnknownError);
            jabberClient.OnConnect += (o, e) => ConnectionComplete();

            //Set client settings
            jabberClient.AutoReconnect = 3f;

            JID jid = new JID(OPENFIRE_USER_NAME, OPENFIRE_SERVER, "gec2o");
            jabberClient.User = jid.User;
            jabberClient.Server = jid.Server;
            jabberClient.NetworkHost = null;
            jabberClient.Port = OPENFIRE_NOT_ENCRYPTED_PORT;
            jabberClient.Resource = jid.Resource;
            jabberClient.Password = OPENFIRE_PASSWORD;
            jabberClient.AutoStartTLS = false;
            jabberClient.AutoPresence = false;

            CapsManager cm = new CapsManager();
            cm.Stream = jabberClient;


            jabberClient.Connect();

        }
        catch (Exception ex)
        {
            _log.LogError("ConnectionManager", "Connect", "Could not connect to Openfire Server", ex.ToString());
            throw ex;
    }
}

However, this seems to result in the same behavior with the additional errors showing up in the console stating 'Sock errno: 10061' and an exception being thrown stating that 'No connection could be made because the target machine actively refused it' which indicates that for some reason the openfire server is rejected my connection request. I found This topic on the Jabber-net Google Group that suggest I use the server's IP address instead of server name due to the error possibly having something to do with the inability to resolve an IPv4 vs IPv6 issue.

Using the full IP addressed got rid of the 'Target Machine Actively Refused' error but presented me with following error

 SEND: <iq id="JN_1" type="set" to="192.168.1.182"><bind 
xmlns="urn:ietf:params:xml:ns:xmpp-bind"><resource>rsup</resource></ 
bind></iq> 
RECV: <iq type="error" id="JN_1" from="192.168.1.182" to="infotel/ 
bf18b431"><bind xmlns="urn:ietf:params:xml:ns:xmpp- 
bind"><resource>rsup</resource></bind><error code="400" 
type="modify"><bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/ 
></error></iq> 

ERROR: jabber.connection.sasl.AuthenticationFailedException: Error 
binding resource: <error code="400" type="modify" 
xmlns="jabber:client"><bad-request xmlns="urn:ietf:params:xml:ns:xmpp- 
stanzas" /></error> 

This error is mention but not fully resolved on this thread of the Jabber-net Google Group

I was able to get rid of this error based on Joe Hildebrand comments by settings AutoStartTLS to true and creating an event handler for OnInvalidCertifcate and binding it to the jabber client.

Here is the revised 'Connect' method

public void Connect()
{
        try
        {
            jabberClient = new JabberClient();

            //Bind the JabberClient events to methods that handle those events.
            jabberClient.OnAuthError += (o, e) => ThrowError(ErrorType.AuthError);
            jabberClient.OnStreamError += (o, e) => ThrowError(ErrorType.StreamError);
            jabberClient.OnError += (o, e) => ThrowError(ErrorType.UnknownError);
            jabberClient.OnConnect += (o, e) => ConnectionComplete();
            jabberClient.OnInvalidCertificate += new System.Net.Security.RemoteCertificateValidationCallback(OnInvalidCertificate);

            //Set client settings
            jabberClient.AutoReconnect = 3f;

            JID jid = new JID(OPENFIRE_USER_NAME, OPENFIRE_SERVER, "gec2o");
            jabberClient.User = jid.User;
            //jabberClient.Server = jid.Server;
            jabberClient.Server = "192.168.97.26";

            jabberClient.NetworkHost = null;
            jabberClient.Port = OPENFIRE_NOT_ENCRYPTED_PORT;
            jabberClient.Resource = jid.Resource;
            jabberClient.Password = OPENFIRE_PASSWORD;
            jabberClient.AutoStartTLS = true;
            jabberClient.AutoPresence = false;

            CapsManager cm = new CapsManager();
            cm.Stream = jabberClient;


            jabberClient.Connect();

}

And here is the OnInvalidCertifcate event handler

bool OnInvalidCertificate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
        Console.WriteLine("Invalid certificate ({0}):\n{1}", sslPolicyErrors.ToString(), certificate.ToString(true));
        return true;
}

This results in the following exception.

Error binding resource 
<error type="modify" code="400"><bad-requestmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /></error>

I should also note that the jabber-net sample Console Application does not work for me either.

This is my command line input when trying to run the app.

ConsoleClient.exe /j 800802@palburtus/gec2o /r 800802 /p 800802 /o 5222 /t true /n null

And this is the output I receive

  Connecting
Connected
ERROR: System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it at System.Net.Sockets.Socket.EndConnect(IAsyncResult asy
   at bedrock.net.AsyncSocket.ExecuteConnect(IAsyncResult a
.0.710\bedrock\net\AsyncSocket.cs:line 782

Hopefully someone can help explain what I'm doing wrong.

标签: c# xmpp openfire
5条回答
叼着烟拽天下
2楼-- · 2019-05-26 15:01

Have you tried the Example or ConsoleClient application?

You're calling Connect() before your have your JabberClient instance fully configured. Set up all of your properties and callbacks first, then call Connect(). Finally, you should almost never call Login() unless AutoLogin is False or OnAuthError has fired.

查看更多
萌系小妹纸
3楼-- · 2019-05-26 15:03

Does your server have an IPv6 address? That's not really working at the moment.

查看更多
冷血范
4楼-- · 2019-05-26 15:05

I had the exact same issue. I finally realized that I was using the wrong IP address for my network host (I was using the localhost, instead of my actual IP address). I know this isn't your exact issue, but now I can run JabberNet and connect to my local OpenFire server. Here's what I have:

Basic tab::
User: tony
Password: tony
Server: Server-Name (from the OpenFire Admin Console: / Server / Server Management page)

Network::
Port: 5222
Network Host: My IP Address

If I run the JabberNet Example app from Visual Studio 2010,

AutoLogin = true,
Resource = Jabber.Net

I just click Allow Once on the (inevitable) Invalid Certificate dialog.

Everything else is default.

I don't know if this helps at all, but it (finally) works for me.

查看更多
太酷不给撩
5楼-- · 2019-05-26 15:06

I am also having the same error while trying to connect to Openfire. I managed to get rid of the error however by connecting with port 5223 which is Openfire's port for "The port used for clients to connect to the server using the old SSL method."

查看更多
欢心
6楼-- · 2019-05-26 15:19

A number of parameters need to be set in order to connect using an IP address instead of DNS:

  1. NetworkHost - aka the Server IP (or hostname if you have DNS or /etc/host file configured)
  2. Server - aka XMPP Server name/domain (typically the same as the server's hostname)
jabberClient = new JabberClient();
jabberClient.NetworkHost = "192.168.0.2";
jabberClient.Server = "xmppservername.domain.etc";

If jabberClient.Server is set and jabberClient.NetworkHost is not, jabber-net will automatically assume that NetworkHost is the same as Server.

查看更多
登录 后发表回答