Soapbox Studio SDK と aggXmpp / Matrix SDK の両方の使用を除外せざるを得なくなったため、C# xmpp ライブラリを見つけるのに苦労し続けています。利用可能な数少ない C# ライブラリの 1 つであるJabber-netに移行しましたが、今のところ Openfire サーバーに接続できません。私がこれまでに使用したほとんどの xmpp ライブラリと同様に、このライブラリは非同期で実行されることを理解しているため、最初に JabberClient の「Connect メソッド」を呼び出し、サーバーにログインするメソッドを JabberClient の OnConnect ハンドラにバインドします。
以下は、xmpp サーバーに接続し、jabberClient の OnConnect ハンドラーを Logon メソッドにバインドする Connect メソッドです。
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 が生成されますが、これは jabberClinet の Connect メソッドに到達すると、タイプ「System.FormatException」の最初の変更例外をスローします。次に、「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();
}
このメソッドは例外をスローしません。
さらに、JabberClient の onStreamError ハンドラが呼び出され、単に「ストリーム エラーが発生しました」という例外を生成し、内部例外を提供しません。
これらのエラーを Web と製品ドキュメントの両方で調査しようとしましたが、サーバーへの接続を確立するためのガイドがないようです。必要な資格情報をすべて提供していないか、サーバーにログオンするために必要な手順を間違った順序で実行しただけであると想定する必要があります。
Joe Hildebrand の回答に記載されているサンプル アプリケーションを調べた後、「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 サーバーが接続要求を拒否しました。Jabber-net Google グループでこのトピックを見つけました。このトピックは、IPv4 と IPv6 の問題を解決できないことに関係している可能性があるエラーのため、サーバー名の代わりにサーバーの IP アドレスを使用することを提案しています。
完全な 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>
このエラーは、Jabber-net Google グループのこのスレッドで言及されていますが、完全には解決されていません 。
Joe Hildebrand のコメントに基づいて、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
誰かが私が間違っていることを説明できることを願っています。