多用戶即時通訊系統03 4.編碼實現02 4.4功能實現-私聊功能實現 4.4.1思路分析 客戶端 - 發送者: 用戶在控制台輸入信息,客戶端接收內容 將消息構建成Messgae對象,通過對應的socket發送給伺服器 伺服器: 可以讀取到客戶端(發送者)發送給某個用戶(接收者)的消息 從管理線程的 ...
多用戶即時通訊系統03
4.編碼實現02
4.4功能實現-私聊功能實現
4.4.1思路分析
- 客戶端 - 發送者:
- 用戶在控制台輸入信息,客戶端接收內容
- 將消息構建成Messgae對象,通過對應的socket發送給伺服器
- 伺服器:
- 可以讀取到客戶端(發送者)發送給某個用戶(接收者)的消息
- 從管理線程的集合中,根據messgae對象的信息,獲取到接收者的userId,從而獲取接收者的socket
- 最後將Message對象轉發給指定客戶(接收者)
- 客戶端 - 接收者:
- 在接收者的線程(通信線程中),讀取到發送者的message消息,並顯示即可
4.4.2代碼實現
1.客戶端
1.MessageClientService類
這裡新建一個類,專門用來管理聊天(私聊/群聊)的功能
package qqclient.service;
import qqcommon.Message;
import qqcommon.MessageType;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Date;
/**
* @author 李
* @version 1.0
* 該類提供和消息(私聊、群聊)相關的服務方法
*/
public class MessageClientService {
/**
* @param content 內容
* @param senderId 發送用戶id
* @param getterId 接收用戶id
*/
public void sendMessageToOne(String content, String senderId, String getterId) {
//構建 message
Message message = new Message();
message.setMesType(MessageType.MESSAGE_COMM_MES);//設置消息類型是普通的聊天類型
message.setSender(senderId);
message.setGetter(getterId);
message.setContent(content);
message.setSendTime(new Date().toString());//發送時間也封裝到message對象中
System.out.println(senderId + " 對 " + getterId + " 說 " + content);
//發送給服務端
try {//在管理線程的集合中,通過userId來獲取線程,通過線程來獲取對應的socket,再通過socket獲取輸出流
ObjectOutputStream oos =
new ObjectOutputStream(ManageClientConnectServerThread.getClientConnectServerThread(senderId).getSocket().getOutputStream());
oos.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.修改:ClientConnectServerThread類
在該類的run方法中修改業務代碼,增加else if語句
else if (message.getMesType().equals(MessageType.MESSAGE_COMM_MES)) {
//接收到的是普通的聊天消息
//就把伺服器轉發的消息,顯示到控制台即可
System.out.println(message.getSendTime() + "\n" + message.getSender()
+ " 對" + message.getGetter() + " 說" + message.getContent());
}
3.修改處:QQView類
- 在類中增加屬性messageClientService
private MessageClientService messageClientService = new MessageClientService();//該對象用於私聊/群聊
- 在類中的內層迴圈中調用messageClientService對象中的方法
case "3":
System.out.println("請輸入想聊天的用戶號(線上):");
String getterId = Utility.readString(50);
System.out.println("請輸入想說的話:(100個字元以內)");
String content = Utility.readString(100);
//編寫一個方法,將消息發送給服務端
messageClientService.sendMessageToOne(content,userId,getterId);
break;
2.服務端:
1.修改:ServerConnectClientThread類
- 在該類中增加方法getSocket()
public Socket getSocket() {
return socket;
}
- 在該類中的run方法中增加私聊的業務代碼
else if (message.getMesType().equals(MessageType.MESSAGE_COMM_MES)) {
//業務三:客戶請求和某用戶私聊
//根據message獲取getterId,再得到接收者對應的線程
ServerConnectClientThread serverConnectClientThread =
ManageClientThreads.getServerConnectClientThread(message.getGetter());
//得到對應的socket的輸出流,將message轉發給指定的用戶
ObjectOutputStream oos =
new ObjectOutputStream(serverConnectClientThread.getSocket().getOutputStream());
oos.writeObject(message);//轉發消息,提示:如果客戶不線上,可以保存消息到資料庫,實現離線留言
}
運行:
2.客戶端:登錄三個用戶菩提老祖、至尊寶、紫霞仙子,使其相互通信:
用戶1:
用戶2:
用戶3: