依赖配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--webSocket-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>sockjs-client</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>stomp-websocket</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1</version>
</dependency>
群聊
socket config配置
@Configuration
@EnableWebSocketMessageBroker // 开启WebSocket消息代理
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config){
// 设置消息代理的前缀,将消息转发给消息代理(broker),消息代理将消息广播给当前连接的客户端
config.enableSimpleBroker("/topic");
// 可以配置一个或多个前缀,过滤出需要被注解方法处理的消息,该消息将被requestMapping注解方法处理
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry){
// sockjs可以解决浏览器对WebSocket的兼容问题,客户端将通过这里配置的URL来建立WebSocket连接
registry.addEndpoint("/chat").withSockJS();
}
}
controller配置
@Controller
public class GreetingController {
// 使用SendTo注解将方法处理过的消息转发给broker,再由broker进行消息广播
@MessageMapping("/hello") // 在注解中对消息进行处理后,再将消息转发到@SendTo定义的路径上
@SendTo("/topic/greetings") // 该消息将被交给消息代理broker进行广播
public Message greeting(Message message) throws Exception{
return message;
}
}
Message
public class Message {
private String name;
private String content;
...
}
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<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>
<div>
<label for="name">请输入用户名:</label>
<input type="text" id="name" placeholder="用户名">
</div>
<div>
<button id="connect" type="button">连接</button>
<button id="disconnect" type="button" disabled="disabled">断开连接</button>
</div>
<div id="chat" style="display:none;">
<div>
<label for="name">请输入聊天内容:</label>
<input type="text" id="content" placeholder="聊天内容">
</div>
<button id="send" type="button">发送</button>
<div id="greetings">
<div id="conversation" style="display:none">群聊进行中 ... </div>
</div>
</div>
</body>
<script>
var stompClient=null ;
function setConnected (connected) {
$("#connect").prop(" disabled", connected);
$("#disconnect").prop("disabled", !connected);
if (connected) {
$("#conversation").show();
$("#chat").show()
} else {
$(" #conversation ").hide();
$(" #chat ").hide();
$(" #greetings").html("");
}
}
function connect() {
console.log($("#name").val())
if (!$("#name").val()) {
return;
}
// 建立webSocket连接
var socket = new SockJS ('/chat');
// 发起连接请求
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
// 订阅服务端发送回来的消息
stompClient.subscribe('/topic/greetings', function(greeting) {
showGreeting(JSON.parse(greeting.body));
})
})
}
function disconnect () {
if (stompClient !== null) {
// 断开连接请求
stompClient.disconnect();
}
setConnected(false)
}
function sendName () {
stompClient.send("/app/hello", {}, JSON.stringify({'name': $( "#name" ) .val () ,'content':$("#content").val()}));
}
function showGreeting(message){
$("#greetings").append ("<div>" + message.name + ":" + message.content + "</div>");
}
$(function(){
$("#connect").click(function(){
connect();
});
$("#disconnect").click(function(){
disconnect();
});
$("#send").click(function(){
sendName();
});
});
</script>
</html>
单聊
引入security
<!-- security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
security配置
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// 配置密码加密
@Bean
PasswordEncoder passwordEncoder(){
// 使用BCrypt强哈希函数,strength默认为10
return new BCryptPasswordEncoder();
}
// 配置用户
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.inMemoryAuthentication()
.withUser("admin")
.password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq") // 123
.roles("admin")
.and()
.withUser("sang")
.password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq") // 123
.roles("user");
}
@Override
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().permitAll(); // 相关接口都不需要认证即可访问
}
}
修改socket config配置
// configureMessageBroker 添加queue用以区分
config.enableSimpleBroker("/topic", "/queue");
controller
@Controller
public class GreetingController {
// messagingTemplate也可以发送消息,可以实现和SendTo一样的效果,可以在任意地方发送消息到broker,也可以发送给某一用户
@Autowired
SimpMessagingTemplate messagingTemplate;
// 点对点发送
@MessageMapping("/chat")
public void chat(Principal principal, Chat chat) throws Exception{
// Principal用来获取当前登录用户的信息
String from = principal.getName();
// Chat为客户端发送来的消息
chat.setFrom(from);
// convertAndSendToUser方法内部调用了convertAndSend方法
// 消息的最终发送路径是"/user/用户名/queue/chat"
messagingTemplate.convertAndSendToUser(chat.getTo(),"/queue/chat", chat);
}
}
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<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>
<div id="chat">
<div id="chatsContent"></div>
</div>
请输入聊天内容:
<input type="text" id="content" placeholder="聊天内容">
<input type="text" id="to" placeholder="目标用户">
<button id="send" type="button">发送</button>
</body>
<script>
var stompClient=null ;
function connect() {
// 建立webSocket连接
var socket = new SockJS ('/chat');
// 发起连接请求
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
// 订阅服务端发送回来的消息
stompClient.subscribe('/user/queue/chat', function(greeting) {
showGreeting(JSON.parse(greeting.body));
})
})
}
function sendMsg () {
stompClient.send("/app/chat", {}, JSON.stringify({'content':$("#content").val(), 'to': $("#to").val()}));
}
function showGreeting(message){
$("#chatsContent").append ("<div>" + message.from + ":" + message.content + "</div>");
}
$(function(){
connect();
$("#send").click(function(){
sendMsg();
});
});
</script>
</html>