1. 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2. websocket配置类
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConf implements WebSocketMessageBrokerConfigurer {
public void registerStompEndpoints(StompEndpointRegistry registry){
registry.addEndpoint("/websocket")
.setAllowedOrigins("*")
.withSockJS();
}
public void configureMessageBroker(MessageBrokerRegistry registry){
//设置接收客户端订阅的路径前缀(必须设置)
registry.enableSimpleBroker("/topic", "/queue");
//设置接收客户端消息的路径前缀
registry.setApplicationDestinationPrefixes("/app");
registry.setUserDestinationPrefix("/user");
}
}
3. 监听类
@Component
public class WebSocketEventListener {
//监听连接
@EventListener
public void handleConnectListener(SessionConnectedEvent event) {
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(event.getMessage());
String sessionId = accessor.getSessionId();
System.out.println("[ws-connect] socket connect:"+sessionId);
}
//监听断开连接
@EventListener
public void handleDisConnectListener(SessionDisconnectEvent event){
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(event.getMessage());
String sessionId = accessor.getSessionId();
System.out.println("[ws-disconnect] socket disconnect:"+sessionId);
}
}
3. Controller层
@RestController
@RequestMapping("/ws")
public class WebSocketController {
@Autowired
private WsSendService wsSendService;
//服务端给客户端发送消息
@RequestMapping(value="/sendMsg", method = RequestMethod.GET)
public void sendMsg(){
wsSendService.broadcastMsg("this is server' msg");
}
//接收客户端发送的消息
@MessageMapping("/address1")
@SendTo("/topic/broadcast/message")
public String address1(String msg){
System.out.println(msg);
return "address1' msg:"+msg;
}
}
4.service层
@Service
public class WsSendServiceImpl implements WsSendService {
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;
@Override
public void broadcastMsg(Object msg) {
simpMessagingTemplate.convertAndSend(WebSocketConstant.TOPIC_BROADCAST_MESSAGE, msg);
}
}
5.其他
public class WebSocketConstant {
/**
* 广播消息订阅
*/
public static final String TOPIC_BROADCAST_MESSAGE = "/topic/broadcast/message";
}
6.前端
需要添加
jquery.js
sockjs.min.js
stomp.min.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="css/main.css">
<script src="js/sockjs.min.js"></script>
<script src="js/stomp.min.js"></script>
<script>
var sendMessage = null;
var disConnect = null;
function connect(){
var client;
var socket = new SockJS('http://localhost:8885/websocket');
client = Stomp.over(socket);
client.heartbeat.outgoing = 5000;
client.heartbeat.incoming = 0;
client.connect({
},function(succ){
console.log('client connect success:', succ);
updateState('连接成功');
//订阅广播
client.subscribe("/topic/broadcast/message", onMessage);
},function(error){
console.log('client connect error:', error);
updateState('连接失败');
});
sendMessage = function (destination, headers, body){
client.send(destination, headers, body)
};
disConnect = function (){
client.disconnect();
console.log('client connect break')
}
}
function onMessage(message){
console.log(message);
}
function send(){
var destination = document.getElementById("destination").value;
var body = document.getElementById("content").value;
if(sendMessage == null){
alert('ws connect break');
return;
}
sendMessage(destination, {}, body);
insertChat(true, destination, body)
}
function updateState(state){
document.getElementById("state").innerHTML = state;
}
function insertChat(isLeft, destination, body){
var p = document.createElement('p');
if(isLeft){
p.setAttribute('class', 'p-left');
}else{
p.setAttribute('class', 'p-right');
}
p.innerHTML = destination + '<br/>' + body;
document.getElementById("chat").appendChild(p);
}
</script>
</head>
<body>
<div class="body-left">
<div id="state">未连接</div>
<button id="connect" onclick="connect()">连接</button>
<button id="disConnect" onclick="disConnect()">断开</button>
<div>
<input id="destination" type="text" placeholder="destination"/>
<textarea id="content" rows="10", placeholder="payload"></textarea>
<button id="send" onclick="send()">发送</button>
</div>
</div>
<div id="chat" class="body-right">
<p class="p-left">client message...</p>
<p class="p-right">server message...</p>
</div>
</body>
</html>
普通websocket
客户端
<script>
if('WebSocket' in window){
websocket = new WebSocket("ws://localhost:8080/demo/websocket/aa.ws");
}else{
alert('Not support websocket');
}
//链接发生错误的回调方法
websocket.onerror = function(){
alert('websocket发生错误');
}
//连接建立成功的回调方法
websocket.onopen = funciton(){
send("连接成功");
}
//接收到消息的回调方法
websocket.onmessage = function(event){
var obj = JSON.parse(event.data);
console.log(obj);
}
//连接关闭的回调方法
websocket.onclose = function(event){
console.log("连接关闭");
}
</script>
服务器:
@Component
@Slf4j
@ServerEndpoint("/websocket/{aa}")
public class WebSocket{
private Session session;
public static CopyOnWriteArraySet<WebSocket> webSocket = new CopyOnWriteArraySet<>();
//连接时执行
@OnOpen
public void onOpen(Session session){
this.session = session;
webSocket.add(this);
log.info("websocket有新连接,总数:"+webSocket.size());
}
//收到消息时执行
@OnMessage
public void onMessage(String message,Session session){
log.info("websocket收到客户端消息:"+message);
}
//关闭时执行
@OnClose
public void onClose(){
webSocket.remove(this);
log.info("websocket断开连接,总数:"+webSocket.size());
}
public void sendMessage(String message){
for(WebSocket websocket:webSocket){
log.info("websocket广播消息:"+message);
try{
websocket.session.getBasicRemote().sendText(message);
}catch (IOException e){
e.printStackTrace();
}
}
}
}