Моя борьба с поиском библиотеки C # xmpp продолжается, так как теперь я вынужден исключить использование Soapbox Studio SDK и aggXmpp / Matrix SDK.Я перешел на Jabber-net , одну из немногих оставшихся доступных библиотек C #, и до сих пор не могу подключиться к моему серверу Openfire.Из того, что я понимаю, эта библиотека, как и большинство библиотек xmpp, которые я использовал до сих пор, выполняется асинхронно, поэтому я сначала вызываю «метод Connect» JabberClients и связываю метод, который регистрируется на сервере, с обработчиком OnConnect JabberClient.
Ниже приведен мой метод Connect, который подключается к серверу xmpp и связывает обработчик OnConnect jabberClient с методом Logon.
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;
}
}
, который выдает следующий найденный выходной SRV: denjab2.jabber.com:5222, но при этом генерируется исключение первого изменения типа System.FormatException, когда он достигает метода Connect jabberClinet.Затем он выводит «ExecuteConnect»
Ниже приведен метод входа в систему
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();
}
Этот метод не вызывает исключений.
Кроме того, вызывается обработчик onStreamError JabberClient, который просто обрабатывает исключение, которое гласит «Произошла ошибка потока» и не предоставляет внутреннего исключения.
Я пытался исследовать эти ошибки как в Интернете, так и в документации по продуктам, но, похоже, нет руководств по установлению соединения с сервером.Я должен предположить, что я либо пропускаю шаг, не предоставив все необходимые учетные данные, либо просто выполняю шаги, необходимые для входа на сервер в неправильном порядке.
Изучив пример приложения, упомянутого в ответе Джо Хильдебранда, я изменил свой метод «Connect», чтобы он выглядел следующим образом.
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;
}
}
Однако, похоже, это приводит к тому же самому поведению: дополнительные ошибки отображаются в консоли с сообщением «Sock errno: 10061» и возникает исключение, указывающее, что «Соединение не может быть установлено, посколькуцелевая машина активно отказалась », что указывает на то, что по какой-то причине сервер openfire отклонил мой запрос на подключение.Я обнаружил Этот раздел в группе Google Jabber-net , в котором предлагается использовать IP-адрес сервера вместо имени сервера из-за ошибки, возможно, связанной с невозможностью решить проблему IPv4 vs IPv6.
Использование полного IP-адреса избавило от ошибки 'Target Machine Actively Refused', но подало мне следующую ошибку
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>
Эта ошибка упоминается, но не полностью устранена в этой темеGoogle Group из Jabber-сети
Мне удалось избавиться от этой ошибки, основываясь на комментариях Джо Хильдебранда, установив для AutoStartTLS значение true и создав обработчик событий для OnInvalidCertifcate и привязав его к клиенту jabber.
Вот пересмотренный метод 'Connect'
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();
}
А вот обработчик события OnInvalidCertifcate
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;
}
Это приводит к следующему исключению.
Error binding resource
<error type="modify" code="400"><bad-requestmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /></error>
Следует также отметить, что пример консольного приложения jabber-net у меня тоже не работает.
Это мой ввод из командной строки при попытке запустить приложение.
ConsoleClient.exe /j 800802@palburtus/gec2o /r 800802 /p 800802 /o 5222 /t true /n null
И это вывод, который я получаю
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
Надеюсь, кто-то может помочь объяснить, чтоЯ делаю не так