百度空间 | 百度首页 
               
 
文章列表
 
您正在查看 "Xmpp" 分类下的文章

2009-06-30 21:23
Multi-user real-time web 应用目前是一个热门的方向, 如上个月Google Wave的demo就有很酷的real-time gadget demo。这些实时的web应用包括普通的web协同应用,web game, 各种SNS扩展应用及SNS game等。

此类应用前端实现有两种方式,socket/flash或ajax方式。为了达到实时效果,使用轮询的ajax通常占用服务器资源过大,目前逐渐被comet方式代替。服务器的实现通常需要开发者自行实现基于业务的socket server,但自己实现的server通常存在性能及可扩展性的问题,因此实现全部功能需要投入大量的开发精力。

Hemlock是一套适合此场景的可扩展框架。它后端使用XMPP MUC chatroom作为多人交互应用的通道,通过flash长连到XMPP Server上。由于XMPP Server(如openfire, ejabberd等)本身就支持多服务器,因此使用默认的版本就可以支持上十万的并发,如果稍加优化,同时支持上百万用户也不会有太大问题。

比如下图是用Hemlock实现一个多人聊天的实时白板程序,真实demo
(图片来源:Fancy a draw? Hemlock in action)

另外官方网站还有一个football3s多人足球游戏的demo。

安装Hemlock的文档可参阅http://hemlock-kills.com/learn,文档是以ejabberd为例的,经Tim验证也可安装在openfire/Linux上。唯一需要注意的配置是SERVER必须和xmpp domain一致。开发的环境需要用到Flex SDK, Java, Ruby, Rake等。

Hemlock底层使用jive的XIFF library, 在XMPP的基础上做了多人交互数据包的封装,并且大部分编程都可以基于事件机制,比较容易上手。大部分Web Game都有生命周期短,开发周期要求短的特点,因此使用Hemlock可以节约大量底层开发时间,有兴趣的朋友不妨一试。
类别:Xmpp | 评论(0) | 浏览()
 
2009-05-31 21:52
本周发布的Google Wave其中一个亮点就是Google Wave Federation Protocol(需翻墙)通讯协议基于XMPP。摘要如下
  • Federation 简单的解释就是分布式的互联互通,没有中心服务器。比如email, XMPP等系统都是federation的,任何公司没法对它进行控制。Google Wave Federation Protocol协议基于XMPP核心协议XMPP core [RFC3920]来扩展,实现多个wave服务器之间即时的交互通讯。
  • Waves可以理解为一种支持实时通讯的多人文档(multi-user document),它由一到多个wavelets构成。wavelet中包含一到多个具体的document。
  • 服务器之间通讯必须使用TLS(类似SSL)
  • Wave 的创建服务器通常认为拥有此wave, 在协议中称为master, 所有修改及并发操作逻辑由master负责管理。其他外域用户的服务器实际上只起一个代理作用,将本域用户的操作发送到master。多个服务器通讯,协 议中的Client和Server都是相对的,因为实际上双方都是服务器。协议上把发起方视为client。因此从单一的wave对象来看,实际上还是一 个中心服务器的架构。
下图是官方协议介绍中的一个插图,可以看到所有的用户交互都需要通过master(authoritative server)来进行。
Non-Authoritative         Authoritative
Server Server
----------------- -------------
| |
| establish connection |
| ---------------------> |
| |
| send delta operation |
| ---------------------> |
| |
| receive response | All non-authoritative
| <--------------------- | servers with
| participants
| ----------
| establish connection |
| --------------------> |
| |
| send delta operation |
| --------------------> |
| |
| receive response |

| <-------------------- |
  • 从 协议来看,虽然Wave是XMPP的协议扩展,但和XMPP目前的体系并无具体的联系,没有互联互通(wave federation不等于xmpp federation)。没有presence(在线状态), message(消息), roster(联系人)。可能和很多人想像的不一样。它只是用XMPP协议来作为载体。打个比方就像写了一个socket服务程序,用pop3协议(或扩展)来实现多机传送文件,虽然协议是POP3, 但是这个体系跟邮件没什么关系。wave与XMPP的关系也是这样。
  • 从目前来看,Wave不会代替IM,因为它没有对Presence(在线状态)的定义,但用发展的眼光来看,如果一些extension可以把xmpp presence带入的话可能情况就会发生改变,如下所示,比较期待。
participant = XMPP roster
wave = XMPP message
extension = XMPP presence

Google Wave更多介绍可参看我独立blogTim[后端技术]的介绍文章从技术角度看Google Wave,顺便抗议一下CSDN新闻频道抄过去这篇文章不加指向原文链接,明显的违反CC协议。
类别:Xmpp | 评论(2) | 浏览()
 
2009-04-06 23:35
  • Present.ly是一个偏商务方面的初创型公司的应用,用户可以通过Present.ly进入一个公司的network来micro-blogging或者update status,他们自称是 = Twitter + LinkedIn
  • Present.ly 使用 ejabberd 作为通讯平台, 目前国外使用 ejabberd 的系统越来越多,比如最近另外一个初创服务 drop.io 也使用 ejabberd 作为通讯平台。见下文引用的说明。
Present.ly
You may have noticed near-instant updates on the new web interface—this is primarily due to the super-fast messaging features of eJabberd, the XMPP server that Present.ly runs on
drop.io
We are using ejabberd, which is known for its high level of compliance with XMPP. On the front end we use the Strophe javascript library, which uses a technique called Bidirectional-streams Over Synchronous HTTP (BOSH) to connect to a Jabber server.
  • Openfire最近一两年在大规模集群方面停滞不前,而基于erlang的ejabberd天生具有良好的分布式及可扩展性,因此受到国外 很多初创项目的青睐。尽管如此,对于国内同时在线人数小于30万规模的应用,我建议还是采用Openfire,它易用性强,门槛低,更容易扩展。而大规模的互联网应用可以考虑基于ejabberd。
  • 除ejabberd外,Present.ly大部分应用都是基于ruby开发。
  • 另外产品上,感觉Present.ly目前的定位(商务网络+twitter)被facebook可替代性比较强。
类别:Xmpp | 评论(0) | 浏览()
 
2009-03-11 13:01
上个月说到关注XMPP OPEN DAY, 最近Peter Saint-Andre又组织一个类似的每月一次MUC聊天活动,首次时间在3/12 20:00 UTC (北京时间 3/13 周五 4:00am),地址 jdev@conference.jabber.org,这是一个标准的MUC房间,任何jabber客户端通过任何支持federation(s2s) 功能的服务器都可以进入,讨论的主题可能有:
  • XEP扩展协议是不是太多了,看得好晕?Too many XEPs!
  • Not enough developer-friendly documentation — can we build out the tech pages or a wiki?
  • Can’t we use Relax NG instead of W3C XML Schema?
  • Where’s that [user|developer]-friendly [client|library|server] written in [insert favorite code language here]?!?
  • XMPP people are trying to do too much (pubsub, voice, video, microblogging, etc.).
  • XMPP people aren’t doing enough (why haven’t we killed off [AIM|MSN|Skype] yet?)!
  • There’s not enough coordination and cross-pollination among projects.
  • [Add your idea/complaint/rant in the comments or on the jdev list.]
详情见 Let’s Mix ‘em Up!

另外 Peter 有意将 jabber.org 改造成一个由社区驱动的2.0版本,包括在上面提供基于jabber的 web chat room,提供资源给jabber社区进行各种前沿试验,包括VoIP。见A Vision
类别:Xmpp | 评论(1) | 浏览()
 
2009-02-20 00:50
Facebook Chat 最新进展
Facebook很多个月之前就说打算提供一个XMPP的网关,支持所有客户使用第三方XMPP客户端登录。但是这个任务迟迟没有完成。Engineering @ Facebook's Notes 提到了最新的进展
  • 最近几个月都在紧张的忙着改bug :)
  • 用户从10个月前的7千万增加到目前的1.75亿
  • 其中2/3的用户用过facebook chat
  • 最复杂的实现据称是作为HTTP网关的channel server,是erlang实现的,存放推送给客户端的message
  • presence server收集所有的cluster下用户的presence,并可一次返回用户的所有好友状态,逻辑简单, 但是传输的数据用zlib进行了压缩
  • chatloggers是c++实现的,主要瓶颈在malloc,由于太多内存碎片造成
  • 监控服务器运行有2种方法,erlang支持attach一个pid做实时分析; 另外用了Scribe来收集日志。
Scribe可参看前文 使用 Scribe 来监控大型网络系统
Facebook chat介绍也可参看前文 Facebook chat 技术架构摘要

Google App Engine将支持XMPP收发消息
A roadmap update!

支持Silverlight的XMPP library
MatriX is a XMPP library for Microsoft Silverlight web development written in c#.
Flash有XIFF的libary, 那Silverlight也有MatriX了。另外ag-software这个公司更有名的产品是.net平台的libary - agsXMPP, 国内几年前就有不少公司在用这个库了。

XMPP Summit 6 - Jingle Thingle
2/6 - 2/9 在Brussels举办的,主要的讨论都是Jingle音视频传输方面的,见raw notes from Jingle Thingle 大部分话题也可以在 Jingle mail list 上看到

pubsub and djabberd视频
今天Brad(djabberd及memcached作者)又在yahoo传道XMPP, 同时还讨论的XMPP pubsub和另外一种所谓的web hook技术的比较。这两种技术在API接口的领域(比如Twitter API)需求极为迫切,可参看更多"web hooks"讨论

黑莓与XMPP
尽管黑莓上已经有第三方软件支持XMPP,但还是有黑客大声呼吁RIM应该增加官方的支持。An open letter to RIM about IM interop for BlackBerries
类别:Xmpp | 评论(3) | 浏览()
 
2009-01-20 10:35
通常XMPP client连接服务器是无须指定IP的,比如登录 gtalk, 只需填入账号 username@gmail.com 及密码,标准的客户端都可以自动解析需要的服务器和端口连接到服务器上。这个解析就是通过DNS的SRV record来实现的。

标准的 XMPP client解析的流程为(以timyang.net为例)
  1. 解析 "_xmpp-client._tcp.timyang.net" ,获得连接的服务器和端口;
  2. 如果失败,则解析 "_jabber._tcp.timyang.net",这个主要针对老的服务器配置;
  3. 如果还是失败,则客户端认为该域没有配置SRV记录,则直接解析"timyang.net"并使用默认端口5222连接。
SRV配置方法可参看:SRV record

具体的格式为
_Service._Proto.Name TTL Class SRV Priority Weight Port Target

可使用 Linux 命令 dig 查看设置结果。

$ dig -t SRV _xmpp-client._TCP.gmail.com

; <<>> DiG 9.4.2-P2 <<>> -t SRV _xmpp-client._TCP.gmail.com
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53058
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;_xmpp-client._TCP.gmail.com.   IN   SRV

;; ANSWER SECTION:
_xmpp-client._TCP.gmail.com. 85182 IN   SRV   20 0 5222 talk3.l.google.com.
_xmpp-client._TCP.gmail.com. 85182 IN   SRV   20 0 5222 talk4.l.google.com.
_xmpp-client._TCP.gmail.com. 85182 IN   SRV   5 0 5222 talk.l.google.com.
_xmpp-client._TCP.gmail.com. 85182 IN   SRV   20 0 5222 talk1.l.google.com.
_xmpp-client._TCP.gmail.com. 85182 IN   SRV   20 0 5222 talk2.l.google.com.

;; Query time: 202 msec
;; SERVER: 208.67.222.222#53(208.67.222.222)
;; WHEN: Tue Jan 20 10:29:59 2009
;; MSG SIZE rcvd: 234


类别:Xmpp | 评论(1) | 浏览()
 
2009-01-09 23:16
XMPP Open Day是一个jack moffitt发起的有关XMPP协议完全online的活动,不用坐飞机,也不用去美国,就可以参与一次有高手演讲的互动活动。它使用的是XMPP多人聊天MUC(multi-user chat)的方式来进行,任何人都可以参与。

目前大概确定了有5名左右专家有意愿演讲,确定了大约6个议题。所有可能的议题包括:
  • XMPP primer
  • tutorials on writing XMPP bots and components
  • XMPP server setup tutorials
  • Jingle
  • PubSub
  • microblogging
  • MOM (Message-Oriented Middleware)
它的时间预计在2009年1月中旬,时间为北京时间23:00-7:00左右(15:00 UTC to 23:00 UTC),国内人员要参加可能稍不方便一点。

了解最新时间安排及进展可看它的wiki:XMPP OPEN DAY

另外2/6-2/9在欧洲还有一个 6th XMPP Summit 的活动,会议会讨论Jingle开发方面的话题。
类别:Xmpp | 评论(1) | 浏览()
 
2008-09-06 12:34
最近看到一篇文章 Thoughts On Scalable XMPP Bots, 描述构建一个大型基于IM bot的一些思路。
  • Client Bot
就是Client 自己按照IM协议作为一个普通的客户连接到服务器。普通用户添加这个bot账号之后可以进一步进行相关的业务交互。Client Bot在实现各种专有IM系统中比较常见,比如MSN bot, GTalk Bot等。

Client Bot最大的问题就是能够添加的好友列表的长度限制。因为bot是一个普通的客户端,所以普通客户端最多只能添加数百个好友的问题就成了最大的障碍。

另外由于bot通常流量过大,而且会给服务器造成额外压力,很容易被服务器当做发广告信息或垃圾信息或其他业务竞争方面的原因遭受屏蔽。

综上所述,基于client bot构建一个大型业务系统不是最佳的选择。
  • Component Bot
这个只对XMPP系统而言,XMPP中Component使用专门的协议与服务器交互。实际上component有自己的domain, 如 rabbiter 使用 rabbiter@rabbiter.DOMAIN

在 ejabberd 上,component可以使用round robin负载均衡算法,将component请求分布到多个相同component name的服务上。以实现一个跨服务器的大型业务系统。
  • S2S Bot
Bot有自己专门的域名,如 tim-bot.com, 它可以在 DNS 设置轮询使服务定向到多个具体的服务器上。但是由于此方法需要单独申请域名并配置配置独立的服务,这个做法显得有点过于复杂。

Component和S2S bot适合构建自己的基于bot的服务。比如文章开头连接中所说的Chesspark(一个实现下棋游戏的bot),以及以前介绍的Rabbiter一个开源的XMPP微博客实现
类别:Xmpp | 评论(2) | 浏览()
 
2008-08-06 00:32
最近听一个做类twitter系统的技术同行聊到 Rabbiter, 简单了解了一下,原理如下


1. Rabbiter 是一个xmpp bot,即 IM 机器人,基于 RabbitMQ 和 RabbitMQ XMPP Transport实现,即底层还是一个消息服务器

2. Rabbiter 采用 Erlang 开发,原理上具有良好的可扩展性,可支持非常大型的系统,通常跟 ejabberd 同时部署

3. Rabbiter 实现的原理上属于 XMPP PubSub

4. Rabbiter 实现的功能上目前主要是微博客(microblogging)的功能,支持的指令包括 follow, unfollow, following, followers 等。(微博客是twitter, 饭否之类系统)

5. Rabbiter 可以实现 MUC (多人聊天) 或群功能,比如用户A/B/C/D互相follow, 就成了一个多人群体

6. 所有 Client 订阅信息都是 PUSH 过去, 原理上可以避免 twitter 目前遇到的 API 负荷过大问题。

这个是我1年前关于 XMPP 与 Microblogging 不成熟的想法:Twitter中文版类似系统实现的技术构想。那现在 Rabbiter 则是可用的 XMPP/Microblogging 产品了。

Rabbiter的网站及下载地址为:http://github.com/tonyg/rabbiter/tree/master
类别:Xmpp | 评论(0) | 浏览()
 
2008-05-14 23:46
XMPP Server(IM Server)不像Web Server有十分标准的性能评测工具, 一个新的IM服务器拿到之后,通常并没有十分方便的方式来进行测试性能。

通常我们只能依赖网上的数据来衡量某个服务器产品的性能。但是网上的数据通常并不准确,因为测试的环境, 测试的指标不同,测试的方法有差异,得到的结果并没有直接的可比性。我们去验证某些测试结果,得出的数据有2~3倍的差异并不奇怪。

因此最好通过自己的环境去验证这些产品的性能指标,所以构建一套简单的性能测试工具十分重要。目前想到的测试一个XMPP Server的几种方案。
  • 使用 Smack API, 它是一个 Java 的XMPP Client Library,也是由Jive Software开发。
  • 使用 Java Socket异步NIO select方式, 模拟XMPP登录。XML可直接用string构建,可直接根据XML返回结果的特征字符判断调用是否成功。如使用XML library来解析可能会造成部分自身瓶颈。
    • 优点:可以模拟更多的客户连接。1台客户机可以模拟数万个用户同时操作。
    • 编程稍复杂,需要熟悉Java NIO async socket,或相关框架,如Mina
    • 代码示例,使用MINA模拟客户端连接到服务器

/**
* Use mina client to connect xmpp server
* @author Tim
*
*/
public class XmppClient {
public static void main(String[] args) {
String hostname = "server";
int port = 5222;

SocketConnectorConfig cfg = new SocketConnectorConfig();
cfg.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory()));

for (int i = 1; i <= 2; i++) {
SocketConnector connector = new SocketConnector();
connector.connect(new InetSocketAddress(hostname, port),
new XmppProtocolHandler("tim" + i, "tim", "mina"), cfg);
}
}
}

class XmppProtocolHandler extends IoHandlerAdapter {
String username = "tim";
String password = "tim";
String server = "server";
String bareJid = username + "@" + server;
String resource = "mina";

public XmppProtocolHandler(String username, String password, String resource) {
this.username = username;
this.password = password;
this.resource = resource;
this.bareJid = username + "@" + server;
}

@Override
public void sessionClosed(IoSession session) throws Exception {
System.err.println("Closed. Total " + session.getReadBytes() + " byte(s)");
}

@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
ByteBuffer buf = (ByteBuffer) message;
while (buf.hasRemaining()) {
System.out.print((char) buf.get());
}
System.out.flush();
}

@Override
public void sessionOpened(IoSession session) throws Exception {
sendPacket(session, sendStream(true));
Thread.sleep(50);
sendPacket(session, sendAuth(username, bareJid, password));
Thread.sleep(200);
sendPacket(session, sendStream(false));
Thread.sleep(50);
sendPacket(session, sendResource(username, resource));
Thread.sleep(50);
sendPacket(session, sendPresence(username));
}

private String genPassword(String bareJid, String username, String password) {
String str = bareJid + "\0" + username + "\0" + password;
BASE64Encoder base64 = new BASE64Encoder();
return base64.encode(str.getBytes());
}

private StringBuilder sendStream(boolean addHeader) throws IOException {
StringBuilder sb = new StringBuilder();
if (addHeader)
sb.append("<?xml version='1.0' encoding='UTF-8'?>");
sb.append("<stream:stream to=\"").append(server)
.append("\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" version=\"1.0\">");
return sb;
}

private StringBuilder sendAuth(String username, String bareJid,
String password) throws IOException {
String pwd = genPassword(bareJid, username, password);
StringBuilder sb = new StringBuilder();
sb.append("<auth mechanism=\"PLAIN\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">")
.append(pwd).append("</auth>");
return sb;
}

private StringBuilder sendResource(String username,
String resource) throws IOException {
StringBuilder sb = new StringBuilder();
sb.append("<iq id=\"").append(username)
.append("-0\" type=\"set\"><bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"><resource>")
.append(resource).append("</resource></bind></iq>");
return sb;
}

private StringBuilder sendPresence(String username)
throws IOException {
StringBuilder sb = new StringBuilder("<presence id=\"")
.append(username).append("-2\" />");
return sb;
}

private void sendPacket(IoSession session, StringBuilder sb) throws Exception {
sb.append("\r\n");
System.out.println(sb.toString());
session.write(sb.toString());
}
}
  • 使用 tsung, tsung使用erlang开发,利用了erlang并发编程的优势,可以从一到多个客户机向发起xmpp请求。
    • 优点:利用现成的工具,无需开发。测试过程使用XML来配置,不需要改动源代码。
    • 缺点:配置和扩展复杂,学习成本,适应成本及扩展成本大。
  • 使用 Python 等动态语言开发,如PyXMPP
    • 优点:开发及重构效率比Java稍快,可以更多关注测试模型及指标本身。而不是测试程序怎么实现。
    • 缺点:需要开发人员熟悉相关语言及特性。另外同样有 one thread per client 的问题,占用客户端资源过高。可能要几台客户机才能搞定一台服务器。
    • 代码示例,下面例子可以对实现一个Python的client有个基本了解,详细可参考 PyXMPP examples 下面的例子。
class MyClient(Client):
def session_started(self):
self.stream.send(Presence())

def idle(self):
print "idle"
Client.idle(self)
if self.session_established:
target=JID("tim2",s.jid.domain)
self.stream.send(Message(to_jid=target,body=unicode("测试","utf-8")))

def post_disconnect(self):
print "Disconnected"
raise Disconnected

logger=logging.getLogger()
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.DEBUG)

libxml2.debugMemory(1)

print "creating stream..."
s=MyClient(jid=JID("tim@server/Test"),password=u"tim",auth_methods=["sasl:DIGEST-MD5","digest"])

print "connecting..."
s.connect()

print "processing..."
try:
try:
s.loop(1)
finally:
s.disconnect()
except KeyboardInterrupt:
traceback.print_exc(file=sys.stderr)
except (StreamError,Disconnected),e:
raise

libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print "OK"
else:
print "Memory leak %d bytes" % (libxml2.debugMemory(1))
libxml2.dumpMemory()
类别:Xmpp | 评论(3) | 浏览()
 
     
 
 
文章分类
 
 
Jep(11)
 
Xmpp(21)
 
 
 
 
 
Mysql(10)
 
 
 
 
 
 
 
 
Xep(1)
 
 
     
 
文章存档
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
     
 
最新文章评论
   
 

这个屌,谁都骂
 

回复匿名网友:java -Xmx 1024m
 
 

占用贵博客。宣传一下http://Google.wavebbs.cn
 
     


©2009 Baidu