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
的认证java@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
的需要的依赖xml<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
-
导入
spring security
的需要的依赖java@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
java@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)
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
处理javascriptvar 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(); }); }
-
接下来既可以测试点对点的聊天
-