欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2024-02-28 16:19:10
前言 很久没写blog了,之前在写android聊天室的时候答应过要写一个客户(好友)之间的聊天demo,android 基于socket的聊天室已经实现了通过socke...

前言

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

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

功能

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

基本原理

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

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

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

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

服务器server

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

这次我在服务器加入了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

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

关于聊天,为了能够实现同时与多个好友聊天(不同窗口线程),这里用了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:

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