晴间多云 2014-03-04
正如我们所知道的那样,有着如下的使用场景:
当我们使用QQ或者YY的时候,服务器推送的消息,我会不由的想到,他们是怎么进行处理的?
问题1:用户进行登录后,不知道是从服务器拉取消息还是服务器推送过来未读的消息?
那么服务器是否需要保存用户的未读消息?当使用电脑客户端,手机客户端,电脑客户端和手机客户端同时使用的时候,推送消息是怎么进行处理的?
猜想:当有消息来时,服务器就把消息进行id分类,分别推送到手机客户端和电脑客户端。但是如果用户不在线的时候怎么办?我认为多半是先判断用户是否在线,如果不在线,就把消息进行标注,当有用户的心跳包存在时,就把标注的未读消息给推送过去。个人认为不太可能是客户端主动去得到消息,因为如果用户的消息很少的话,每次主动去得到消息,不仅会浪费客户端的内存,而且每次每隔一段时间主动访问的时候服务端都要进行查询,大量浪费了服务器的内存。如果是一台机子的话,那么还可以,但是如果有成千上万的用户时,就不值得。
得出结论:服务器对未读消息进行标注。当有心跳包存在时,就进行推送,如果同时存在客户端和服务器端的时候,就对两个同时推送,如果只有一个,那么就对一个进行推送,然后去掉标注。
问题2:由问题三,我们可以了解到时推送过来的消息,那么客户端如何在不同的界面对这些消息进行处理?
猜想:如果是我做的话,就把收到的消息扔给服务,然后界面和服务绑定。原因是:android中的一个服务,都是后台serviceManager进行新建的一个线程,我们可以再里面做任何的事情,不用影响到软件的运行。但是如果有两个界面和这条消息相关联的话,比如消息列表,和消息聊天框,怎么才能做到一条推送过来的消息,同时对两个界面的数据源进行修改?究竟是先保存到数据库中,再对数据源进行修改?还是先保存到数据库中,然后从数据库中得到消息,再进行界面修改?
个人认为,选择先保存到数据库,再对数据源进行修改更好。因为,如果每次都从数据库中读取消息,还得判断,这样浪费了很多的资源,万一数据库中的数据很多,那就问题就会很突出了。这样做的好处在于,可以根据推送的界面不同,来对数据的保存。例如:如果是消息界面,我就可以得到当前的消息,然后把未读消息数目加一,然后保存该消息为未读。如果是聊天消息,我也可以得到当前的消息,然后把保存该消息为已读。但是还是有一个疑问,当在聊天框的时候,这条消息已经读取了,那么当我返回的时候,怎么显示当前的最新消息?这个时候消息界面和service已经解除绑定了,为什么要用绑定拉,原因是绑定可以在界面直接Binder重复利用,但是Biner与服务器进行交互只有唯一一个Binder,所以我们要用这个Binder做很多的事情。
下面的图形可以解释他们之间的关系: