.net平台 基于 XMPP协议的即时消息服务端简单实现
.net平台 基于 XMPP协议的即时消息服务端简单实现
昨天抽空学习了一下XMPP,在网上找了好久,中文的资料太少了所以做这个简单的例子,今天才完成。公司也正在准备开发基于XMPP协议的即时通讯工具所以也算是打一个基础吧!如果你还没有了解过XMPP请先阅读附录中链接的文章,本实例是基agsXMPP上开发的,agsXMPP是C#写的支持开源XMPP协议软件,我们可以在agsXMPP上快速构建自已的即时通讯平台,我的这个例子只是修改了服务器端,因为agsXMPP本身自带的服务器端没有实现聊天功能、签名和登录密码认证。
服务器端XmppSeverConnection类事件
streamParser.OnStreamStart += new StreamHandler(streamParser_OnStreamStart);
//在流结束时触发,一般是发送</stream:stream>并关闭套接字连接streamParser.OnStreamEnd += new StreamHandler(streamParser_OnStreamEnd);
//在接收到流结点时触发,这是用得最多的,常用的<message>消息,<Presence>出席消息,< IQ>请求应答消息都在这里处理
streamParser.OnStreamElement += new StreamHandler(streamParser_OnStreamElement);
private void streamParser_OnStreamElement(object sender, Node e)
{
Console.WriteLine("OnStreamElement: " + e.ToString());
if (e.GetType() == typeof(Presence))
{
// 路由presences节
}
else if (e.GetType() == typeof(Message))
{
// 路由messages节
}
else if (e.GetType() == typeof(IQ))
{
//处理IQ节
}
}
/// IQ节处理函数
/// </summary>
/// <param name="iq">.</param>
private void ProcessIQ(IQ iq)
{
if (iq.Query.GetType() == typeof(Auth))
{
Auth auth = iq.Query as Auth;
this.Username = auth.Username.ToString();
switch (iq.Type)
{
case IqType.get:
iq.SwitchDirection();
iq.Type = IqType.result;
auth.AddChild(new Element("password"));
auth.AddChild(new Element("digest"));
Send(iq);
break;
case IqType.set:
// 进行登录认证
if (AccountBus.CheckLogin(auth.Username, auth.Digest, this.SessionId))
{
iq.SwitchDirection();
iq.Type = IqType.result;
iq.Query = null;
Send(iq);
Console.WriteLine(auth.Username + "登录了" + " 登录时间:" + System.DateTime.Now.ToString());
}
else
{
//登录失败返回错误信息
iq.SwitchDirection();
iq.Type = IqType.error;
iq.Query = null;
Send(iq);
}
break;
}
}
else if (iq.Query.GetType() == typeof(Roster))
{
ProcessRosterIQ(iq);
}
}
/// 处理IQ节的杂项数据.
/// </summary>
/// <param name="iq">The iq.</param>
private void ProcessRosterIQ(IQ iq)
{
if (iq.Type == IqType.get)
{
// 发送IQ节的杂项数据
//这里我用来下载好友列表
iq.SwitchDirection();
iq.Type = IqType.result;
List<string> friendList = new List<string>();
friendList = AccountBus.GetFriendName(this.username);
foreach (string str in friendList)
{
RosterItem ri = new RosterItem();
ri.Name = str.Trim();
ri.Subscription = SubscriptionType.both;
ri.Jid = new agsXMPP.Jid(str.Trim() + "@localhost");
ri.AddGroup("localhost");
iq.Query.AddChild(ri);
}
Send(iq);
}
}
服务器端开启监听5222端口
{
////
allDone.Reset();
// Start an asynchronous socket to listen for connections.
Console.WriteLine("等待连接");
listener.BeginAccept(new AsyncCallback(AcceptCallback), null);
//// 等待客户端连接
allDone.WaitOne();
}
如果收到客户端请求就异步调用AcceptCallback初始化套接字连接
,并为客户端建立一个通信线程,新建初始化套接字连接采用异步调
用读取套接字信息
: this()
{
m_Sock = sock;
m_Sock.BeginReceive(buffer, 0, BUFFERSIZE, 0, new AsyncCallback(ReadCallback), null);
m_Sock.SendTimeout = 100;
}
客户端与服务器端的交互过程
1客户端异步向服务器端发送连接请求
<stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' xml:lang='en'>
2服务器端收到请求,初始化回应流,并随机生成一相SessionID
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" from="localhost" id="30e3b8c0" >
3等待服务器返回消息后客户端发送用户名(由于在客户端采用了异步调用
方式,所以UI界面感觉不到等待)
<iq xmlns="jabber:client" id="agsXMPP_1" type="get" to="localhost">
<query xmlns="jabber:iq:auth"><username>test</username></query></iq>
4服务器端收到用户名等待用户提供密码
<iq xmlns="jabber:client" from="localhost" type="result" id="agsXMPP_1">
<query xmlns="jabber:iq:auth"><username>test</username><password />
<digest /></query></iq>
5客户端提供加密后的密码
<iq xmlns="jabber:client" id="agsXMPP_2" to="localhost" type="set">
<query xmlns="jabber:iq:auth"><username>test</username>
<digest>e66557d2b67256bf7e9b317a51b6101674a56b5e</digest>
<resource>MiniClient</resource></query></iq>
6服务器端从数据库验证用户名和密码,并返回结果
iq xmlns="jabber:client" from="localhost" type="result" id="agsXMPP_2" />
7如果返回错误,客户端提示并终断连接,否则客户端发送响应数据
8 服务器端返回数据
9 客户端发送状态,
10服务器收到状态,发送IQ节并通知其它用户.
项目解决方案和类图
附录:
推荐使用Pandion作为客户端
服务器端下载 客户端下载agsXMPP 源码下载
XMPP RFC 3920 可扩展消息出席协议
jabber官方网站
.net平台 基于 XMPP协议的即时消息服务端简单实现的更多相关文章
- 基于XMPP协议的手机多方多端即时通讯方案
一.开发背景 1.国际背景 随着Internet技术的高速发展,即时通信已经成为一种广泛使用的通信方式.1996年Mirabilis公司推出了世界上第一个即时通信系统ICQ,不到10年间,即时通信(I ...
- MQTT的学习研究(八)基于HTTP DELETE MQTT 订阅消息服务端使用
HTTP DELETE 订阅主题请求协议和响应协议http://publib.boulder.ibm.com/infocenter/wmqv7/v7r0/topic/com.ibm.mq.csqzau ...
- 基于XMPP协议的Android即时通信系
以前做过一个基于XMPP协议的聊天社交软件,总结了一下.发出来. 设计基于开源的XMPP即时通信协议,采用C/S体系结构,通过GPRS无线网络用TCP协议连接到服务器,以架设开源的Openfn'e服务 ...
- 基于XMPP协议(openfire服务器)的消息推送实现
转自:http://blog.csdn.net/nomousewch/article/details/8088277 最近好像有不少朋友关注Android客户端消息推送的实现,我在之前的项目中用到过J ...
- python测试基于websocket协议的即时通讯接口
随着html5的广泛应用,基于websocket协议的即时通讯有了越来越多的使用场景,本文使用python中的websocket-client模块来做相关的接口测试 import webclient ...
- IOS基于XMPP协议开发--XMPPFramewok框架(一):基础知识
最近蘑菇街团队的TT的开源,使我对im产生了兴趣,然后在网上找到了XMPPFramework进行学习研究, 并写了以下系列教程供大家参考,有写的不对的地方,请大家多多包涵指正. 目录索引 IOS基于X ...
- 通过集群的方式解决基于MQTT协议的RabbitMQ消息收发
在完成了基于AMQP协议的RabbitMQ消息收发后,我们要继续实现基于MQTT协议的RabbitMQ消息收发. 由于C#的RabbitMQ.Client包中只实现了基于AMQP协议的消息收发功能的封 ...
- 开源jabber(XMPP)架设内部即时通讯服务的解决方案
Jabber 是著名的即时通讯服务服务器,它是一个自由开源软件,能让用户自己架即时通讯服务器,可以在Internet上应用,也可以在局域网中应用. XMPP(可扩展消息处理现场协议)是基于可扩展 ...
- “一切都是消息”--iMSF(即时消息服务框架)入门简介
“一切都是消息”--这是iMSF(即时消息服务框架)的设计哲学. MSF的名字是 Message Service Framework 的简称,由于目前框架主要功能在于处理即时(immediately) ...
随机推荐
- COM RTS/CTS, DTR/DSR
COM: 串行通讯端口cluster communication port它是串行接口,现在的PC 机一般有两个串行口COM 1 和COM 2 .串行口不同于并行口之处在于它的数据和控制信息是一位接一 ...
- 优化web前端性能的几个方法
1 减少http请求, a. 合并脚本跟样式文件,如可以把多个 CSS 文件合成一个,把多个 JS 文件合成一个. b. CSS Sprites 利用 CSS background 相关元素进行背景图 ...
- MySQL5.7源码安装问题汇总
编译安装mysql5.7版本,想试用一下新的版本特性,发现跟之前的5.6版本编译有了一些变化,总结一下避免以后继续入坑.5.6安装方式 cmake版本 5.7编译cmake要求版本最低为2.8,当前为 ...
- xmlSerializer属性的使用
学习了XmlAttribute,XmlElement属性的定义和使用. Order类定义 using System; using System.Collections.Generic; using S ...
- Cow Navigation(USACO)
题目大意: 给定一个N*N的矩阵,并告诉你每一个格子能否经过,要求你求出(n,1)到(1,n)的最短路径的操作数. 其中操作有2种,第一种是沿着目前的方向走一格,第二种是向左或向右转90° 由于题目设 ...
- UVA 10229 Modular Fibonacci
斐波那契取MOD.利用矩阵快速幂取模 http://www.cnblogs.com/Commence/p/3976132.html 代码: #include <map> #include ...
- java 24小时倒计时案例
import java.util.Calendar; import java.util.Date; public class Daojishi { static String Countdown=&q ...
- WINFORM写入COOKIE
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)] public static exte ...
- 设计模式原则总结--读《大话设计模式》有感 <转>
读了<大话设计模式>,摘录该书中讲到的设计模式几大原则,供日后使用. 一.单一职责原则 就一个类而言,应该仅有一个引起它变化的原因.如果一个类承担的职责过多,就等于把这些职责耦合在一起,一 ...
- 牛客网暑期ACM多校训练营(第一场) - J Different Integers(线段数组or莫队)
链接:https://www.nowcoder.com/acm/contest/139/J来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 524288K,其他语言1048 ...