java仿聊天室项目总结_Java团队课程设计-socket聊天室(个人总结)
Java團隊課程設計-socket聊天室(個人總結)
一、團隊課程設計博客鏈接
二、本人負責模塊或任務說明
任務1
服務端對socket線程的接受以及對客戶端的數據轉發操作
任務2
數據庫的查找,添加,刪除,更改操作
三、自己代碼的提交記錄
注:只有部分提交記錄,詳細提交記錄請訪問團隊博客
四、自己負責模塊或任務詳細說明
1、服務端需要定義定義一個服務端控制對象來處理用戶的登錄和注冊,并執行創建用戶線程的任務以完成消息的存取和轉發
? 首先,用戶登錄界面需要發送用戶注冊信息或者用戶登錄信息給服務端,服務端需要進行判斷,如果是接收的是用戶登錄信息,則進行數據庫信息匹配,返回是否成功登錄(封裝成Object發送),返回離線消息,將以發送的信息置為歷史消息,并把該連接線程加入到一個HashMap中(方便轉發時查找接收方線程),并創建用戶線程進行傳輸在線聊天消息服務。若接收的是用戶注冊信息,則在數據庫的用戶表中插入新注冊的用戶信息(包括賬號和密碼),返回注冊成功(封裝成Object)。
main方法中循環監聽是否有用戶連接,并判斷新連接的用戶是需要注冊還是登錄
public static void main(String[] args) throws Exception {
ServiceControllerImpl serviceController = new ServiceControllerImpl();
ServerSocket serverSocket = null;
Socket socket;
try {
serverSocket = new ServerSocket(20);
} catch (IOException e) {
e.printStackTrace();
}
Object o = null;
while (true) {
try {
//assert關鍵字,返回一個boolean,如果為true,則程序繼續進行,否則,拋出異常阻塞程序
assert serverSocket != null;
socket = serverSocket.accept();
if (socket != null) {
inputStream = socket.getInputStream();
objectInputStream = new ObjectInputStream(inputStream);
o = objectInputStream.readObject();
//獲取新連接的socket所需的輸出流
outputStream = socket.getOutputStream();
objectOutputStream = new ObjectOutputStream(outputStream);
if("class user.User".equals(o.getClass().toString())){
User user = (User) o;
if (serviceController.checkIfTheAccountMatches(user)) {
objectOutputStream.writeObject("Login successful!");
objectOutputStream.flush();
serviceController.sendPersonName();
serviceController.sendOfflineMessage( user);
serviceController.creatThread(user,objectInputStream,objectOutputStream);
} else {
objectOutputStream.writeObject("Login error!");
objectOutputStream.flush();
}
}else{
UserInformation userInformation=(UserInformation)o;
try {
serviceController.userRegister(userInformation);
objectOutputStream.writeObject("user created successfully!");
objectOutputStream.flush();
}catch (SQLException e){
objectOutputStream.writeObject("Find error in user regist!");
objectOutputStream.flush();
}
}
}
}catch (SQLException e){
System.out.println("數據庫異常,不能進行對"+((User) o).getUserName()+"查找匹配");
} catch (IOException | ClassNotFoundException e) {
System.out.println("線程意外退出!");
}
}
}
2.服務端需要創建服務線程以對客戶端發送的要求進行回應
? 該線程需要循環監聽客戶端的請求(封裝成Object發送),對可請求的數據類型進行判斷
若客戶端請求轉發在線消息,則:
public boolean sendMessage(OnlineMessage onlineMessage) throws IOException {
if(threadMap.containsKey(onlineMessage.getReceivingEnd())){
System.out.println(onlineMessage.getReceivingEnd());
//發送給對方信息 threadMap.get(onlineMessage.getReceivingEnd()).forwardMessage(onlineMessage);
return true;
}else{
return false;
}
}
//轉發功能
public void forwardMessage(OnlineMessage onlineMessage) throws IOException {
oos.writeObject(new OnlineMessage(null,null,null,null));
oos.flush();
oos.writeObject(onlineMessage);
oos.flush();
}
在已連接的線程中查找接收方對應的線程,進行信息的轉發。同時,將相應的信息插入數據庫,返回一個boolean變量表示轉發是否成功。
若客戶端請求轉發文件,則:
public boolean sendDocument(UserDocument userDocument) throws IOException {
if(threadMap.containsKey(userDocument.getReceiver()))
{
threadMap.get(userDocument.getReceiver()).forwardDocument(userDocument);
return true;
}
return false;
}
private void forwardDocument(UserDocument userDocument) throws IOException {
oos.writeObject(new UserDocument(null,null,null));
oos.flush();
oos.writeObject(userDocument);
oos.flush();
}
在已連接的線程中查找接收方的線程,進行文件的轉發。返回一個boolean變量表示轉發是否成功(這里的轉發文件做不到離線轉發,需要發送方和接收方同時在線)
3、數據庫相應操作
首先是建表:
User表:包含所有已注冊過的用戶的賬號和密碼信息,若用戶注冊成功則將改用戶賬號信息插入到數據庫中
每個用戶的個人消息表,包含各個其他用戶與該用戶的聊天信息記錄
包含兩個標記字段,放置一個Flag字段,Flag的值為1表示是對方發來的信息,值為2表示是該用戶發給對方的信息。還有一個Type字段,其值為1表示該信息還沒有被改用戶讀取,為離線消息,值為2表示該信息已被查看,為歷史消息
其次,使用jdbc對數據庫的操作:
如果對方在線,轉發為在線消息,在自己的消息表中將該信息設置為自己為發送方(Flag為2)歷史消息(Type為2)。在對方的消息表中將該條信息設置為接收方(Flag為1),并置為歷史消息(Type為2)
if(flag==1) {
//自己的表
//Flag=1是別人給我的消息 Type=1是離線消息
preparedStatement=connection.prepareStatement(SQL);
preparedStatement.setString(1,onlineMessage.getReceivingEnd());
System.out.println(onlineMessage.getReceivingEnd());
System.out.println(onlineMessage.getSender());
preparedStatement.setString(2,"2");
preparedStatement.setString(3,onlineMessage.getMessage());
preparedStatement.setString(4,"2");
preparedStatement.setString(5,onlineMessage.getTime());
preparedStatement.executeUpdate();
//對方的表
stringBuffer = new StringBuffer("Insert into ");
stringBuffer.append(onlineMessage.getReceivingEnd());
stringBuffer.append(" values(?,?,?,?,?)");
SQL = new String(stringBuffer);
preparedStatement=connection.prepareStatement(SQL);
preparedStatement.setString(1,onlineMessage.getSender());
preparedStatement.setString(2,"1");
preparedStatement.setString(3,onlineMessage.getMessage());
preparedStatement.setString(4,"2");
preparedStatement.setString(5,onlineMessage.getTime());
preparedStatement.executeUpdate();
}
如果對方不在線,則轉發為離線消息,在自己的消息表中將該信息設置為自己為發送方(Flag為2)歷史消息(Type為2)。在對方的消息表中將該條信息設置為接收方(Flag為1),并置為歷史消息(Type為1)
else if(flag==2) {
//自己的表
//Flag=1是別人給我的消息 Type=1是離線消息
preparedStatement=connection.prepareStatement(SQL);
preparedStatement.setString(1,onlineMessage.getReceivingEnd());
preparedStatement.setString(2,"2");
preparedStatement.setString(3,onlineMessage.getMessage());
preparedStatement.setString(4,"2");
preparedStatement.setString(5,onlineMessage.getTime());
preparedStatement.executeUpdate();
//對方的表
stringBuffer = new StringBuffer("Insert into ");
stringBuffer.append(onlineMessage.getReceivingEnd());
stringBuffer.append(" values(?,?,?,?,?)");
SQL = new String(stringBuffer);
preparedStatement=connection.prepareStatement(SQL);
preparedStatement.setString(1,onlineMessage.getSender());
preparedStatement.setString(2,"1");
preparedStatement.setString(3,onlineMessage.getMessage());
preparedStatement.setString(4,"1");
preparedStatement.setString(5,onlineMessage.getTime());
preparedStatement.executeUpdate();
}
五、課程設計感想
在本次課程設計中,項目設計的階段困難重重,socket使用阻塞式的傳輸方式,一開始,消息傳輸總有接收方的獲取操作和發送方的傳送操作對接不上的問題,最后通過使用線程的等待來確保發送和接收方的對接
本次團隊合作讓我對JAVA面向對象的設計有了更加深刻的理解,項目實現了類似QQ的聊天和傳送文件功能,雖然在實現過程出現了很多問題,通過不斷的調試最終都解決了
總結
以上是生活随笔為你收集整理的java仿聊天室项目总结_Java团队课程设计-socket聊天室(个人总结)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一套完整的java程序_编写一个完整的J
- 下一篇: java vm 远程监控配置文件_Jav