作为一名初学者错误疏漏之处在所难免,恳请各位批评指正。
即时通讯一般采用TCP/IP协议或者UDP协议进行通信,这两种都涉及终端ip地址的确定,对于PC而言ip地址是容易确定的,但对于android手机端ip地址不容易确定,上述两种协议不太合适。可以使用http协议进行通信,每位用户向服务器发送请求,请求中包含相关信息:如果是一个用户发出消息,这个http请求中应该包含请求的类型(发送消息)消息的发送者,消息的接受者,消息的内容,消息的时间等属性,服务器进行有关数据库操作,将消息插入到数据库中;如果是用户要接受新的消息,http请求中应该包含请求的类型(接受消息),用户等属性,提供给服务器,服务器检索数据库,找出该用户要接收的,新的消息,将消息返回。
某个用户客户端并不知道其他用户何时发来消息,因此要实现即时消息的接受,可能就要每隔一段时间,可能是1秒,可能是0.1秒,发送一个请求,服务器进行一次查找数据库操作,寻找新消息,然后返回,断开连接,这种方式称作“轮询”,这样虽然能保证基本达到即时,但是需要频繁的向服务器发送请求,需要不断地创建http链接,因此对服务器压力较大;还有一种是基于http长链接,客户端发送一个接受消息的http请求,服务器进行查询数据库操作,但是这种情况不是进行一次查询,而是在一个循环内,不断进行查询,直到查询到新消息或者达到最长连接时间断开连接(有新消息是返回新消息后断开),可以在循环内设置delay,调节查询数据库的频率,这样可以避免频繁建立http链接的开销。
下面是几个具体的问题
如何确定是否为新消息。一种是在数据库中保存消息的表格中添加is_new的字段,值默认为1,当该消息的接受者接收某一条消息时(发送http请求获取新消息时,服务器查询新消息检索数据库,检索到了这条记录时),将该记录的is_new属性更新为0,而请求新消息时服务器查询是否有该用户的新消息时查询的必须同时满足的条件之一就是is_new=1。另一种是借助时间,每条消息的记录中有一个表示消息时间的字段,值是unix时间戳,每次查询新消息的请求完成后,服务器返回的内容包含一个当时时间(unix时间戳),客户端接受到返回数据,从中获得这个时间,保存在本地,比如数据库的一张表格中,每次请求时都要发送这个时间,提供给服务器,服务器利用这个时间属性,检索数据库里消息是否为新,消息的时间属性值比客户端发来的时间值大时才为新消息。
手机端如何发送数据至服务器,服务器如何接收数据。可以借助第三方jar包httpclient,具体见http://blog.csdn.net/giantpoplar/article/details/38685817
手机端发送http请求时,服务器接收请求后的操作。
$MAX_TIME = 600;
$DELAY_SECOND = 1;
set_time_limit ($MAX_TIME);
$result_array = array();
$got_message = false ;
$start_time = time();
$execute_time = 0;
while (!$got_message && $execute_time <= $MAX_TIME && connection_status () == CONNECTION_NORMAL ) {
sleep ($DELAY_SECOND);
if(get_query_resylt()){
$result_array = append_array($result_array);
$got_message = true;
}
$execute_time = time () - $start_time;
}
$json_str = json_encode($result_array);
echo $json_str;