spring boot(学习笔记第十六课)

spring boot(学习笔记第十六课)

  • Spring boot的websocket(点对点)

学习内容:

  • Spring boot的websocket(点对点)spring boot(学习笔记第十六课)

1. Spring boot的websocket(点对点)

  1. 前面练习了websocket的广播模式。

  2. 接下来练习websocket的点对点模式

    这里主要使用spring security,进行login,让spring boot认识到每个用户的存在,之后SimpMesssagingTemplateconvertAndSendToUser进行最终的发送。

    • 使用spring security进行login
    • 使用SimpMesssagingTemplateconvertAndSendToUser进行单独想单独用户发送。
      是和websocket广播最大的不同。
  3. 开始结合代码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这个beanconvertAndSendToUser进行指定名字的点对点发送。
      • from就是spring securityPrincipal获得的当前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处理

      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();
          });
      }
    • 接下来既可以测试点对点的聊天

相关推荐
sulikey6 小时前
个人Linux操作系统学习笔记6 - 操作系统与进程初识
linux·笔记·学习·操作系统·进程
unicorn317 小时前
学习学习学习
学习
XGeFei7 小时前
【Fastapi学习笔记(3)】——资源的层级关系、安全性-幂等性、Field、工厂函数
笔记·学习·fastapi
逍遥德7 小时前
MQTT教程详解-04.SpringBoot集成MQTT(告别手动控制)
java·spring boot·物联网·中间件·iot·iotdb
星恒随风8 小时前
Python 基础语法详解(一):从表达式、变量到数据类型
开发语言·笔记·python·学习
暴躁小师兄数据学院10 小时前
【AI大数据工程师特训笔记】第14讲:Linux操作系统与shell脚本
大数据·人工智能·笔记
tedcloud12310 小时前
cc-switch评测:多AI Coding Agent管理工具详解
数据库·人工智能·sql·学习·自动化
土狗TuGou10 小时前
SQL内功笔记 · 第8篇:事务的四大特性与隔离级别
数据库·笔记·后端·sql·mysql·oracle
胡图图不糊涂^_^11 小时前
测试BUG篇
学习·bug·测试
智者知已应修善业11 小时前
【51单片机用T0定时器方式1,实现0.5S的时间间隔实现第一次一个灯亮、第二次二个灯亮,直到全部灯亮,然后重复整个过程】2023-12-29
c++·经验分享·笔记·算法·51单片机