什么是Websocket
websocket使得客户端和服务器之间的数据交换变得更加简单,他是全双工通信,我们可以利用浏览器给服务器发送数据,也允许服务端主动向客户端推送数据。在websocket api中浏览器和服务器只需完成一次握手,两者之间直接可以创建持久性的连接,并进行双向传输数据。
1.添加相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.webjars/sockjs-client -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>sockjs-client</artifactId>
<version>1.1.2</version>
</dependency><!-- https://mvnrepository.com/artifact/org.webjars/jquery -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency><!-- https://mvnrepository.com/artifact/org.webjars/stomp-websocket -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>stomp-websocket</artifactId>
<version>2.3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.webjars/webjars-locator-core -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
2.配置websocket
package com.gy.demowebsocket.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker//表示开启使用STOMP协议来传输基于代理的消息,Broker就是代理的意思。
public class WebsocketConfig implements WebSocketMessageBrokerConfigurer {
/**
* 注册stomp的端点
* @param registry
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
//允许使用socketJs方式访问,访问点为chat,允许跨域
//在网页上我们可以通过这个链接
//http://localhost:8080/chat
//来和服务器的websocket连接
registry.addEndpoint("/chat").setAllowedOrigins("*").withSockJS();//与socket建立连接
}
/**
* 配置信息代理
* @param registry
*/
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
//订阅Broker的名称(群聊)
registry.enableSimpleBroker("/topic");
//全局使用的消息前缀(客户端订阅路径上会体现出来)
registry.setApplicationDestinationPrefixes("/app");
}
}
3.消息实体类
package com.gy.demowebsocket.bean;
public class Message {
private String name;
private String content;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
4.控制层
package com.gy.demowebsocket.controller;
import com.gy.demowebsocket.bean.Message;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class GreetingController {
@Resource
SimpMessagingTemplate simpMessagingTemplate;
/* @MessageMapping("/hello")
@SendTo("/topic/greeting")
public Message greeting(Message message) {
return message;
}*/
//与上边是等价的
@MessageMapping("/hello")
public void greeting(Message message) {
simpMessagingTemplate.convertAndSend("/topic/greeting",message);
}
}
5.前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/webjars/jquery/jquery.min.js"></script>
<script src="/webjars/sockjs-client/sockjs.min.js"></script>
<script src="/webjars/stomp-websocket/stomp.min.js"></script>
</head>
<body>
<table>
<tr>
<td>请输入用户名:</td>
<td><input type="text" id="name" /></td>
</tr>
<tr>
<td><input type="button" id="connect" value="连接" /></td>
<td><input type="button" id="disconnect" disabled="disabled" value="断开连接" /></td>
</tr>
</table>
<div id="chat" style="display: none">
<table>
<tr>
<td>请输入聊天内容:</td>
<td><input type="text" id="content"/></td>
<td><input type="button" id="send" value="发送" /></td>
</tr>
</table>
<div id="conversation">群聊进行中...</div>
</div>
</body>
<script>
$(function () {
$("#connect").click(function () {
connect();
})
$("#disconnect").click(function () {
if(stompClient != null){
stompClient.disconnect();
}
setConnected(false);
})
$("#send").click(function () {
stompClient.send('/app/hello',{},JSON.stringify({'name':$("#name").val(),'content':$("#content").val()}));
})
})
var stompClient = null;
function connect() {
if(!$("#name").val()){
return;
}
var socket = new SockJS('/chat'); <!-- 与socket建立连接 -->
stompClient = Stomp.over(socket);
stompClient.connect({},function success() {
setConnected(true);
stompClient.subscribe('/topic/greeting',function success(msg) {
showGreeting(JSON.parse(msg.body));
})
})
}
function showGreeting(msg) {
$("#conversation").append('<div>'+msg.name+':'+msg.content+'</div>');
}
function setConnected(flag) {
$("#connect").prop("disabled",flag);
$("#disconnect").prop("disabled",!flag);
if(flag){
$("#chat").show();
}else{
$("#chat").hide();
}
}
</script>
</html>