C#連接基於Java開發IM——Openfire

来源:https://www.cnblogs.com/WarrenRyan/archive/2019/02/20/10406535.html
-Advertisement-
Play Games

Openfire簡介    Openfire 是開源的、基於可拓展通訊和表示協議(XMPP)、採用Java編程語言開發的實時協作伺服器。Openfire的效率很高,單台伺服器可支持上萬併發用戶。   Server和Client端的通信都用xml文檔的形式進行通 ...


Openfire簡介

   Openfire 是開源的、基於可拓展通訊和表示協議(XMPP)、採用Java編程語言開發的實時協作伺服器。Openfire的效率很高,單台伺服器可支持上萬併發用戶。
  Server和Client端的通信都用xml文檔的形式進行通信。
但是Openfire是Java語言寫的,對於C#的dll拓展庫相比與java的jar包少的可憐,在網上尋找一番之後找到了一個比較好的dll拓展庫,agsxmpp是一個專門為C#連接xmpp協議下即時通訊已經搭建xmpp協議服務端的的dll,同時他有商業版MatriX,博主窮學生一個,沒有啥錢去購買商業版,還是採用了普通的agsxmpp。

AgsXmpp簡介

  agsxmpp是AG—Software進行開發的一個開源項目,可以在它的官網進行下載源碼。
  agsxmpp是在2003年開始研發,2008年發佈它的最後一個版本,因此它在相容性上顯然是不很好的。
  同時在C#連接Openfire上,agsxmpp中有一個巨坑,加上網上關於agsxmpp的開發文檔奇少,而且博主沒有在官網上找到相關的開發文檔(就算有也是全英文看不懂系列),故記下開發全過程。
  因為agsxmpp並不是專門為Openfire製作的,而是對任何以xmpp協議的即時通訊進行連接等服務。如果不對源碼進行一定的重寫,在某些情況下會出現一些問題。
  如果你直接使用 agsxmpp.dllXmppClientConnection 類進行連接,就算你代碼毫無錯誤,也無法正常連接Openfire,因為
博主只是對源碼改了一句話,即可正常連接。
修改 protocolsasl 下的 Mechanism.cs 中源碼,將

case "DIGEST-MD5":
    return MechanismType.DIGEST_MD5;

註釋,因為 openfire 發送數據流 是通過 PLAIN 的 , 而 agsxmpp 是預設是 通過DIGEST-MD5 發送。
  同時,在agsxmpp中,還有一個地方表現了對openfire的不相容,openfire 發送iq節 不接收 to屬性,因此還需要修改一個地方
源代碼如下

public IQ SendIq(agsXMPP.protocol.client.IQ iq, int timeout)
{
    synchronousResponse = null;
    AutoResetEvent are = new AutoResetEvent(false);

    SendIq(iq, new IqCB(SynchronousIqResult), are);

    if (!are.WaitOne(timeout, true))
    {
        // Timed out
        lock (m_grabbing)
        {
            if (m_grabbing.ContainsKey(iq.Id))
                m_grabbing.Remove(iq.Id);
        }
        return null;
    }

    return synchronousResponse;
}
 
修改後如下
public void SendIq(IQ iq, IqCB cb, object cbArg)
{
    // check if the callback is null, in case of wrong usage of this class
    if (cb != null)
        {
            TrackerData td = new TrackerData();
            td.cb = cb;
            td.data = cbArg;
            m_grabbing[iq.Id] = td;

            //iq在agsxmpp中發送Iq節的時候先iq.RemoveAttribute("to")
            iq.RemoveAttribute("to");
        }
    m_connection.Send(iq);
}

public void SendIq2(IQ iq, IqCB cb, object cbArg)
{
    // check if the callback is null, in case of wrong usage of this class
    if (cb != null)
        {
            TrackerData td = new TrackerData();
            td.cb = cb;
            td.data = cbArg;
            m_grabbing[iq.Id] = td;
            //iq在agsxmpp中發送Iq節的時候先iq.RemoveAttribute("to")
            //iq.RemoveAttribute("to");
        }
    m_connection.Send(iq);
}

  登錄操作:發送xml消息用 SendIq() 方法
  其他操作:發送xml消息用 SendIq2() 方法

連接上Openfire

官方提供了一個只有三行代碼的小型Demo

XmppClientConnection xmpp = new XmppClientConnection(server);
xmpp.Open(username,secret);
xmpp.OnLogin+=delegate(object o){xmpp.Send(new Message(JID,MessageType.chat,msg));};

我的代碼

public class XmppLogin
    {
        private XmppClientConnection xmppCon;
        private bool isSSL;
        /// <summary>
        /// 是否使用加密連接
        /// </summary>
        public bool IsSSL { get { return isSSL; } set { isSSL = value; } }
        private string userName;
        private string server;
        public string Server { get { return server; } set { server = value; } }
        /// <summary>
        /// 用戶名
        /// </summary>
        public string UserName { get { return userName; } set { userName = value; } }
        private string passWord;
        /// <summary>
        /// 密碼
        /// </summary>
        public string PassWord { get { return passWord; } set { passWord = value; } }
        private string clientVersion;
        /// <summary>
        /// 客戶端版本
        /// </summary>
        public string ClientVersion { get { return clientVersion; }set { clientVersion = value; } }
        /// <summary>
        /// 登錄狀態
        /// </summary>
        public string LoginState { get { return xmppCon.XmppConnectionState.ToString(); } }
        private int port;
        /// <summary>
        /// 登錄埠,通常是5222,加密時是5223
        /// </summary>
        public int Port { get { return port; }set{ port = value;} }

        public XmppLogin()
        {
            xmppCon = new XmppClientConnection();
        }

        #region 傳遞一個XmppClient對象
        /// <summary>
        /// 傳遞一個XmppClient對象
        /// </summary>
        /// <param name="con">需要操作的具體實例</param>
        public XmppLogin(XmppClientConnection con)
        {
            xmppCon = new XmppClientConnection();
            xmppCon = con;
        }
        #endregion

        #region 登錄
        /// <summary>
        /// 登錄openfire的方法
        /// </summary>
        /// <returns>返回值為是否登錄</returns>
        public void Login()
        {
            
            xmppCon.Server = server;
            xmppCon.UseSSL = false;
            xmppCon.Port = 5222;
            xmppCon.AutoResolveConnectServer = true;
            xmppCon.UseCompression = false;
            xmppCon.EnableCapabilities = true;
            xmppCon.ClientVersion = "1.0";
            xmppCon.Capabilities.Node = "http://www.ag-software.de/miniclient/caps";
            xmppCon.DiscoInfo.AddIdentity(new DiscoIdentity("pc", "MyClient", "client"));
            xmppCon.DiscoInfo.AddFeature(new DiscoFeature(agsXMPP.Uri.DISCO_INFO));
            xmppCon.DiscoInfo.AddFeature(new DiscoFeature(agsXMPP.Uri.DISCO_ITEMS));
            xmppCon.DiscoInfo.AddFeature(new DiscoFeature(agsXMPP.Uri.MUC));
            xmppCon.Open(userName,passWord);
            
            //xmppCon.OnLogin += delegate (object o) { xmppCon.Send(new agsXMPP.protocol.client.Message("[email protected]", MessageType.chat, "sdgo")); };
        }
        #endregion

        #region 測試連接
        /// <summary>
        /// 測試指定的OpenFire伺服器和埠是否能連通
        /// </summary>
        /// <returns>返回是否能連通</returns>
        public bool TestPing()
        {
            string ipAddress = Server;
            int portNum = port;
            bool CanConnect = false;
            IPAddress ip = IPAddress.Parse(ipAddress);
            try
            {
                IPEndPoint point = new IPEndPoint(ip, portNum);
                using (Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
                {
                    sock.Connect(point);
                    CanConnect = sock.Connected;
                    sock.Close();
                    return CanConnect;
                }
            }
            catch (SocketException e)
            {
                //LOG TODO
                return false;
            }
        }
        #endregion

        public static implicit operator XmppClientConnection(XmppLogin v)
        {
            return v.xmppCon;
        }
    }

  至此,Openfire連接成功。
  最近忙而且也剛開始弄這個,過幾天更新一下XmppConnection下各種屬性、事件、函數的具體用法。

我的掘金:WarrenRyan

我的簡書:WarrenRyan

歡迎關註我的博客獲得第一時間更新 https://blog.tity.online

我的Github:StevenEco

我的博客園:WarrenRyan


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 現在好些網站都支持掃碼登錄,感覺上安全了很多,但是本地程式掃碼登錄的不多,就用C 實現了一下,需要作如下準備 1. 在官網上申請一個企業微信,有條件的話做個企業認證吧,我們的是認證過的,所以賬號和本地其他系統的賬號是統一的. 2. 在應用中創建一個應用,這個是關鍵,我們掃碼就是和它有關. 3. 點擊 ...
  • 0 綜述 1 MVP各模塊規範 1.1 實體模塊規範 1.1.1 命名規範 實體類封裝到單獨的DLL中,DLL命名遵循<ProjectName>.DataEntity。資料庫實體類名遵循:資料庫表名去掉複數尾碼,如“s”、“es”等(資料庫表的名稱必須是名詞複數)。 1.1.2 架構規範 實體模塊中 ...
  • 成功的故事固然蕩氣迴腸,失敗的故事也能千迴百轉,但是如果你連第一步都不願邁出,不去追求與償試,那麼你永完不會知道成功或者失敗的原因是什麼,人生一輩子也就三萬多天,如果每天糊裡糊塗的過去了,若幹年後可能連故事都沒得講。 年前的時候廣州.net俱樂部主席葉老師就曾微信找我私聊,說你可以在合肥組織一個合肥 ...
  • ASP.net core 使用UEditor.Core 實現 ueditor 上傳功能 首先通過nuget 引用UEditor.Core,作者github:https://github.com/baiyunchen/UEditor.Core/ 在Startup.cs中添加 引入ueditor並配置 ...
  • 一. 支持欄位 EF允許讀取或寫入欄位而不是一個屬性。在使用實體類時,用面向對象的封裝來限制或增強應用程式代碼對數據訪問的語義時,這可能很有用。無法使用數據註釋配置。除了約定,還可以使用Fluent API為屬性配置支持欄位。 1.1 約定 1.2 Fluent API 二. 構造函數 從開始 EF ...
  • 1.對微服務的理解 之前看到在群里的朋友門都在討論微服務,看到他們的討論,我也有了一些自己的理解,所謂微服務就是系統里的每個服務都 可以自由組合。自由組合這個就很厲害了,這樣一來,每個服務與服務之間基本的物理 耦合為0,橫向擴展整個系統就會非常非常靈活。 surging的厲害之處也恰恰是可以做到這些 ...
  • 鏈接:https://pan.baidu.com/s/1SJHKTvQ4av_P9kLrtyYZ6w 提取碼:toya ...
  • 右鍵“工具箱”選擇“選擇項” 彈出對話框 選擇“瀏覽” 選中下載還的dll庫文件。完成後工具箱中會有 treeGridView控制項,如下圖 拖動控制項到windform 中 添加代碼 參考: https://www.cnblogs.com/mrtiny/p/5174095.html ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...