本篇介紹websocket實現QQ聊天室的後端實現,前端的實現看鏈接說明
鏈接說明
1.使用了spring boot 框架,有關spring boot 入門請戳此鏈接使用Intellij IDEA開發第一個spring boot項目
2.安卓前端實現細節戳此鏈接安卓android+WebSocket實現簡易QQ聊天室
界面演示
說明
有兩個界面,第一個是登陸界面,我借用了我之前實現的登陸界面,並做了一些微調。需要輸入ID和名字,測試的時候輸入的ID不能重複,第二個是名字用於界面展示,登陸後跳轉入第二個界面,就可以在聊天室裏聊天了。
下面圖模擬了一組場景,大青兒先進入聊天室,然後小明進入,互相發一段消息後,小明退出聊天室。
大青兒界面變化
小明界面變化
控制檯輸出:
代碼部分
pom.xml添加依賴
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
User.java
public class User {
private String userId;
private String userName;
private int userImg;
private Msg userMsg;
public int getUserImg() {
return userImg;
}
public void setUserImg(int userImg) {
this.userImg = userImg;
}
public User(String userId, String userName, int userImg) {
this.userId = userId;
this.userName = userName;
this.userImg = userImg;
}
public User() {
}
public User(String userId, String userName) {
this.userId = userId;
this.userName = userName;
}
public User(String userId, String userName, Msg userMsg) {
this.userId = userId;
this.userName = userName;
this.userMsg = userMsg;
}
public User(String userId, String userName, int userImg, Msg userMsg) {
this.userId = userId;
this.userName = userName;
this.userImg = userImg;
this.userMsg = userMsg;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Msg getUserMsg() {
return userMsg;
}
public void setUserMsg(Msg userMsg) {
this.userMsg = userMsg;
}
@Override
public String toString() {
return JSON.toJSONString(this);
}
}
Msg.java
public class Msg {
private boolean send;//是否是發送的消息
private String content;//發送的內容
private boolean system;//是否是系統消息
public Msg(boolean send, String content) {
this.send = send;
this.content = content;
this.system = false;
}
public Msg() {
}
public Msg(boolean send, String content, boolean system) {
this.send = send;
this.content = content;
this.system = system;
}
public boolean isSystem() {
return system;
}
public void setSystem(boolean system) {
this.system = system;
}
public boolean isSend() {
return send;
}
public void setSend(boolean send) {
this.send = send;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return JSON.toJSONString(this);
}
}
WebSocketTest.java
@ServerEndpoint("/test/{userId}")
@Component
public class WebSocketTest {
/**
* 存放所有在線的客戶端
*/
private static Map<String, Session> clients = new ConcurrentHashMap<>();
private String userId;
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId) {
System.out.println("打開了一個連接");
System.out.println("userId:"+userId);
System.out.println("session.getId():"+session.getId());
this.userId = userId;
User user = new User();
user.setUserMsg(new Msg(false,"有新人加入聊天",true));
sendAll(user.toString());
//將新用戶存入在線的組
clients.put(userId, session);
}
/**
* 客戶端關閉
* @param session session
*/
@OnClose
public void onClose(Session session, @PathParam("userId") String userId) {
System.out.println("有用戶斷開了");
System.out.println("userId:"+userId);
System.out.println("session.getId():"+session.getId());
User user = new User();
user.setUserMsg(new Msg(false,"有用戶斷開聊天",true));
sendAll(user.toString());
//將掉線的用戶移除在線的組裏
clients.remove(userId);
}
/**
* 發生錯誤
* @param throwable e
*/
@OnError
public void onError(Throwable throwable) {
throwable.printStackTrace();
}
/**
* 收到客戶端發來消息
* @param message 消息對象
*/
@OnMessage
public void onMessage(String message) {
System.out.println("服務端收到客戶端發來的消息:"+message);
User user = JSON.parseObject(message, User.class);
user.getUserMsg().setSend(false);
this.sendAll(user.toString());
}
/**
* 羣發消息
* @param message 消息內容
*/
private void sendAll(String message) {
for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
if (!sessionEntry.getKey().equals(userId)){
sessionEntry.getValue().getAsyncRemote().sendText(message);
}
}
}
}
WebSocketConfig.java
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}