spring boot(学习笔记第十六课)
- Spring boot的websocket(点对点)
学习内容:
- Spring boot的websocket(点对点)spring boot(学习笔记第十六课)
1. Spring boot的websocket(点对点)
-
前面练习了
websocket的广播模式。

-
接下来练习
websocket的点对点模式

这里主要使用spring security,进行login,让spring boot认识到每个用户的存在,之后SimpMesssagingTemplate的convertAndSendToUser进行最终的发送。- 使用
spring security进行login - 使用
SimpMesssagingTemplate的convertAndSendToUser进行单独想单独用户发送。
是和websocket广播最大的不同。
- 使用
-
开始结合代码
websocket的点对点模式-
导入
spring security的认证@Configuration public class SecurityConfig { @Bean PasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); } @Bean UserDetailsService userDetailsService() { InMemoryUserDetailsManager users = new InMemoryUserDetailsManager(); users.createUser(User.withUsername("finlay_admin") .password("123456") .roles("ADMIN") .build()); users.createUser(User.withUsername("finlay_dba") .password("123456") .roles("DBA") .build()); users.createUser(User.withUsername("finlay_super") .password("123456") .roles("ADMIN", "DBA") .build()); return users; } @Bean SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception { httpSecurity.authorizeHttpRequests( auth -> auth.requestMatchers("/admin/**")//匹配所有/** url .hasRole("ADMIN")//只能对于admin的role,才能访问 .requestMatchers("/user/**")//匹配/user/** .hasRole("USER")//只有对于user的role,才能访问 .requestMatchers("/db/**")//配置/db/** .hasRole("DBA")//只有对于dba的role,才能访问 .anyRequest() .authenticated()//设定任何访问都需要认证 ) .formLogin(form -> form.loginProcessingUrl("/login")//这里对于前后端分离,提供的非页面访问url .usernameParameter("username")//页面上form的用户名 .passwordParameter("password"))//页面上form的密码 .csrf(csrf -> csrf.disable())//csrf跨域访问无效 .sessionManagement(session -> session.maximumSessions(1).maxSessionsPreventsLogin(true)); return httpSecurity.build(); } -
导入
spring security的需要的依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> -
导入
spring security的需要的依赖@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry messageBrokerRegistry) { messageBrokerRegistry.enableSimpleBroker("/topic","/private_chat"); messageBrokerRegistry.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry){ stompEndpointRegistry.addEndpoint("/chat").withSockJS(); } }/private_chat是设置的点对点聊天的时候,从web server发送到浏览器时候使用的url。/app是从浏览器发送到的web server时候,使用的url的前缀。/chat是浏览器和web server建立连接时候的endPoint。
-
定义
WebSocketController@Controller public class WebSocketController { @Autowired SimpMessagingTemplate simpMessagingTemplate; @MessageMapping("/hello") @SendTo("/topic/greetings") public Message greeting(Message message) throws Exception { return message; } @MessageMapping("/chat") public void chat(Principal principal, Chat chat) throws Exception { String from = principal.getName(); chat.setFrom(from); simpMessagingTemplate.convertAndSendToUser(chat.getTo() ,"/private_chat/chat",chat); } }SimpMessagingTemplate这个bean就是点对点发送的关键对象。@MessageMapping("/chat")定义了之后,可以通过/app/chat进行从浏览器到web server的点对点发送。- 其中,点对点的发送请求时候,浏览器会指定
to用户的名称,也就是spring security的登录用户名字。 - 之后利用
SimpMessagingTemplate这个bean的convertAndSendToUser进行指定名字的点对点发送。 from就是spring security的Principal获得的当前session的用户名。
-
定义点对点聊天的
html页面(chatOnline.html)<!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> <script src="/chats.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> </div> </div> </body> </html -
定义点对点聊天的
javascript处理var stompClient = null; function connect(){ var socket = new SockJS('/chat'); stompClient = Stomp.over(socket); stompClient.connect({},function (frame){ stompClient.subscribe('/user/private_chat/chat',function(chat){ showGreeting(JSON.parse(chat.body)); }); }); } function sendMessage(){ stompClient.send("/app/chat",{}, JSON.stringify({'to':$("#to").val(),'content':$("#content").val()})); } function showGreeting(message){ $("#chatsContent").append("<div>" + message.from+ ":" + message.content + "</div>"); } $(function(){ connect(); $("#send").click(function(){ sendMessage(); }); } -
接下来既可以测试点对点的聊天

-


