在Android 開發即時聊天工具 YQ :(三) 實現登陸功能中已經實現了登陸功能,離能聊天又近了一步了 :)
在實現聊天之前還有一個重要的東西,?沒錯,就是好友列表,沒的好友你和誰聊呀,是吧,
嘿嘿,一切從簡,早點實現基本的聊天目標的說,所以代碼很懶(or 爛?),為什么呢?看完就知道了,
在服務器端當登陸成功后,新開一個線程,用來服務器和該賬號通信,這樣服務器端就可以處理別的登陸請求了,
- 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")){
-
- }
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")){
//注冊
}
服務器和某個客戶端通信的線程:
- public class ServerConClientThread 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 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) {
-
- }
- }
- }
- }
- }
public class ServerConClientThread 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) {
}
}
}
}
}
可以看到已經有了處理請求好友列表的代碼了,現在知道為什么說代碼寫的爛了吧,哈哈,
在客戶端中,與上面類似:
- 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;
- }
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對象,以便想服務器發送數據,當然也可以寫一個專門發送數據的線程。
在客戶端登陸成功后,向服務器發送一個請求好友列表的包:
-
- 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);
//發送一個要求返回在線好友的請求的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種種,就不詳細說了,
完成后效果如圖:
話說安卓模擬器永遠是3G信號,永遠在充電,,,,
該文章在 2013/2/25 14:23:21 編輯過