SpringBoot中WebSocket的应用:即时通讯
程序员文章站
2022-07-13 14:52:39
...
1.新建一个springboot工程,添加websocket、Thymleaf,Security依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.配置WebSocket
package com.cvsea.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{
@Override
public void registerStompEndpoints(StompEndpointRegistry P_Registry) {
P_Registry.addEndpoint("/endpointChat").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry P_Registry) {
P_Registry.enableSimpleBroker("/queue");
}
}
3.配置SpringSecurity
package com.cvsea.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/", "/login").permitAll().anyRequest().authenticated().and().formLogin().loginPage("/login")
.defaultSuccessUrl("/chat").permitAll().and().logout().permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("pxs").password("123456").roles("USER").and().withUser("lgp").password("123456").roles("USER");
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/static/**");
}
}
4.配置WebMVC
package com.cvsea.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{
@Override
public void addViewControllers(ViewControllerRegistry P_Registry) {
P_Registry.addViewController("/login").setViewName("/login");
P_Registry.addViewController("/chat").setViewName("/chat");
}
}
5.前端控制器
package com.cvsea.contoller;
import java.security.Principal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
@Controller
public class ChatContoller {
@Autowired
private SimpMessagingTemplate messagingTemplate;
@MessageMapping("/chat")
public void handleChat(Principal P_Principal,String msg)
{
String strSendTo=P_Principal.getName().equals("pxs")?"lgp":"pxs";
System.out.println("strSendTo:"+strSendTo);
messagingTemplate.convertAndSendToUser(strSendTo, "/queue/notifications", P_Principal.getName()+"-Send:"+msg);
}
}
6.登录
/src/main/resources/templates/login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>登录</title>
</head>
<body>
<div th:if="${param.error}">无效的账号和密码</div>
<div th:if="${param.logout}">你已注销</div>
<form th:action="@{/login}" method="post">
<div><label>账号:<input type="text" name="username"/></label></div>
<div><label>密码:<input type="password" name="password"/></label></div>
<div><input type="submit" value="登录"/></div>
</form>
</body>
</html>
7.聊天主界面
/src/main/resources/templates/chat.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>即时通讯</title>
<script th:src="@{/websocket/js/sockjs.min.js}"></script>
<script th:src="@{/websocket/js/stomp.min.js}"></script>
<script th:src="@{/common/js/jquery.min.js}"></script>
</head>
<body>
<h2>即时通讯</h2>
<form id="cvseaForm">
<textarea rows="4" cols="60" name="text" id="content"></textarea>
<input type="submit" value="发送" />
</form>
<input type="button" value="断开连接" id="stop" />
<ul id="response"></ul>
<script th:inline="javascript">
var sock = new SockJS("endpointChat");
var stomp = Stomp.over(sock);
stomp.connect("guest", "guest", function(frame) {
stomp.subscribe("/user/queue/notifications", handleNotification);
});
$("#cvseaForm").submit(function(e) {
e.preventDefault();
var content = $("#content").val();
sendSpittle(content);
});
function handleNotification(message) {
$("#response").append("<li>Re:" + message.body + "</li>");
}
function sendSpittle(message) {
stomp.send("/chat", {}, message);
}
$("#stop").click(function() {
sock.close();
});
</script>
</body>
</html>
8.添加js脚本到/src/main/resources/static/
#stomp.min.js存放在/websocket/js/
http://www.bootcdn.cn/stomp.js/
#sockjs.min.js存放在/websocket/js/
http://www.bootcdn.cn/sockjs-client/
#jquery.min.js存放在/common/js/
http://www.bootcdn.cn/jquery/
9.运行测试
- 登录
- 聊天