Android 基於Socket的聊天應用(二)

來源:互聯網
上載者:User
前言

很久沒寫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,另一個則專門用於處理使用者之間的通訊資訊傳遞

1 static Map<String, Socket> socketMap = new HashMap<String, Socket>();
2 static Map<String, Socket> onlineMap = new HashMap<String, Socket>();

Clients 上線,下線動作,Server都會經過篩選然後通知其線上的好友,Clients收到好友的線上狀態然後修改Friends List。

1 //save client's name ,online
2 //...
3 getnameString = str.substring(config.PROTOCOL_KEY.length()+config.PROTOCOL_ONLINE.length());
4 Server.onlineMap.put(getnameString, s);
5 //...
6 //update online friends
7 DataOutputStream onlineDOS = new DataOutputStream (Server.onlineMap.get(clientKey).getOutputStream());
8 onlineDOS.writeUTF(config.PROTOCOL_FRIENDS_START+onlineString+config.PROTOCOL_FRIENDS_END);
9 onlineDOS.flush();

關於聊天,我是通過一個自訂加密符來給每個Client做標誌的,例如:Client A發出的資訊,該條資訊的頭部帶有一條伺服器和用戶端都會識別的特殊符號,通過字元處理,找出該條資訊的使用者資訊;以此類推,Client A的通訊對象也是用這個方法

我們找到ClientA的目標對象後,找出這個Socket通道,他們就可以一對一的對話了

1 //send msg to friend
2 DataOutputStream ndos = new DataOutputStream (Server.socketMap.get(forname).getOutputStream());
3 ndos.writeUTF(fromname+date+"\n"+forchat);
4 ndos.flush();

 

關於離線資訊,這個主要是伺服器承擔的功能,我是使用mySql儲存資料的。Client A 向離線狀態的Client B發送一條資訊,Server會判斷Client B是否線上,如果是離線狀態,伺服器則把該資訊先儲存在mySql裡;當Client B上線時,伺服器會尋找它的離線資訊,如果有未讀資訊,則會及時發送。Client B就能收到離線資訊了  ( ̄ˇ ̄)    

用戶端 Clients

        

關於聊天,為了能夠實現同時與多個好友聊天(不同視窗線程),這裡用了ContentProvider監視聊天資料的變化,使不在當前聊天視窗的Activity也能收到好友的資訊拼列印。

1 //監視聊天資料的變化
2 getContentResolver().registerContentObserver(DataChangeProvider.CONTENT_URI,true, cob);

那後台是怎麼樣接收好友發來的資訊的呢?上面Server裡說過,有一個SocketMap的集合,而這個集合就是記錄使用者的通訊Socket,當有資訊的時候,用戶端背景WaitMsg()會接到發來的資訊並做處理。

1 private Runnable waitThread = new Runnable() {
2 public void run() {
3 System.out.println("wait running!");
4 WaitMsg();
5 }
6 };

關於Online/Offline狀態,好友名單Activity ReceiveMsg()會監視Server發送的好友狀態資訊,及時更新好友名單ListActivity。

1 //更新好友資料庫
2 fanDS.updateData(reMsg,name);
3 //擷取好友名單
4 fansArray = fanDS.getFans();
5
6 friends = new Friends(fansArray,reMsg,name);
7 friendList = friends.getFriends();
總結

相對聊天室而言,一對一的聊天主要是對每個Client的Socket都標誌記錄起來,讓每個通訊動作有了目標對象;Server作為信使把兩者的Socket對接,使兩者可以通訊聊天。

這是在 TCP/IP協議下的 C/S 模式通訊方式,還有UDP協議,P2P模式下的通訊方式的值得再去學習。

demo代碼太多,這裡就不貼出來了,如果需要,請把郵箱留下。

如果你喜歡這篇文章,請頂我一下吧。

 

 

我的新浪微博

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.