實現聊天之前還有一個重要的東西,?沒錯,就是好友列表,沒的好友你和誰聊呀,是吧,
嘿嘿,一切從簡,早點實現基本的聊天目標的說,所以代碼很懶(or 爛?),為什麼呢?看完就知道瞭,
在服務器端當登陸成功後,新開一個線程,用來服務器和該賬號通信,這樣服務器端就可以處理別的登陸請求瞭,
[java]
if(u.getOperation().equals("login")){ //登錄
int account=u.getAccount();
boolean b=new UserDao().login(account, u.getPassword());//連接數據庫驗證用戶
if(b){
System.out.println(MyData.getDate()+"'"+account+"' 上線瞭!");
m.setType(YQMessageType.SUCCESS);//返回一個成功登陸的信息包
oos.writeObject(m);
ServerConClientThread cct=new ServerConClientThread(s);//單開一個線程,讓該線程與該客戶端保持連接
ManageServerConClient.addClientThread(u.getAccount(),cct);
cct.start();//啟動與該客戶端通信的線程
}else{
m.setType(YQMessageType.FAIL);
oos.writeObject(m);
}
}else if(u.getOperation().equals("register")){
//註冊
}
服務器和某個客戶端通信的線程:
[java] ad extends Thread {
Socket s;
public ServerConClientThread(Socket s){
this.s=s;
}
public void run() {
while(true){
ObjectInputStream ois = null;
YQMessage m = null;
try {
ois=new ObjectInputStream(s.getInputStream());
m=(YQMessage) ois.readObject();
//對從客戶端取得的消息進行類型判斷,做相應的處理
if(m.getType().equals(YQMessageType.COM_MES)){//如果是普通消息包
//取得接收人的通信線程
ServerConClientThread scc=ManageServerConClient.getClientThread(m.getReceiver());
ObjectOutputStream oos=new ObjectOutputStream(scc.s.getOutputStream());
//向接收人發送消息
oos.writeObject(m);
}else if(m.getType().equals(YQMessageType.GET_ONLINE_FRIENDS)){//如果是請求好友列表
//操作數據庫,這裡返回的是所有的用戶列表,先留著坑,以後填,增加好友
//暫時將結果揉成string類型,以後可以改為json
String res=new UserDao().getUser();
//發送好友列表到客戶端
ServerConClientThread scc=ManageServerConClient.getClientThread(m.getSender());
ObjectOutputStream oos=new ObjectOutputStream(scc.s.getOutputStream());
YQMessage ms=new YQMessage();
ms.setType(YQMessageType.RET_ONLINE_FRIENDS);
ms.setContent(res);
oos.writeObject(ms);
}
} catch (Exception e) {
e.printStackTrace();
try {
s.close();
ois.close();
} catch (IOException e1) {
}
}
}
}
}
可以看到已經有瞭處理請求好友列表的代碼瞭,現在知道為什麼說代碼寫的爛瞭吧,哈哈,
在客戶端中,與上面類似:
[java]
if(ms.getType().equals(YQMessageType.SUCCESS)){
//創建一個該賬號和服務器保持連接的線程
ClientConServerThread ccst=new ClientConServerThread(context,s);
//啟動該通信線程
ccst.start();
//加入到管理類中
ManageClientConServer.addClientConServerThread(((User)obj).getAccount(), ccst);
b=true;
}else if(ms.getType().equals(YQMessageType.FAIL)){
b=false;
}
將客戶端連接服務器的線程為什麼要加到ManageClientServer這個類中,就是方便隨時可以得到ObjectOutputStream對象,以便想服務器發送數據,當然也可以寫一個專門發送數據的線程。
在客戶端登陸成功後,向服務器發送一個請求好友列表的包:
[java]
//發送一個要求返回在線好友的請求的Message
ObjectOutputStream oos = new ObjectOutputStream (
ManageClientConServer.getClientConServerThread(user.getAccount()).getS().getOutputStream());
YQMessage m=new YQMessage();
m.setType(YQMessageType.GET_ONLINE_FRIENDS);
m.setSender(user.getAccount());
oos.writeObject(m);
在得到好友列表後,顯示到好友列表中就OK,listView 和adapter種種,就不詳細說瞭,
完成後效果如圖: