当前位置: 移动技术网 > IT编程>移动开发>Android > Android 基于Socket的聊天应用实例(二)

Android 基于Socket的聊天应用实例(二)

2019年07月24日  | 移动技术网IT编程  | 我要评论

禁宫极乐酷刑,儿童文学大本营,化险为夷造句

前言

很久没写blog了,之前在写android聊天室的时候答应过要写一个客户(好友)之间的聊天demo,android 基于socket的聊天室已经实现了通过socket广播形式的通信功能。

以下是我写的一个类似现在多数聊天软件的冒泡聊天app。全部功能都是自己的想法,对于现在市面上成功的例子是怎么实现的,我还不了解。所以读者可只做参考学习,也可以分享您的案例给我。

功能

  • 一对一聊天,非聊天室
  • 好友列表
  • 好友在线,离线状态(实时更新)
  • 冒泡实时聊天窗口
  • 发送离线信息

基本原理

之前的聊天室原理:每当客户端socket连接到该serversocket之后,程序将对应socket加入clients集合中保存,并为该socket启动一条线程,该线程负责处理该socket所有的通信任务,当服务器线程读到客户端数据之后,程序遍历clients集合,并将该数据向clients集合中的每个socket发送一次

一对一的聊天:server通过map把clients的socket都储存起来,把client用户id作为map的key,当a发送信息给b时,服务器搜索出b的socket,建立他们的通信通道。

服务器server

这次我在服务器加入了2个socket集合,一个用来处理用户online/offline,另一个则专门用于处理用户之间的通信信息传递

 static map<string, socket> socketmap = new hashmap<string, socket>();
 static map<string, socket> onlinemap = new hashmap<string, socket>();

clients 上线,下线动作,server都会经过筛选然后通知其在线的好友,clients收到好友的在线状态然后修改friends list。

//save client's name ,online
//...
getnamestring = str.substring(config.protocol_key.length()+config.protocol_online.length());
server.onlinemap.put(getnamestring, s);
//...
//update online friends
dataoutputstream onlinedos = new dataoutputstream (server.onlinemap.get(clientkey).getoutputstream());
onlinedos.writeutf(config.protocol_friends_start+onlinestring+config.protocol_friends_end);
onlinedos.flush();

关于聊天,我是通过一个自定义加密符来给每个client做标志的,例如:client a发出的信息,该条信息的头部带有一条服务器和客户端都会识别的特殊符号,通过字符处理,找出该条信息的用户信息;以此类推,client a的通信对象也是用这个方法

我们找到clienta的目标对象后,找出这个socket通道,他们就可以一对一的对话了

//send msg to friend
dataoutputstream ndos = new dataoutputstream (server.socketmap.get(forname).getoutputstream());
ndos.writeutf(fromname+date+"\n"+forchat);
ndos.flush();

关于离线信息,这个主要是服务器承担的功能,我是使用mysql保存数据的。client a 向离线状态的client b发送一条信息,server会判断client b是否在线,如果是离线状态,服务器则把该信息先保存在mysql里;当client b上线时,服务器会查找它的离线信息,如果有未读信息,则会及时发送。client b就能收到离线信息了  ( ̄ˇ ̄)   

客户端 clients

关于聊天,为了能够实现同时与多个好友聊天(不同窗口线程),这里用了contentprovider监视聊天数据的变化,使不在当前聊天窗口的activity也能收到好友的信息拼打印。

 //监视聊天数据的变化
 getcontentresolver().registercontentobserver(datachangeprovider.content_uri,true, cob);

那后台是怎么样接收好友发来的信息的呢?上面server里说过,有一个socketmap的集合,而这个集合就是记录用户的通信socket,当有信息的时候,客户端后台的waitmsg()会接到发来的信息并做处理。

 private runnable waitthread = new runnable() {
 public void run() {
 system.out.println("wait running!");
 waitmsg();
 }
 };

关于online/offline状态,好友列表activity receivemsg()会监视server发送的好友状态信息,及时更新好友列表listactivity。

 //更新好友数据库
 fands.updatedata(remsg,name);
 //获取好友列表
 fansarray = fands.getfans();
 
 friends = new friends(fansarray,remsg,name);
 friendlist = friends.getfriends();

总结

相对聊天室而言,一对一的聊天主要是对每个client的socket都标志记录起来,让每个通讯动作有了目标对象;server作为信使把两者的socket对接,使两者可以通信聊天。

这是在 tcp/ip协议下的 c/s 模式通信方式,还有udp协议,p2p模式下的通信方式的值得再去学习。

现在把代码直接放上博客园,download:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网