注解版websocket
原创
©著作权归作者所有:来自51CTO博客作者码农小宋的原创作品,请联系作者获取转载授权,否则将追究法律责任
1、搭建项目框架,添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、自定义服务器端点,创建 ChatRoomServerEndpoint 类。代码如下
package com.spz.websocket;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/*** 聊天室服务端
* * 标注为端点:@ServerEndpoint,其中"/chat-room/{username}"为访问路径
*/
@ServerEndpoint("/chat-room/{username}")
public class ChatRoomServerEndpoint {
/**
* 存储所有存活的用户
* *我们需要周期性的去检查用户是否还处于活跃状态,不活跃的,移除该用户的session
*/
private static Map<String , Session> livingSessions = new ConcurrentHashMap<>();
/**
* 前端一旦启用WebSocket,就会调用@OnOpen注解标注的方法
* @param username 路径参数 *
* @param session 会话,每个访问对象都会有一个单独的会话
*/
@OnOpen
public void openSession(@PathParam("username") String username, Session session){
livingSessions.put(session.getId(), session);
sendTextAll("欢迎用户【" + username +"】来到聊天室!");
}
/**
* 服务端发送消息给前端时调用 *
* @param username 路径参数 *
* @param session 会话,每个访问对象都会有一个单独的会话
* @param message 待发送的消息
*/
@OnMessage
public void onMessage(@PathParam("username") String username, Session session, String message) {
sendTextAll("用户【" + username + "】:" + message);
}
/** *
* 客户端关闭WebSocket连接时,调用标注@OnClose的方法 *
* @param username 路径参数
* @param session 会话,每个访问对象都会有一个单独的会话
* */
@OnClose
public void onClose(@PathParam("username") String username, Session session){
//将当前用户移除
livingSessions.remove(session.getId());
//给所有存活的用户发送消息
sendTextAll("用户【" + username +"】离开聊天室!");
}
/** *
* 向指定Session(用户)发送message
* */
private void sendText(Session session, String message){
//发送消息对象
RemoteEndpoint.Basic basicRemote = session.getBasicRemote(); try {
//发送消息
basicRemote.sendText(message);
} catch (IOException e) { e.printStackTrace();
}
}
/** *
* 遍历所有存活的用户,并发送消息(PS:就是广播消息)
*/
private void sendTextAll(String message){
Iterator<String> sids=livingSessions.keySet().iterator();
while(sids.hasNext()) {//没有指针下移操作,只是判断是否存在下一个元素
String sid=sids.next();
Session session=livingSessions.get(sid);
this.sendText(session, message);
}
}
}
3、改造启动接口,激活 WebSocket,并注册 WebSocket 相关类和端点,参考代码如下
package com.spz;
import com.spz.websocket.ChatRoomServerEndpoint;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@SpringBootApplication
@EnableWebSocket
public class WebsocketApplication {
public static void main(String[] args) {
SpringApplication.run(WebsocketApplication.class, args);
}
/**
* * 注册 ServerEndpointExporter Bean对象(因为Springboot没有自动注册,所以得手动注册)
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
/**
* * 注册 端点对象
*/
@Bean
public ChatRoomServerEndpoint chatRoomServerEndpoint(){
return new ChatRoomServerEndpoint();
}
}
4、 前端chat.html 代码如下
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>聊天室</title>
<script type="text/javascript" src="js/layui(layui-v2.4.3)/jquery-1.8.2.min.js"></script>
<script>
$(document).ready(function() {
$("#username").val(localStorage.getItem('uName'));
var urlPrefix = "ws://localhost:8080/chat-room/"+$("#username").val();
var ws = null;
//加入聊天室
$('#bt_join').click(function() {
var username = $('#username').val();
//这一步,会调用服务端的@OnOpen注解标注的方法
ws = new WebSocket(urlPrefix + username);
ws.onmessage = function(event) {
//接收服务端返回给前端的消息
$('#text_chat_content').append(event.data + "\n");
};
ws.onclose = function() {
$('#text_chat_content').append("用户【" + username + "】离开聊天室!" + "\n");
};
});
//发送消息
$('#bt_send').click(function() {
if(ws) {
ws.send($('#in_msg').val());
}
});
92
//离开聊天室
$('#bt_left').click(function() {
if(ws) {
ws.close();
}
});
})
</script>
</head>
<body>
聊天消息内容:
<br />
<textarea id="text_chat_content" readonly="readonly" cols="60" rows="20"></textarea>
<br /> 用户:
<input id="username" type="text" />
<button id="bt_join">加入聊天室</button>
<button id="bt_left">离开聊天室</button>
<br /> 输入框:
<input id="in_msg" type="text" />
<button id="bt_send">发送消息</button>
</body>
</html>