Android 基于Socket的聊天應(yīng)用實(shí)例(二)
前言
很久沒(méi)寫(xiě)B(tài)LOG了,之前在寫(xiě)Android聊天室的時(shí)候答應(yīng)過(guò)要寫(xiě)一個(gè)客戶(好友)之間的聊天demo,Android 基于Socket的聊天室已經(jīng)實(shí)現(xiàn)了通過(guò)Socket廣播形式的通信功能。
以下是我寫(xiě)的一個(gè)類(lèi)似現(xiàn)在多數(shù)聊天軟件的冒泡聊天APP。全部功能都是自己的想法,對(duì)于現(xiàn)在市面上成功的例子是怎么實(shí)現(xiàn)的,我還不了解。所以讀者可只做參考學(xué)習(xí),也可以分享您的案例給我。
功能
- 一對(duì)一聊天,非聊天室
- 好友列表
- 好友在線,離線狀態(tài)(實(shí)時(shí)更新)
- 冒泡實(shí)時(shí)聊天窗口
- 發(fā)送離線信息
基本原理
之前的聊天室原理:每當(dāng)客戶端Socket連接到該ServerSocket之后,程序?qū)?duì)應(yīng)Socket加入clients集合中保存,并為該Socket啟動(dòng)一條線程,該線程負(fù)責(zé)處理該Socket所有的通信任務(wù),當(dāng)服務(wù)器線程讀到客戶端數(shù)據(jù)之后,程序遍歷clients集合,并將該數(shù)據(jù)向clients集合中的每個(gè)Socket發(fā)送一次
一對(duì)一的聊天:Server通過(guò)Map把Clients的Socket都儲(chǔ)存起來(lái),把Client用戶ID作為Map的key,當(dāng)A發(fā)送信息給B時(shí),服務(wù)器搜索出B的Socket,建立他們的通信通道。
服務(wù)器Server
這次我在服務(wù)器加入了2個(gè)Socket集合,一個(gè)用來(lái)處理用戶Online/Offline,另一個(gè)則專(zhuān)門(mén)用于處理用戶之間的通信信息傳遞
static Map<String, Socket> socketMap = new HashMap<String, Socket>(); static Map<String, Socket> onlineMap = new HashMap<String, Socket>();
Clients 上線,下線動(dòng)作,Server都會(huì)經(jīng)過(guò)篩選然后通知其在線的好友,Clients收到好友的在線狀態(tài)然后修改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();
關(guān)于聊天,我是通過(guò)一個(gè)自定義加密符來(lái)給每個(gè)Client做標(biāo)志的,例如:Client A發(fā)出的信息,該條信息的頭部帶有一條服務(wù)器和客戶端都會(huì)識(shí)別的特殊符號(hào),通過(guò)字符處理,找出該條信息的用戶信息;以此類(lèi)推,Client A的通信對(duì)象也是用這個(gè)方法
我們找到ClientA的目標(biāo)對(duì)象后,找出這個(gè)Socket通道,他們就可以一對(duì)一的對(duì)話了
//send msg to friend DataOutputStream ndos = new DataOutputStream (Server.socketMap.get(forname).getOutputStream()); ndos.writeUTF(fromname+date+"\n"+forchat); ndos.flush();
關(guān)于離線信息,這個(gè)主要是服務(wù)器承擔(dān)的功能,我是使用mySql保存數(shù)據(jù)的。Client A 向離線狀態(tài)的Client B發(fā)送一條信息,Server會(huì)判斷Client B是否在線,如果是離線狀態(tài),服務(wù)器則把該信息先保存在mySql里;當(dāng)Client B上線時(shí),服務(wù)器會(huì)查找它的離線信息,如果有未讀信息,則會(huì)及時(shí)發(fā)送。Client B就能收到離線信息了 ( ̄ˇ ̄)
客戶端 Clients
關(guān)于聊天,為了能夠?qū)崿F(xiàn)同時(shí)與多個(gè)好友聊天(不同窗口線程),這里用了ContentProvider監(jiān)視聊天數(shù)據(jù)的變化,使不在當(dāng)前聊天窗口的Activity也能收到好友的信息拼打印。
//監(jiān)視聊天數(shù)據(jù)的變化 getContentResolver().registerContentObserver(DataChangeProvider.CONTENT_URI,true, cob);
那后臺(tái)是怎么樣接收好友發(fā)來(lái)的信息的呢?上面Server里說(shuō)過(guò),有一個(gè)SocketMap的集合,而這個(gè)集合就是記錄用戶的通信Socket,當(dāng)有信息的時(shí)候,客戶端后臺(tái)的WaitMsg()會(huì)接到發(fā)來(lái)的信息并做處理。
private Runnable waitThread = new Runnable() { public void run() { System.out.println("wait running!"); WaitMsg(); } };
關(guān)于Online/Offline狀態(tài),好友列表Activity ReceiveMsg()會(huì)監(jiān)視Server發(fā)送的好友狀態(tài)信息,及時(shí)更新好友列表ListActivity。
//更新好友數(shù)據(jù)庫(kù) fanDS.updateData(reMsg,name); //獲取好友列表 fansArray = fanDS.getFans(); friends = new Friends(fansArray,reMsg,name); friendList = friends.getFriends();
總結(jié)
相對(duì)聊天室而言,一對(duì)一的聊天主要是對(duì)每個(gè)Client的Socket都標(biāo)志記錄起來(lái),讓每個(gè)通訊動(dòng)作有了目標(biāo)對(duì)象;Server作為信使把兩者的Socket對(duì)接,使兩者可以通信聊天。
這是在 TCP/IP協(xié)議下的 C/S 模式通信方式,還有UDP協(xié)議,P2P模式下的通信方式的值得再去學(xué)習(xí)。
現(xiàn)在把代碼直接放上博客園,Download:demo
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- android使用Socket通信實(shí)現(xiàn)多人聊天應(yīng)用
- Android Socket通信實(shí)現(xiàn)簡(jiǎn)單聊天室
- Android使用Websocket實(shí)現(xiàn)聊天室
- 基于Socket.IO實(shí)現(xiàn)Android聊天功能代碼示例
- android Socket實(shí)現(xiàn)簡(jiǎn)單聊天小程序
- android socket聊天室功能實(shí)現(xiàn)
- android Socket實(shí)現(xiàn)簡(jiǎn)單聊天功能以及文件傳輸
- Android 基于Socket的聊天室實(shí)例
- Android基于socket實(shí)現(xiàn)的簡(jiǎn)單C/S聊天通信功能
- Android Socket實(shí)現(xiàn)多個(gè)客戶端聊天布局
相關(guān)文章
android獲取當(dāng)前運(yùn)行Activity名字的方法
這篇文章主要介紹了android獲取當(dāng)前運(yùn)行Activity名字的方法,對(duì)比分析了兩種實(shí)現(xiàn)方法供大家選擇,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-01-01Android利用SAX對(duì)XML進(jìn)行增刪改查操作詳解
在項(xiàng)目中會(huì)遇到對(duì)于XML的增刪改查,下面這篇文章主要給大家介紹了關(guān)于Android利用SAX對(duì)XML進(jìn)行增刪改查操作的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01Android實(shí)現(xiàn)在屏幕上移動(dòng)圖片的方法
這篇文章主要介紹了Android實(shí)現(xiàn)在屏幕上移動(dòng)圖片的方法,實(shí)例分析了Android操作圖片的相關(guān)技巧,需要的朋友可以參考下2015-06-06使用RecyclerView實(shí)現(xiàn)瀑布流高度自適應(yīng)
這篇文章主要為大家詳細(xì)介紹了使用RecyclerView實(shí)現(xiàn)瀑布流高度自適應(yīng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09Android實(shí)現(xiàn)一周時(shí)間早中晚排班表
項(xiàng)目需求需要實(shí)現(xiàn)一個(gè)動(dòng)態(tài)添加,修改一周早中晚時(shí)間排班表,文章給大家提供了實(shí)現(xiàn)代碼,需要的朋友參考下吧2018-07-07Android中判斷手機(jī)是否聯(lián)網(wǎng)實(shí)例
這篇文章主要介紹了Android中判斷手機(jī)是否聯(lián)網(wǎng)實(shí)例,包括xml配置文件及功能代碼的實(shí)現(xiàn),需要的朋友可以參考下2014-10-10Android組件TabHost實(shí)現(xiàn)頁(yè)面中多個(gè)選項(xiàng)卡切換效果
這篇文章主要為大家詳細(xì)介紹了Android組件TabHost實(shí)現(xiàn)頁(yè)面中多個(gè)選項(xiàng)卡切換效果的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-05-05Android仿高德首頁(yè)三段式滑動(dòng)效果的示例代碼
很多app都會(huì)使用三段式滑動(dòng),比如說(shuō)高德的首頁(yè)和某寶等物流信息都是使用的三段式滑動(dòng)方式。本文將介紹如何實(shí)現(xiàn)這一效果,感興趣的可以學(xué)習(xí)一下2022-01-01