使用Google App Engine的XMPP服务

XMPP作为IM通讯标准协议已经得到了广泛的应用。Sametime, Gtalk 以及Cisco Webex Connect都是基于XMPP协议的IM产品。GAE前一段时间推出了XMPP服务.也许是希望能有更多支持gtalk的服务出现,从而推进gtalk的发展吧.
最近终于有空试用了一下,感觉还不错.想想普通的Web hosting由于缺少独立IP,没有办法实现端口映射,所以基本没有办法用来部署IM机器人。如今有了GAE的XMPP服务,做一个相关的机器人就不只是梦了。如果有同学想在Gtalk,Webex Connect以及其他基于XMPP的IM平台上开发机器人的话,GAE绝对是一个不错的选择.

XMPP消息发送
GAE提供了完整的XMPP类库。你可以在你的web应用中对用户发送XMPP应用或者邀请.示例代码如下.

import com.google.appengine.api.xmpp.JID;
import com.google.appengine.api.xmpp.Message;
import com.google.appengine.api.xmpp.MessageBuilder;
import com.google.appengine.api.xmpp.SendResponse;
import com.google.appengine.api.xmpp.XMPPService;
import com.google.appengine.api.xmpp.XMPPServiceFactory;
...
String Content = "Hello World";
JID jid = new JID("abc@gmail.com");
Message msg = new MessageBuilder()
.withRecipientJids(jid).withBody(content).build();
XMPPService xmpp = XMPPServiceFactory.getXMPPService();
String result = null;
if (xmpp.getPresence(jid).isAvailable()) {
SendResponse status = xmpp.sendMessage(msg);
if ( status.getStatusMap().get(jid) == SendResponse.Status.SUCCESS){
result = "Success";
}
else{
result = "Failed";
log.info(status.getStatusMap().get(jid).toString());
}
}
else{
xmpp.sendInvitation(jid);
}

XMPP消息接收
XMPP服务支持app-id@appspot.com,anything@app-id.appspotchat.com以及anything@version.latest.app-id.appspotchat.com三种ID,发送到这三种ID的XMPP消息都会自动mapping到下面的URL.该URL默认只能admin才能访问,无须再在web.xml中进行安全配置.

/_ah/xmpp/message/chat/

在web.xml中将此URL映射到你的servlet之后,就可以对发送的XMPP消息进行处理了.

@SuppressWarnings("serial")
public class XMPPReceiverServlet extends HttpServlet {
private static final Logger log = Logger
.getLogger(XMPPReceiverServlet.class.getName());
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws IOException {
XMPPService xmpp = XMPPServiceFactory.getXMPPService();
Message message = xmpp.parseMessage(req);
JID fromJid = message.getFromJid();
String body = message.getBody();
log.info("Receive Message: " + body + " from " + fromJid);
String response = "Echo:"+fromJid.getId();
message = new MessageBuilder().withRecipientJids(fromJid).withBody(
response).build();
xmpp.sendMessage(message);
}
}
}

如上所示,GAE的XMPP提供方便的辅助工具帮你从HTTP参数中获得Message信息.

Message message = xmpp.parseMessage(req);

注意:对GAE XMPP服务ID的添加邀请都会被自动接收,但是邀请无法通知到应用中.

目前XMPP的不足
目前GAE XMPP服务的不足主要包括下面四个方面.

  • 开发与调试不便
  • 无法使用自定义域名
  • 无法判断用户状态
  • 性能限制

开发与调试不便
目前Google App Engine SDK不支持XMPP 服务.只能提供最基本的编译功能.所以如果你想要开发发送或者接收XMPP消息的功能.唯一的办法只有实现编译无误以后上传到Google App Engine上进行测试调试.麻烦可见一斑.

无法使用自定义域名
目前Google App Engine支持的XMPP地址只有@appspot.com和@app-id.appspotchat.com两种.不过考虑到App Engine的Web 服务已经支持了自定义域名.XMPP服务对自定义域名帐号的支持,也是可以期待的一件事情.

无法判断用户状态
目前GAE XMPP服务只能识别对方用户”在线”和”离线”两种状态.作为XMPP特色之一,自定义状态已经被各大IM工具广泛的推广了.尤其是Cisco Webex Connect集成了UC之后添加的”In a Meeting”,”In a Webex Meeting”,”On phone”等状态,让人用的非常舒服.希望GAE XMPP服务的未来版本能对它有所支持,阿门.

性能限制
和普通Web服务一样,GAE的XMPP服务也要受到网络带宽,CPU,内存等各方面的限制.除此之外,对发送的XMPP消息长度也有一定的限制.具体的数据可以参考资料来源中的介绍.皑皑,免费的,还能说啥呢.

OK了,还等什么,做一个属于你自己的XMPP bot吧.
资料来源
Google App Engine, The XMPP Java API

 

Jabber与Asterisk的整合

虽然Skype风雨飘摇,但是它的成功不言而喻,一个小小的聊天软件居然还能打电话,酷阿。
 
前一段日子装了Openfire(Jabber),聊天的一套有了。
最近玩了Asterisk(PBX),能打电话了。
嗯,整整吧。
 
没办法,伟大的人总归想的都是一样的(-,-),
这方面的需求显然是非常炙热的,整合的办法也有很多种。
 
在Openfire中整合Asterisk
0Asterisk必须安装AMI
1在Openfire中安装Asterisk-IM的plugin
2配置Asterisk服务器信息。Asterisk-IM->General Settings(user/pwd为AMI帐号)
3将Openfire用户与Phone匹配。Asterisk-IM->Phone Mapping(Device的格式类似SIP/2000)
这个plugin的作用是通过AMI(Asterisk Manager API)获得Phone的状态变化信息。
具体的效果就是Spark上用户的状态会变为"On the Pone",or "Available".
不过可以把它的AMI Client偷过来自己用,娃哈哈)
 
4在Openfire中安装SIP Phone Plugin
5配置SIP Server信息.Server->Phone->Sip Settings
(没有NAT所以没有配STUN,voicemail实在不知道干啥用这里,随便写了)
6将PHONE与Openfire用户匹配.Server->Phone->Sip Phone Mapping(其实为什么不和上面那个Plugin整合呢)
7在Spark上安装SIP Phone Plugin,关闭,重启
这套Plugin要强大的多,提供了基本的SIP Softphone的功能,可以Call,Hold等等。
实现用了OpenSource的SIP包,娃哈哈可以偷过来玩)
 
OK.顺利的话,你的Spark就进化成为了SIP Softphone!
终于有了第二个SoftPhone,欢快的地给Xlite打了一个电话。
这个方案最大的问题是对客户端的依赖。
不管是Status的变化还是Sip Phone,换成其他的都不行。
 
P.S.配置之中遇到的最大问题是Spark一直没办法注册到Asterisk上。
搞了半天最后才搞定。总结下来最有可能是以下两方面问题。
1原来Openfire上Asterisk的地址配的是localhost,可能Phone直接拿了这个地址去连接。
2最后Spark卸载了重装就好了,可能是本身Configuration没有更新。
 
在Asterisk中整合Jabber
其实Asterisk本身也整合了Jabber的功能(皑皑,蛋糕就这么大,谁都想吃)
1.4以后的版本都包含了Jabber Module,可以作为Jabber Client或者Component进行实用。
1作为Jabber Client,可以通过两个Application(jabbersend,jabberstatus)
在extension.conf中发送XMPP消息
2作为Jabber Component
可以在jabber.conf中配置Jabber Server
让Asterisk作为Jabber Component与Server通讯。(还不知道具体啥样子呢-。-)
 
这部分都没有试过。因为具体的效果就是那样
而且我也不确定Jabber Server是否对这种通讯支持良好。
皑皑,毕竟有上面那种比较完善的解决方案在了。。。
 
 
 
 
 
 

 

无觅相关文章插件,快速提升流量