C#连接基于Java开发IM——Openfire

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 outlock (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 classif (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 classif (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("testa@118.89.48.159", 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 TODOreturn false;}}#endregionpublic static implicit operator XmppClientConnection(XmppLogin v){return v.xmppCon;}}

  至此,Openfire连接成功。
  最近忙而且也刚开始弄这个,过几天更新一下XmppConnection下各种属性、事件、函数的具体用法。

我的掘金:WarrenRyan

我的简书:WarrenRyan

欢迎关注我的博客获得第一时间更新 https://blog.tity.online

我的Github:StevenEco

我的博客园:WarrenRyan

转载于:https://www.cnblogs.com/WarrenRyan/p/10406535.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/264755.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数字万用表的使用

参考&#xff1a;连3岁小孩子都能看懂的万用表使用方法 地址&#xff1a;https://www.bilibili.com/video/BV1Gx411z7x2?p1&vd_sourcecc0e43b449de7e8663ca1f89dd5fea7d 目录万用表外观测量电阻测量通断/二极管测量电容测量温度测量电流测量电压测量三极管万用表外观 测量…

程序员讨论 《黑客帝国》 (三) 情感

人总会与人比较&#xff0c;找出自己拥有而别人没有的东西&#xff0c;从而建立起自信心。早期机器就已经在记忆和运算能力上超越人类&#xff0c;于是人类嘲笑机器没有智慧&#xff0c;突然有一天机器出现了智慧&#xff0c;能解决复杂问题&#xff0c;学会“骗人”了。人类傻…

在GridView开头插入自动编号的方法

网上看了很多方法&#xff0c;发现都是照抄别人&#xff0c;而且&#xff0c;都是把第一列替换掉了&#xff0c;往往不是我们的理想结果。经过本人的实践&#xff0c;下面方法觉得更好用一些。就是不知道数据量过大时&#xff0c;效率怎么样&#xff0c;不过既然能用&#xff0…

python数据整理 高一_关于Python爬虫的最全知识梳理,项目经理花了三天总结出来的经验...

作爲零基础小白&#xff0c;大体上可分爲三个阶段去完成&#xff0c;第一阶段是入门&#xff0c;掌握必备基础知识&#xff0c;比如Python基础、网络央求的基本原理等&#xff0c;第二阶段是模仿&#xff0c;跟着别人的爬虫代码学&#xff0c;弄懂每一行代码&#xff0c;熟习主…

GNS3中不同型号路由器支持的模块表

Dynamips 支持的模块C7200 开始Slot 0:C7200-IO-FE <------> 支持1 个Fastethernet 接口C7200-IO-2FE <------> 支持2 个Fastethernet 接口(DynamipsGUI 2.3 里面没有这个选项,想用只有自己添加了)C7200-IO-GE-E <------> 插这个卡以后会同时出现2 个端口,Et…

南京:第三届软博会“外包”将唱主角

南京&#xff1a;第三届软博会“外包”将唱主角 新华网江苏频道2007-08-17 09:10:31 来源: 本网综合 据《江南时报》报道&#xff0c;再过半个月&#xff0c;名列“中国十大知名展会品牌”之一的南京“软博会”——第三届中国&#xff08;南京&#xff09;国际软件产品博览会将…

vue鼠标右键自定义菜单_vue-右键菜单功能

[TOC]>[success] # :-: vue-右键菜单功能[在线demo点击我](https://xunleif2e.github.io/vue-context-menu/demo/dist/#/)项目中有时候会有右键菜单的需求&#xff0c;所以在github找了一个[右键菜单](https://github.com/xunleif2e/vue-context-menu)的插件&#xff0c;使用…

Zookeeper:fsync超时导致实例异常

一、问题描述 2019-02-19 08:44左右&#xff0c;实时计算服务重启&#xff0c;报错显示找不到zk集群的leader节点&#xff0c;同时ZooKeeper集群有告警显示连接超时&#xff1a; 指标[连接耗时(ms)18221]符合告警规则[连接耗时(ms)>3000] 二、排查过程 查看当前集群状态&…

断言(assert)的用法

参考&#xff1a;https://www.runoob.com/w3cnote/c-assert.html 目录作用总结与注意事项Demo作用 assert 是个宏&#xff0c;并且作用并非"报错"。 assert() 的用法像是一种"契约式编程"&#xff0c;程序满足我的假设条件&#xff0c;才能正常良好的运作…

oracle 变量

插入 日期时间 循环插入 declaretotal date: trunc(sysdate-1) ;beginfor i_count in 1..10000 LOOPinsert into DQ_DATE(date_time) values ( total );total : total 1/24;end loop; end; 转载于:https://www.cnblogs.com/kingxiaozi/p/3790327.html

马云语录,非常值得一看(转)

来源:计算机网1999至今 在杭州设立研究开发中心&#xff0c;以香港为总部&#xff0c;创办阿里巴巴网站(Alibaba.com) 孙正义跟我有同一个观点&#xff0c;一个方案是一流的Idea加三流的实施&#xff1b;另外一个方案&#xff0c;一流的实施&#xff0c;三流的Idea&#xff0c;…

keepalived mysql双主架构图_基于keepalived Mysql双主热备配置

基于keepalived双主热备:一.环境:OS:CentOS 6.5 X64DB Version:Percona Mysql 5.7.15-9-log路径:/app/mysql57数据文件路径:/data/mysql57/dataDB1:192.168.213.4DB2:192.168.213.5二.安装keepalived包(两台主机都需操作)1.下载keepalived包cd /usr/local/toolswget http://www…

centos7 docker安装和使用_入门教程

centos7 docker安装和使用_入门教程 原文:centos7 docker安装和使用_入门教程说明&#xff1a;本文也是参考互联网上的文章写的&#xff0c;感谢相关作者的贡献。 操作系统 64位CentOS Linux release 7.2.1511 (Core) 配置好IP&#xff1a;192.168.1.160 修改yum源 目的是提升对…

公钥、私钥、数字签名和数字证书

参考:公钥、私钥、数字签名和数字证书的概念及解密 地址:https://blog.csdn.net/oscar999/article/details/123489420 作者:oscar999 目录 概念解析https 的非对称加密和对称加密如何产生密钥和证书使用keytool 产生公私钥到一个密钥库文件中从密钥库文件导出证书openssl 将…

curl命令具体解释

对于windows用户假设用Cygwin模拟unix环境的话&#xff0c;里面没有带curl命令&#xff0c;要自己装&#xff0c;所以建议用Gow来模拟&#xff0c;它已经自带了curl工具&#xff0c;安装后直接在cmd环境中用curl命令就可&#xff0c;由于路径已经自己主动给你配置好了。 linux …

[转] SQL2000 关于 Java JDBC 驱动的安装和设定

1、首先要记得sql2000 要打上sp3以上的补丁.(建议用sp4)2、装上SQL Server 2000 Driver for JDBC Service Pack 3下载地址:http://www.microsoft.com/downloads/details.aspx?FamilyId07287B11-0502-461A-B138-2AA54BFDC03A&displaylangen3、安装完SQL Server 2000 Driver…

wxpython 可视化开发pdf_MicroPython for the Internet of Things.pdf

标签&#xff1a;MicroPythonMicroPythonPythonPythonIoTiot是Internet Of Things的缩写&#xff0c;字面翻译是“物体组成的因特网”&#xff0c;准确的翻译应该为“物联网”。物联网(Internet Of Things)又称传感网&#xff0c;简要讲就是互联网从人向物的延伸。“物联网”(I…

PAT A1149 Dangerous Goods Packaging (25 分)——set查找

When shipping goods with containers, we have to be careful not to pack some incompatible goods into the same container, or we might get ourselves in serious trouble. For example, oxidizing agent &#xff08;氧化剂&#xff09; must not be packed with flamma…

C语言中字符串和字符数组的区别

参考&#xff1a;C语言中字符串和字符数组的区别 参考&#xff1a;字符数组和字符串的区别&#xff0c;C语言字符数组和字符串区别详解 这里写目录标题区别代码分析一代码分析二总结区别 &#xff08;1&#xff09;C语言中&#xff0c;没有字符串类型但可以用字符数组模拟字符…

spring in action 读书笔记

IOC 1.几个主要使用的application context. ClassPathXmlApplicationContext 从ClassPath路径加载 FileSystemXmlApplicationContext 从文件系统路径加载XmlWebApplicationContext 配置文件黑夜在/WEB-INF/applicationContext.xml&#xff0c;也可以使用setConfigLocation…