飞信2010分析 – 给离线好友发送消息
今天发这篇文章刚好是全国哀悼玉树地震的中遇难的日子,整个互联网都很悲伤。的确,我也是亲身经历过汶川的地震,经历过那种面对死亡的恐惧和重生过后的喜悦。
汶川地震,我们活着,我们是幸运儿。我们每一个在这场大劫中余生的人,都应该有一种获得重生的净化。在自然面前,人的生命是那么的脆弱。活着,比一切都好。这是地震给我最大的感触。
而在地震中不幸遇难的人们,我们应该为他们祈福,愿他们在天堂活得快乐……阿门····
谨以此文纪念在玉树地震以及汶川地震中死去的同胞们!
飞信发送消息用的是SIP协议里面的标准的M请求。飞信给客户端在线的好友和短信在线的好友发送消息的方式是不同的。我们来先看给状态为短信在线或离线的好友发送消息。
注意我这里说的是消息。飞信由于有短信就有点复杂。解释一下:飞信用户可以给飞信好友发送消息(只要是在用户好友列表里面的用户都视为飞信好友,无论是否开通飞信),
1.如果用户在线,消息直接通过聊天服务器中转后直接发送给客户端。
2.如果好友不在线,
a.好友设置为飞信客户端离线时使用手机短信接收飞信消息,给该好友发送的消息就通过飞信的短信服务器直接通过手机短信的方式把消息发送到好友的手机上,
b.用户设置为客户端不在线不用手机接收飞信消息,飞信服务器就保存用户发送的消息,不发送到好友的手机,然后等待好友再次登录客户端后才发送给好友。
现在来说明好友URI为sip:111111111@fetion.com.cn;p=1111,状态为短信在线或者离线或者隐身,发送和接收飞信消息的交互过程。(如何判断好友是客户端在线,还是短信在线,还是离线,请参见我上一篇文章。)
下面是飞信客户端“主动”向好友发送消息(不是短信),请求和回复如下
F就是飞信号,前几篇文章已经说明了,注意请求中的T,就是To,写明了短消息接收方的URI地址,这个URI可以在登录成功后返回的好友列表中获取到。 前面说过,开通飞信的URI和未开通飞信的URI是不同的,未开通飞信的URI的格式是tel:159xxxxxxxx,倘若知道好友的电话号码,却不知道好友的URI,发送消息时用tel:159xxxxxxxx这样的URI发送消息是不能成功的。但可以通过其他的方式获取到URI,后面会详细说明。
C = Content-Type,消息的格式。有两种:
text/plain,这种是文本格式,就是说消息内容不含有任何格式信息;
text/html-fragment:带有格式信息的消息,字体,大小,颜色,就这三种。如hello。
一般说来,发送手机短信的时候就用text/plain无格式的消息,给用客户端登录的好友就用text/html-fragment格式的消息,客户端可以解析并显示这样的格式的信息。
K(Supported): SaveHistory 不清楚啥含义。
N(Event) : CatMsg,这里说明了消息类型,CatMsg就是飞信消息。这里为SendCatSMS就是发送短信,也就是无论好友客户端是否在线,都会直接发送到好友的手机上。
后面的就是SIP信令里面定义的消息体了,即为消息内容。
来看下回复。发送成功后一般来说有两种状态
200 OK:发送消息成功,如果对方离线就保存到服务器等待好友下次客户端登陆时候发送给好友。如果对方隐身,将直接发送到客户端。因为隐身和离线状态码都是0,无法判断。
280 Send SMS OK:发送消息成功,对方客户端不在线,但设置了手机接收消息,消息通过短信方式的发送到对方手机上。这个和200的状态消息内容不一样。如下:
可以看出,当发送短信成功的时候,返回了一个配额使用统计。
飞信每天发送到手机的短信都是有一定的限制的,以前测试过,飞信最多每天可以发送750条消息到手机上,每月好像是1000条,没有测试。官方没说,只能猜想。所以用飞信做点小的应用是可以的,想做大的短信应用还是使用短信猫或者其他的短信平台才行。虽然发送到手机短信的信息有限制,但给客户端发送的消息没有限额任何限制。
当然,如果超过了这个限制发送就会失败,返回如下
OK,说完了客户端主动向好友发送信息,那好友主动的向用户发信息呢?
因为好友不在线,这种情况只能是好友通过手机回复收到的飞信短信发送信息。手机消息发送方的号码为12520159xxxxxxx这都是飞信网关发送给好友手机的短信。
好友主动给用户发信息是通过一条通知(这里把服务器主动发送给客户端的消息称为一个通知),这是服务器主动发送过来的SIP信令:
很简单吧,F就是From, 说明了这条消息是谁发送的,C和上面一样。注意这里在接受完这个消息之后,一定要发送一个确认回复,向服务器表明我收到了这条消息,如果在一段时间内服务器没有收到这个回复就会像客户端发送消息发送失败回复。I和Q的值就是服务器发回的消息通知里面的I和Q。
上面使用CatMsg发送的消息可能发送到客户端,也可能发送到手机上,如果需要强制把消息发送到手机只需需要把CatMsg改成SendCatSMS就OK了。
注意这里没有了C和K字段,因为都不支持了。消息正文只能是无格式的文本,如果发送成功返回的结果就是280 Send SMS OK,内容和上面一样,不罗嗦了。
倘若需要给手机号为159xxxxxxxx的好友发送消息或者短信,因为发送消息或者短信需要用到uri,但这里只知道好友的手机号,如何才能通过手机号查到好友的Uri呢??
来看看SIPC验证成功返回的结果中没有手机号码,通过BN返回的状态信息中有的含有手机号,有的没有(主要是飞信权限设置的原因),通过遍历好友查找显然是不行的。
某一天我无意中发现了这样的方法。
发起一个获取好友信息的请求:
呵呵,看出来了吗,服务器返回了一个user-id,还记得前面SIPC验证成功之后服务器返回的好友列表中的i吗?i就是user-id,现在得到了手机号为159xxxxxxxx的user-id,就可以去遍历用户的所有好友,如果手机号为159xxxxxxxx的用户是你的好友,就一定会找到这个好友,然后自然就找到了uri(URI就是验证成功之后的好友列表中的u的值),现在就可以拿这个uri去建立会话发消息或者短信吧。。
好了,上面说的都是和状态为短信在线或离线的好友发送或者接受消息。如果你用这个方法去给在线的好友发送消息你会发现对方可以接受到你发的消息,却不能收到对方发送的消息,这是因为飞信和在线好友发消息使用的方式是不同的,如何给在线好友发消息,下篇文章详细说明。