項目源碼:你和我的暢聊時光
一、主要功能
- 註冊,成爲我們的註冊會員用戶,你將擁有全網唯一的ID。
- 登錄,進入擁有千萬好友的暢聊空間。
- 私聊,你可以選擇和任意在線用戶進行一次親密對話。
- 羣聊,只要你想,沒有不可以。你們的團體就是一個小羣組。
二、具體實現
1.服務器與客戶端的連接
服務器加載所有的配置信息,包括數據庫的密碼等。服務器根據Socket與客戶端連接,服務器根據收到的不同類型信息而進行不同的操作。如1代表用戶註冊操作。
1.註冊:將用戶信息存儲到服務器。登錄後將新上線的用戶信息發回給當前已在線的所有用戶。
2.私聊:服務器會檢測到所有的私聊信息以及發送方和接收方。
3.註冊羣:羣名和羣成員信息存儲在Map集合中。
4.羣聊:服務器會接收到所有的羣聊消息,併發送給羣聊內的每一個用戶。
public class MultiThreadServer {
private static final String IP;
private static final int PORT;
// 緩存當前服務器所有在線的客戶端信息
private static Map<String, Socket> clients = new ConcurrentHashMap<>();
// 緩存當前服務器註冊的所有羣名稱以及羣好友
private static Map<String,Set<String>> groups = new ConcurrentHashMap<>();
static {
Properties pros = CommUtils.loadProperties("socket.properties");
IP = pros.getProperty("address");
PORT = Integer.parseInt(pros.getProperty("port"));
}
private static class ExecuteClient implements Runnable {
private Socket client;
private Scanner in;
private PrintStream out;
public ExecuteClient(Socket client) {
this.client = client;
try {
this.in = new Scanner(client.getInputStream());
this.out = new PrintStream(client.getOutputStream(),
true,"UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
if (in.hasNextLine()) {
String jsonStrFromClient = in.nextLine();
MessageVO msgFromClient =
(MessageVO) CommUtils.json2Object(jsonStrFromClient,
MessageVO.class);
// 新用戶註冊到服務端
if (msgFromClient.getType().equals("1")) {
String userName = msgFromClient.getContent();
// 將當前在線的所有用戶名發回客戶端
MessageVO msg2Client = new MessageVO();
msg2Client.setType("1");
msg2Client.setContent(CommUtils.object2Json(
clients.keySet()
));
out.println(CommUtils.object2Json(msg2Client));
// 將新上線的用戶信息發回給當前已在線的所有用戶
sendUserLogin("newLogin:"+userName);
// 將當前新用戶註冊到服務端緩存
clients.put(userName,client);
System.out.println(userName+"上線了!");
System.out.println("當前聊天室共有"+
clients.size()+"人");
}
else if (msgFromClient.getType().equals("2")) {
// 用戶私聊
// type:2
// Content:myName-msg
// to:friendName
String friendName = msgFromClient.getTo();
Socket clientSocket = clients.get(friendName);
try {
PrintStream out = new PrintStream(clientSocket.getOutputStream(),
true,"UTF-8");
MessageVO msg2Client = new MessageVO();
msg2Client.setType("2");
msg2Client.setContent(msgFromClient.getContent());
System.out.println("收到私聊信息,內容爲"+msgFromClient.getContent());
out.println(CommUtils.object2Json(msg2Client));
} catch (IOException e) {
e.printStackTrace();
}
}else if (msgFromClient.getType().equals("3")) {
// 註冊羣
String groupName = msgFromClient.getContent();
// 該羣的所有羣成員
Set<String> friends = (Set<String>) CommUtils.json2Object(
msgFromClient.getTo(),Set.class);
groups.put(groupName,friends);
System.out.println("有新的羣註冊成功,羣名稱爲"+
groupName+",一共有"+groups.size() + "個羣");
}else if (msgFromClient.getType().equals("4")) {
// 羣聊信息
System.out.println("服務器收到的羣聊信息爲:"+msgFromClient);
String groupName = msgFromClient.getTo();
Set<String> names = groups.get(groupName);
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
String socketName = iterator.next();
Socket client = clients.get(socketName);
try {
PrintStream out = new PrintStream(client.getOutputStream(),
true,"UTF-8");
MessageVO messageVO = new MessageVO();
messageVO.setType("4");
messageVO.setContent(msgFromClient.getContent());
// 羣名-[]
messageVO.setTo(groupName+"-"+CommUtils.object2Json(names));
out.println(CommUtils.object2Json(messageVO));
System.out.println("服務端發送的羣聊信息爲:"+messageVO);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
/**
* 向所有在線用戶發送新用戶上線信息
* @param msg
*/
private void sendUserLogin(String msg) {
for (Map.Entry<String,Socket> entry: clients.entrySet()) {
Socket socket = entry.getValue();
try {
PrintStream out = new PrintStream(socket.getOutputStream(),
true,"UTF-8");
out.println(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(PORT);
ExecutorService executors = Executors.
newFixedThreadPool(50);
for (int i = 0; i < 50; i++) {
System.out.println("等待客戶端連接...");
Socket client = serverSocket.accept();
System.out.println("有新的連接,端口號爲"+client.getPort());
executors.submit(new ExecuteClient(client));
}
}
}
2.註冊功能的實現
獲取到用戶在註冊頁面輸入的所有內容,封裝到User類中,存儲到數據庫中。如果提示註冊成功,則返回到登錄頁面;否則,停留在當前頁面。
public UserReg() {
JFrame frame = new JFrame("用戶註冊");
frame.setContentPane(userRegPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
// 點擊註冊按鈕,將信息持久化到db中,成功彈出提示框
regBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 獲取用戶輸入的註冊信息
String userName = userNameText.getText();
String password = String.valueOf
(passwordText.getPassword());
String brief = brifeText.getText();
// 將輸入信息包裝爲User類,保存到數據庫中
User user = new User();
user.setUserName(userName);
user.setPassword(password);
user.setBrief(brief);
// 調用dao對象
if (accountDao.userReg(user)) {//將user信息存到數據庫中
// 返回登錄頁面
JOptionPane.showMessageDialog(frame,"註冊成功!",
"提示信息",JOptionPane.INFORMATION_MESSAGE);
frame.setVisible(false);
}else {
// 保留當前註冊頁面
JOptionPane.showMessageDialog(frame,"註冊失敗!",
"錯誤信息",JOptionPane.ERROR_MESSAGE);
}
}
});
}
3.登錄的實現
構建登錄界面,給每個按鈕設置點擊事件。
1.註冊按鈕,則彈出註冊頁面
2.登錄按鈕,則獲取用戶輸入的用戶名、密碼。
2.1校驗用戶信息,在數據中查找是否存在此用戶。不存在,提示登錄失敗,留在登錄界面。用戶可以選擇註冊,所有的註冊信息存儲在服務器的數據庫中。
2.2存在,提示登錄成功!然後與服務器建立連接,將當前用戶的用戶名發送到服務器。
2.3讀取服務端發回的所有在線用戶信息,通知每個在線用戶有某用戶上線了。
public UserLogin() {
frame = new JFrame("用戶登錄");
frame.setContentPane(UserLoginPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
// 註冊按鈕
regButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 彈出註冊頁面
new UserReg();
}
});
// 登錄按鈕
loginButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 校驗用戶信息
String userName = userNameText.getText();
String password = String.valueOf(
passwordText.getPassword());
User user = accountDao.userLogin(userName,password);//在數據庫中查看是否有對應的用戶名和密碼
if (user != null) {
// 成功,加載用戶列表
JOptionPane.showMessageDialog(frame,
"登錄成功!","提示信息",JOptionPane.INFORMATION_MESSAGE);
frame.setVisible(false);
// 與服務器建立連接,將當前用戶的用戶名發送到服務端
Connect2Server connect2Server = new Connect2Server();
MessageVO msg2Server = new MessageVO();
msg2Server.setType("1");
msg2Server.setContent(userName);
String json2Server = CommUtils.object2Json(msg2Server);
try {
PrintStream out = new PrintStream(connect2Server.getOut(),
true,"UTF-8");
out.println(json2Server);
// 讀取服務端發回的所有在線用戶信息
Scanner in = new Scanner(connect2Server.getIn());
if (in.hasNextLine()) {
String msgFromServerStr = in.nextLine();
MessageVO msgFromServer =
(MessageVO) CommUtils.json2Object(msgFromServerStr,
MessageVO.class);
Set<String> users =
(Set<String>) CommUtils.json2Object(msgFromServer.getContent(),
Set.class);
System.out.println("所有在線用戶爲:"+users);
// 加載用戶列表界面
// 將當前用戶名、所有在線好友、與服務器建立連接傳遞到好友列表界面
new FriendsList(userName,users,connect2Server);
}
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
}
}else {
// 失敗,停留在當前登錄頁面,提示用戶信息錯誤
JOptionPane.showMessageDialog(frame,
"登錄失敗!","錯誤信息",
JOptionPane.ERROR_MESSAGE);
}
}
});
}
4.私聊
1.當用戶A在在線好友列表界面雙擊用戶B,即進入私聊界面。
2.用戶輸入信息,按回車,即將信息發送給服務器。發送到服務器之前,工具類會封裝發送方A的用戶名、消息內容、聊天類型、接收方B的用戶名,將其轉爲json字符串。
3.服務器對json字符串進行解析,決定進行私聊操作,服務器將信息發送給B。發送到B之前會將json字符串轉爲Object對象,用戶B最終才接收到A發送的消息。
public PrivateChatGUI(String friendName,
String myName,
Connect2Server connect2Server) {
this.friendName = friendName;
this.myName = myName;
this.connect2Server = connect2Server;
try {
this.out = new PrintStream(connect2Server.getOut(),true,
"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
frame = new JFrame("與"+friendName+"私聊中...");
frame.setContentPane(privateChatPanel);
// 設置窗口關閉的操作,將其設置爲隱藏
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
frame.setSize(400,400);
frame.setVisible(true);
// 捕捉輸入框的鍵盤輸入
send2Server.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
StringBuilder sb = new StringBuilder();
sb.append(send2Server.getText());
// 1.當捕捉到按下Enter
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
// 2.將當前信息發送到服務端
String msg = sb.toString();
MessageVO messageVO = new MessageVO();
messageVO.setType("2");
messageVO.setContent(myName+"-"+msg);
messageVO.setTo(friendName);
PrivateChatGUI.this.out.println(CommUtils.object2Json(messageVO));
// 3.將自己發送的信息展示到當前私聊界面
readFromServer(myName+"說:"+msg);
send2Server.setText("");
}
}
});
}
5.羣聊
(1)創建羣:
1.點擊創建羣,進入創建羣界面。所有的在線好友以列表形式展現。
2.選擇你想選擇的用戶,勾選進行多選,已選擇的用戶會存儲在集合中。
3.將自己加入到羣聊集合中,存儲羣名。
4.用工具類將羣名、羣成員信息、當前類的操作類型3,封裝成json字符串,發送給服務器。
5.隱藏創建羣界面,然後刷新羣列表界面。
public CreateGroupGUI(String myName,
Set<String> friends,
Connect2Server connect2Server,
FriendsList friendsList) {
this.myName = myName;
this.friends = friends;
this.connect2Server = connect2Server;
this.friendsList = friendsList;
JFrame frame = new JFrame("創建羣組");
frame.setContentPane(createGroupPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400,300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
// 將在線好友以checkBox展示到界面中
friendLabelPanel.setLayout(new BoxLayout(friendLabelPanel,BoxLayout.Y_AXIS));
Iterator<String> iterator = friends.iterator();
while (iterator.hasNext()) {
String labelName = iterator.next();
JCheckBox checkBox = new JCheckBox(labelName);
friendLabelPanel.add(checkBox);
}
// 點擊提交按鈕提交信息到服務端
conformBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 1.判斷哪些好友選中加入羣聊
Set<String> selectedFriends = new HashSet<>();
Component[] comps = friendLabelPanel.getComponents();
for (Component comp : comps) {
JCheckBox checkBox = (JCheckBox) comp;
if (checkBox.isSelected()) {
String labelName = checkBox.getText();
selectedFriends.add(labelName);
}
}
selectedFriends.add(myName);
// 2.獲取羣名輸入框輸入的羣名稱
String groupName = groupNameText.getText();
// 3.將羣名+選中好友信息發送到服務端
// type:3
// content:groupName
// to:[user1,user2,user3...]
MessageVO messageVO = new MessageVO();
messageVO.setType("3");
messageVO.setContent(groupName);
messageVO.setTo(CommUtils.object2Json(selectedFriends));
try {
PrintStream out = new PrintStream(connect2Server.getOut(),
true,"UTF-8");
out.println(CommUtils.object2Json(messageVO));
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
}
// 4.將當前創建羣界面隱藏,刷新好友列表界面的羣列表
frame.setVisible(false);
// addGroupInfo
// loadGroup
friendsList.addGroup(groupName,selectedFriends);
friendsList.loadGroupList();
}
});
}
(2)羣聊操作:
1.雙擊一個羣,進入羣聊。
2.用戶A發送信息,將羣聊消息、操作類型、和其他羣成員信息封裝成json字符串發送到服務器。
3.服務器接收到後,將羣聊消息發送給所有的羣成員。
這裏需要注意的是:
a. 只有羣主才能發送第一條消息。
b. 創建羣時,只有羣主的羣列表纔會刷新,其他羣成員並不知道有這個羣的存在。
c. 只有當羣主發了第一條信息時,其他成員的羣列表纔會刷新出這個羣。
這一點仿照了微信羣聊的特點。
send2Server.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
StringBuilder sb = new StringBuilder();
sb.append(send2Server.getText());
// 捕捉回車按鍵
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
String str2Server = sb.toString();
// type:4
// content:myName-msg
// to:groupName
MessageVO messageVO = new MessageVO();
messageVO.setType("4");
messageVO.setContent(myName+"-"+str2Server);
messageVO.setTo(groupName);
try {
PrintStream out = new PrintStream(connect2Server.getOut(),
true,"UTF-8");
out.println(CommUtils.object2Json(messageVO));
System.out.println("客戶端發送的羣聊信息爲:"+messageVO);
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
}
}
}
});
6.加載好友列表
1.用戶上線,刷新好友界面
2.創建羣,刷新羣列表界面
3.緩存所有私聊界面和羣聊界面
public class FriendsList {
private String userName;
// 存儲所有在線好友
private Set<String> users;
// 存儲所有羣名稱以及羣好友
private Map<String,Set<String>> groupList = new ConcurrentHashMap<>();
private Connect2Server connect2Server;
// 緩存所有私聊界面
private Map<String,PrivateChatGUI> privateChatGUIList = new ConcurrentHashMap<>();
// 緩存所有羣聊界面
private Map<String,GroupChatGUI> groupChatGUIList = new ConcurrentHashMap<>();
// 好友列表後臺任務,不斷監聽服務器發來的信息
// 好友上線信息、用戶私聊、羣聊
private class DaemonTask implements Runnable {
private Scanner in = new Scanner(connect2Server.getIn());
@Override
public void run() {
while (true) {
// 收到服務器發來的信息
if (in.hasNextLine()) {
String strFromServer = in.nextLine();
// 此時服務器發來的是一個json字符串
if (strFromServer.startsWith("{")) {
MessageVO messageVO = (MessageVO) CommUtils.json2Object(strFromServer,
MessageVO.class);
if (messageVO.getType().equals("2")) {
// 服務器發來的私聊信息
String friendName = messageVO.getContent().split("-")[0];
String msg = messageVO.getContent().split("-")[1];
// 判斷此私聊是否是第一次創建
if (privateChatGUIList.containsKey(friendName)) {
PrivateChatGUI privateChatGUI = privateChatGUIList.get(friendName);
privateChatGUI.getFrame().setVisible(true);
privateChatGUI.readFromServer(friendName+"說:"+msg);
}else {
PrivateChatGUI privateChatGUI = new PrivateChatGUI(friendName,
userName,connect2Server);
privateChatGUIList.put(friendName,privateChatGUI);
privateChatGUI.readFromServer(friendName+"說:"+msg);
}
}
else if (messageVO.getType().equals("4")) {
// 收到服務器發來的羣聊信息
// type:4
// content:sender-msg
// to:groupName-[1,2,3,...]
String groupName = messageVO.getTo().split("-")[0];
String senderName = messageVO.getContent().split("-")[0];
String groupMsg = messageVO.getContent().split("-")[1];
// 若此羣名稱在羣聊列表
if (groupList.containsKey(groupName)) {
if (groupChatGUIList.containsKey(groupName)) {
// 羣聊界面彈出
GroupChatGUI groupChatGUI = groupChatGUIList.get(groupName);
groupChatGUI.getFrame().setVisible(true);
groupChatGUI.readFromServer(senderName+"說:"+groupMsg);
}else {
Set<String> names = groupList.get(groupName);
GroupChatGUI groupChatGUI = new GroupChatGUI(groupName,
names,userName,connect2Server);
groupChatGUIList.put(groupName,groupChatGUI);
groupChatGUI.readFromServer(senderName+"說:"+groupMsg);
}
}else {
// 若羣成員第一次收到羣聊信息
// 1.將羣名稱以及羣成員保存到當前客戶端羣聊列表
Set<String> friends = (Set<String>) CommUtils.json2Object(messageVO.getTo().split("-")[1],
Set.class);
groupList.put(groupName, friends);
loadGroupList();
// 2.彈出羣聊界面
GroupChatGUI groupChatGUI = new GroupChatGUI(groupName,
friends,userName,connect2Server);
groupChatGUIList.put(groupName,groupChatGUI);
groupChatGUI.readFromServer(senderName+"說:"+groupMsg);
}
}
}else {
// newLogin:userName
if (strFromServer.startsWith("newLogin:")) {
String newFriendName = strFromServer.split(":")[1];
users.add(newFriendName);
// 彈框提示用戶上線
JOptionPane.showMessageDialog(frame,
newFriendName+"上線了!",
"上線提醒",JOptionPane.INFORMATION_MESSAGE);
// 刷新好友列表
loadUsers();
}
}
}
}
}
}
// 私聊點擊事件
private class PrivateLabelAction implements MouseListener {
private String labelName;
public PrivateLabelAction(String labelName) {
this.labelName = labelName;
}
// 鼠標點擊執行事件
@Override
public void mouseClicked(MouseEvent e) {
// 判斷好友列表私聊界面緩存是否已經有指定標籤
if (privateChatGUIList.containsKey(labelName)) {
PrivateChatGUI privateChatGUI = privateChatGUIList.get(labelName);
privateChatGUI.getFrame().setVisible(true);
}else {
// 第一次點擊,創建私聊界面
PrivateChatGUI privateChatGUI = new PrivateChatGUI(
labelName,userName,connect2Server
);
privateChatGUIList.put(labelName,privateChatGUI);
}
}
// 羣聊點擊事件
private class GroupLabelAction implements MouseListener {
private String groupName;
public GroupLabelAction(String groupName) {
this.groupName = groupName;
}
@Override
public void mouseClicked(MouseEvent e) {
if (groupChatGUIList.containsKey(groupName)) {
GroupChatGUI groupChatGUI = groupChatGUIList.get(groupName);
groupChatGUI.getFrame().setVisible(true);
}else {
Set<String> names = groupList.get(groupName);
GroupChatGUI groupChatGUI = new GroupChatGUI(
groupName,names,userName,connect2Server
);
groupChatGUIList.put(groupName,groupChatGUI);
}
}
}
public FriendsList(String userName, Set<String> users,
Connect2Server connect2Server) {
this.userName = userName;
this.users = users;
this.connect2Server = connect2Server;
frame = new JFrame(userName);
frame.setContentPane(friendsPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400,300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
loadUsers();
// 啓動後臺線程不斷監聽服務器發來的消息
Thread daemonThread = new Thread(new DaemonTask());
daemonThread.setDaemon(true);
daemonThread.start();
// 創建羣組
createGroupBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new CreateGroupGUI(userName,users,connect2Server,
FriendsList.this);
}
});
}
// 加載所有在線的用戶信息
public void loadUsers() {
JLabel[] userLabels = new JLabel [users.size()];
JPanel friends = new JPanel();
friends.setLayout(new BoxLayout(friends,BoxLayout.Y_AXIS));
// set遍歷
Iterator<String> iterator = users.iterator();
int i = 0;
while (iterator.hasNext()) {
String userName = iterator.next();
userLabels[i] = new JLabel(userName);
// 添加標籤點擊事件
userLabels[i].addMouseListener(new PrivateLabelAction(userName));
friends.add(userLabels[i]);
i++;
}
frinedsList.setViewportView(friends);
// 設置滾動條垂直滾動
frinedsList.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
friends.revalidate();
frinedsList.revalidate();
}
public void loadGroupList() {
// 存儲所有羣名稱標籤Jpanel
JPanel groupNamePanel = new JPanel();
groupNamePanel.setLayout(new BoxLayout(groupNamePanel,
BoxLayout.Y_AXIS));
JLabel[] labels = new JLabel[groupList.size()];
// Map遍歷
Set<Map.Entry<String,Set<String>>> entries = groupList.entrySet();
Iterator<Map.Entry<String,Set<String>>> iterator =
entries.iterator();
int i = 0;
while (iterator.hasNext()) {
Map.Entry<String,Set<String>> entry = iterator.next();
labels[i] = new JLabel(entry.getKey());
labels[i].addMouseListener(new GroupLabelAction(entry.getKey()));
groupNamePanel.add(labels[i]);
i++;
}
groupListPanel.setViewportView(groupNamePanel);
groupListPanel.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
groupListPanel.revalidate();
}
public void addGroup(String groupName,Set<String> friends) {
groupList.put(groupName,friends);
}
}
三、整體流程
服務器:
負責緩存所有在線好友、羣組以及私聊羣聊的聊天記錄。根據客戶端進行不同的操作而緩存不同的數據到服務器上。
客戶端:
1.點擊註冊按鈕,觸發註冊事件。在註冊頁面,獲取用戶輸入的用戶名、密碼、簡介,將信息封裝到User類中,將user的信息保存到數據庫中,即進行數據插入操作。註冊成功,返回登錄界面。
2.輸入已註冊的用戶名、密碼,點擊登錄,觸發登錄事件。獲取用戶輸入的用戶名和密碼,在數據庫中查找是否有此用戶。
3.有,則成功登錄。然後與服務器建立連接,將當前用戶的用戶名發送到服務器,服務器緩存此用戶名。服務器給每一個在線好友發送新用戶上線了,並刷新好友列表。
刷新好友列表:加載所有在線的用戶信息,並給每一個用戶標籤添加標籤點擊事件。
4.客戶端讀取服務器返回的所有在線用戶信息,加載主界面。即加載用戶列表界面,將當前用戶名、所有在線好友、與服務器建立連接傳遞到好友列表界面。
5.好友列表界面:加載所有在線的用戶信息,並給每一個用戶標籤添加標籤點擊事件,觸發私聊功能。如果是第一次點擊,則創建私聊界面;如果之前已經有過聊天的記錄,則根據緩存中的指定標籤將私聊界面顯示出來。
6.創建私聊:根據傳遞的參數(發送方,接收方,Socket連接),一旦用戶按下回車,則將當前的發送方、接收方、消息封裝到協議類中,發給服務器,並將自己發送的信息展示到當前私聊界面。最後將當前私聊界面緩存起來。
7.創建羣。點擊創建羣,進入創建羣界面。所有的在線好友以列表形式展現。將已選擇的用戶存儲在集合中。將自己加入到羣聊集合中,存儲羣名。服務器緩存羣名和羣成員信息,將羣名稱標籤存儲在緩存中,給每個羣名稱標籤添加鼠標點擊事件,最後刷新羣列表界面。
8.羣聊:羣聊界面首次創建會存在緩存中,協議類將羣聊的發言人和羣名稱封裝起來,發給服務器。服務器經過解析,將消息發送給在羣組中的每一個人。
8.啓動後臺線程不斷監聽服務器發來的消息:
(1)服務器發來的是json字符串,我們需要進行解析。
a. 服務器發來的是私聊信息。判斷是不是第一次和此用戶進行的私聊。第一次私聊,則創建私聊界面,緩存此私聊界面。不是第一次私聊,將緩存中的私聊界面彈出來。
b. 服務器發來的是羣聊信息。若羣聊名稱在羣聊列表,彈出羣聊界面。如果自己剛剛創建了羣聊,則將羣聊信息緩存起來。若羣成員第一次收到羣聊信息,將羣名稱以及羣成員保存到當前客戶端羣聊列表,然後彈出羣聊界面,將羣聊界面緩存。
(2)服務器發來字符串:newLogin:userName。則提醒新用戶上線,刷新好友列表。