Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 成人免费午夜视频,日本一级特黄完整大片,99精品视频在线观看免费

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          利用Spring WebFlux 整合Bootstr

          利用Spring WebFlux 整合Bootstrap模板引擎技術實現單頁面應用?

          以按照以下步驟進行來實現,在Spring Boot中使用Spring WebFlux結合Bootstrap模板引擎實現單頁面應用(SPA)。

          配置依賴

          需要在POM文件中添加Spring Reactive Web、 Thymeleaf、Spring Data Reactive MongoDB等依賴配置,如下所示。

          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-webflux</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-data-mongodb-reactive</artifactId> <!-- 如果需要持久化 -->
          </dependency>

          如果有特殊的需求,可以在application.yml或application.properties中添加WebFlux相關的配置信息,如果沒有就可以不用配置了。

          創建模板文件

          在src/main/resources/templates目錄下創建Thymeleaf模板文件(或者你選擇的其他模板文件)。例如,創建index.html文件。

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <title>SPA with Spring WebFlux</title>
              <!-- Bootstrap CSS -->
              <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
          </head>
          <body>
              <div class="container">
                  <h1 class="mt-5">Hello, Spring WebFlux with Bootstrap!</h1>
                  <!-- Add your SPA content here -->
                  <div id="app"></div>
              </div>
              <!-- Bootstrap JS -->
              <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
              <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.1/dist/umd/popper.min.js"></script>
              <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
          </body>
          </html>
          

          創建Controller

          定義一個Controller來處理前端請求,如下所示。

          import org.springframework.stereotype.Controller;
          import org.springframework.web.bind.annotation.GetMapping;
          import org.springframework.web.bind.annotation.RequestMapping;
          import reactor.core.publisher.Mono;
          
          @Controller
          @RequestMapping("/")
          public class MainController {
          
              @GetMapping
              public Mono<String> index() {
                  return Mono.just("index"); // 指向模板文件名
              }
          }

          為了使你的應用能夠處理SPA的前端路由,你需要在Controller中添加相應的路由處理邏輯,或者利用JavaScript前端框架(如React、Vue.js等)來管理前端路由。

          啟動Spring Boot應用,訪問http://localhost:8080(默認端口),應該能夠看到使用Bootstrap樣式的頁面。

          總結

          通過這種方式,你可以利用Spring WebFlux的響應式特性和Bootstrap的前端樣式來構建現代化的單頁面應用。如果你需要使用現代SPA框架(如React、Vue.js),你可以將其構建后的靜態文件放在src/main/resources/static目錄中,并配置Spring Boot以提供這些靜態資源。

          pringboot是如何路由到頁面?

          現在我們創建了一個新的springboot的web工程

          非常干凈。

          resources目錄下面有兩個空的文件夾static和templates

          static是用來放靜態資源的,包括靜態頁面,css,js,圖片等等

          template用來放動態頁面,就是要根據java后臺代碼的返回值來動態生成的

          實驗1:路由到靜態頁面

          先什么依賴都不加,當前我的maven依賴只有

          <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
          </dependency>
          

          在static下建一個login.html

          <!doctype html>
          <html lang="en">
          <head>
          <meta charset="UTF-8"/>
          </head>
          <body>
          <h2>
          這是一個靜態登錄頁面
          </h2>
          </body>
          </html>
          

          啟動

          測試

          可以看到,默認情況下springboot會直接訪問到static下的靜態文件

          必須加文件的后綴名。

          實驗二:建一個controller,處理下請求

          測試結果:

          可以看到,經過controller處理了一下請求,找到了靜態資源

          但是,我們后臺開發主要還是使用動態頁面。現在引入Thymeleaf

          <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-thymeleaf</artifactId>
          </dependency>
          

          實驗三:引入Thymeleaf后測試

          在templates路徑下也創建一個login.html

          測試:

          已經找的是templates下的文件了。這說明引入Thymeleaf后,通過java代碼處理的請求,默認是找templates下的文件

          當然,你測試

          依然是靜態頁面

          另外,此時,你的java代碼返回值帶不帶html后綴都可以

          實驗四:加點數據看看

          我們的最終目的是根據后臺數據動態生成頁面

          所以傳點數據看看

          Hi,大家好,我是希留。

          在項目的開發工程中,可能會遇到實時性比較高的場景需求,例如說,聊天 IM 即時通訊功能、消息訂閱服務、在線客服等等。那遇到這種功能的時候應該怎么去做呢?通常是使用WebSocket去實現。

          那么,本篇文章就帶大家來了解一下是什么是WebSocket,以及使用SpringBoot搭建一個簡易的聊天室功能。如果對你有幫助的話,還不忘點贊轉發支持一下,感謝!

          源碼地址:

          https://github.com/277769738/java-sjzl-demo/tree/master/springboot-websocket

          https://gitee.com/huoqstudy/java-sjzl-demo/tree/master/springboot-websocket

          目錄

          • 一、什么是WebSocket
          • 二、Http與WebSocket的區別
          • 三、代碼實現

          一、什么是WebSocket

          WebSocket 是HTML5一種新的協議。它實現了瀏覽器與服務器全雙工通信(full-duplex)。一開始的握手需要借助HTTP請求完成。WebSocket是真正實現了全雙工通信的服務器向客戶端推的互聯網技術。它是一種在單個TCP連接上進行全雙工通訊協議。Websocket通信協議于2011年被IETF定為標準RFC 6455,Websocket API被W3C定為標準。

          全雙工和單工的區別?

          • 全雙工(Full Duplex)是通訊傳輸的一個術語。通信允許數據在兩個方向上同時傳輸,它在能力上相當于兩個單工通信方式的結合。全雙工指可以同時(瞬時)進行信號的雙向傳輸(A→B且B→A)。指A→B的同時B→A,是瞬時同步的。
          • 單工、半雙工(Half Duplex),所謂半雙工就是指一個時間段內只有一個動作發生,舉個簡單例子,一條窄窄的馬路,同時只能有一輛車通過,當目前有兩輛車對開,這種情況下就只能一輛先過,等到頭兒后另一輛再開,這個例子就形象的說明了半雙工的原理。早期的對講機、以及早期集線器等設備都是基于半雙工的產品。隨著技術的不斷進步,半雙工會逐漸退出歷史舞臺。

          二、Http與WebSocket的區別

          http協議是短連接,因為請求之后,都會關閉連接,下次重新請求數據,需要再次打開鏈接。

          WebSocket協議是一種長鏈接,只需要通過一次請求來初始化鏈接,然后所有的請求和響應都是通過這個TCP鏈接進行通訊。

          三、代碼實現


          1.添加依賴

          Maven 依賴:

          <!--websocket依賴-->
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-websocket</artifactId>
          </dependency>
          
          <!-- 引入 Fastjson ,實現對 JSON 的序列化,因為后續我們會使用它解析消息 -->
          <dependency>
              <groupId>com.alibaba</groupId>
              <artifactId>fastjson</artifactId>
              <version>1.2.62</version>
          </dependency>

          2.消息

          因為 WebSocket 協議,不像 HTTP 協議有 URI 可以區分不同的 API 請求操作,所以我們需要在 WebSocket 的 Message 里,增加能夠標識消息類型,這里我們采用 type 字段。所以在這個示例中,我們采用的 Message 采用 JSON 格式編碼,格式如下:

          {
              type : "", //消息類型
              boby: {} //消息體
          }
          • type 字段,消息類型。通過該字段,我們知道使用哪個 MessageHandler 消息處理器。關于 MessageHandler ,我們在 「2.6 消息處理器」 中,詳細解析。
          • body 字段,消息體。不同的消息類型,會有不同的消息體。

          2.1 Message

          創建 Message 接口,基礎消息體,所有消息體都要實現該接口。目前作為一個標記接口,未定義任何操作。代碼如下:

          public interface Message {
          
          }

          2.2 認證相關 Message

          創建 AuthRequest 類,用戶認證請求。代碼如下:

          public class AuthRequest implements Message{
              public static final String TYPE="AUTH_REQUEST";
          
              /**
               * 認證 Token
               */
              private String accessToken;
          
              public String getAccessToken() {
                  return accessToken;
              }
          
              public void setAccessToken(String accessToken) {
                  this.accessToken=accessToken;
              }
          }

          TYPE 靜態屬性,消息類型為 AUTH_REQUEST 。

          accessToken 屬性,認證 Token 。在 WebSocket 協議中,我們也需要認證當前連接,用戶身份是什么。一般情況下,我們采用用戶調用 HTTP 登錄接口,登錄成功后返回的訪問令牌 accessToken 。

          2.3 創建AuthResponse 類

          WebSocket 協議是基于 Message 模型,進行交互。但是,這并不意味著它的操作,不需要響應結果。例如說,用戶認證請求,是需要用戶認證響應的。所以,我們創建 AuthResponse 類,作為用戶認證響應。代碼如下:

          public class AuthResponse implements Message {
          
              public static final String TYPE="AUTH_RESPONSE";
          
              /**
               * 響應狀態碼
               */
              private Integer code;
              /**
               * 響應提示
               */
              private String message;
          
              public Integer getCode() {
                  return code;
              }
          
              public void setCode(Integer code) {
                  this.code=code;
              }
          
              public String getMessage() {
                  return message;
              }
          
              public void setMessage(String message) {
                  this.message=message;
              }
          }

          2.4 發送消息相關 Message

          創建 SendToOneRequest 類,發送給指定人的私聊消息的 Message。代碼如下:

          public class SendToOneRequest implements Message {
          
              public static final String TYPE="SEND_TO_ONE_REQUEST";
          
              /**
               * 發送給的用戶
               */
              private String toUser;
          
              /**
               * 消息編號
               */
              private String msgId;
          
              /**
               * 發送的內容
               */
              private String content;
          
          
              public String getToUser() {
                  return toUser;
              }
          
              public void setToUser(String toUser) {
                  this.toUser=toUser;
              }
          
              public String getMsgId() {
                  return msgId;
              }
          
              public void setMsgId(String msgId) {
                  this.msgId=msgId;
              }
          
              public String getContent() {
                  return content;
              }
          
              public void setContent(String content) {
                  this.content=content;
              }
          }

          在服務端接收到發送消息的請求,需要異步響應發送是否成功。所以,創建 SendResponse 類,發送消息響應結果的 Message 。代碼如下:

          public class SendResponse implements Message{
          
              public static final String TYPE="SEND_RESPONSE";
          
              /**
               * 消息編號
               */
              private String msgId;
              /**
               * 響應狀態碼
               */
              private Integer code;
              /**
               * 響應提示
               */
              private String message;
          }

          在服務端接收到發送消息的請求,需要轉發消息給對應的人。所以,創建 SendToUserRequest 類,發送消息給一個用戶的 Message 。代碼如下:

          public class SendToUserRequest implements Message{
          
              public static final String TYPE="SEND_TO_USER_REQUEST";
          
              /**
               * 消息編號
               */
              private String msgId;
              /**
               * 內容
               */
              private String content;
          
              public String getMsgId() {
                  return msgId;
              }
          
              public void setMsgId(String msgId) {
                  this.msgId=msgId;
              }
          
              public String getContent() {
                  return content;
              }
          
              public void setContent(String content) {
                  this.content=content;
              }
          }

          2.5 消息處理器

          每個客戶端發起的 Message 消息類型,我們會聲明對應的 MessageHandler 消息處理器。這個就類似在 SpringMVC 中,每個 API 接口對應一個 Controller 的 Method 方法。

          2.5.1 MessageHandler

          創建 MessageHandler 接口,消息處理器接口。代碼如下:

          public interface MessageHandler<T extends Message> {
          
              /**
               * 執行處理消息
               * @param session 會話
               * @param message 消息
               */
              void execute(WebSocketSession session, T message);
          
              /**
               * 消息類型,即每個 Message 實現類上的 TYPE 靜態字段
               * @return
               */
              String getType();
          }
          • 定義了泛型 <T> ,需要是 Message 的實現類。
          • 定義的兩個接口方法。

          2.5.2 AuthMessageHandler

          創建 AuthMessageHandler 類,處理 AuthRequest 消息。代碼如下:

          @Component
          public class AuthMessageHandler implements MessageHandler<AuthRequest>{
          
              @Override
              public void execute(WebSocketSession session, AuthRequest message) {
                  // 如果未傳遞 accessToken
                  if (StringUtils.isEmpty(message.getAccessToken())) {
                      AuthResponse authResponse=new AuthResponse();
                      authResponse.setCode(1);
                      authResponse.setMessage("認證 accessToken 未傳入");
                      WebSocketUtil.send(session, AuthResponse.TYPE,authResponse);
                      return;
                  }
          
                  // 添加到 WebSocketUtil 中,考慮到代碼簡化,我們先直接使用 accessToken 作為 User
                  WebSocketUtil.addSession(session, message.getAccessToken());
          
                  // 判斷是否認證成功。這里,假裝直接成功
                  AuthResponse authResponse=new AuthResponse();
                  authResponse.setCode(0);
                  WebSocketUtil.send(session, AuthResponse.TYPE, authResponse);
              }
          
              @Override
              public String getType() {
                  return AuthRequest.TYPE;
              }
          }
          • 關于 WebSocketUtil 類,我們在 「2.6 WebSocketUtil」 中來看看。

          2.5.3 SendToOneRequest

          創建 SendToOneHandler 類,處理 SendToOneRequest 消息。代碼如下:

          @Component
          public class SendToOneHandler implements MessageHandler<SendToOneRequest>{
          
              @Override
              public void execute(WebSocketSession session, SendToOneRequest message) {
                  // 這里,假裝直接成功
                  SendResponse sendResponse=new SendResponse();
                  sendResponse.setMsgId(message.getMsgId());
                  sendResponse.setCode(0);
                  WebSocketUtil.send(session, SendResponse.TYPE, sendResponse);
          
                  // 創建轉發的消息
                  SendToUserRequest sendToUserRequest=new SendToUserRequest();
                  sendToUserRequest.setMsgId(message.getMsgId());
                  sendToUserRequest.setContent(message.getContent());
          
                  // 廣播發送
                  WebSocketUtil.send(message.getToUser(), SendToUserRequest.TYPE, sendToUserRequest);
              }
          
              @Override
              public String getType() {
                  return SendToOneRequest.TYPE;
              }
          }

          2.5.4 SendToAllHandler

          創建 SendToAllHandler 類,處理 SendToAllRequest 消息。代碼如下:

          @Component
          public class SendToAllHandler implements MessageHandler<SendToAllRequest> {
          
              @Override
              public void execute(WebSocketSession session, SendToAllRequest message) {
                  // 這里,假裝直接成功
                  SendResponse sendResponse=new SendResponse();
                  sendResponse.setMsgId(message.getMsgId());
                  sendResponse.setCode(0);
                  WebSocketUtil.send(session, SendResponse.TYPE, sendResponse);
          
                  // 創建轉發的消息
                  SendToUserRequest sendToUserRequest=new SendToUserRequest();
                  sendToUserRequest.setMsgId(message.getMsgId());
                  sendToUserRequest.setContent(message.getContent());
          
                  // 廣播發送
                  WebSocketUtil.broadcast(SendToUserRequest.TYPE, sendToUserRequest);
              }
          
              @Override
              public String getType() {
                  return SendToAllRequest.TYPE;
              }
          }

          2.6 WebSocketUtil

          創建 WebSocketUtil 工具類,代碼如下,主要提供兩方面的功能:

          • Session 會話的管理
          • 多種發送消息的方式
          public class WebSocketUtil {
          
              private static final Logger LOGGER=LoggerFactory.getLogger(WebSocketUtil.class);
          
              /**
               * Session 與用戶的映射
               */
              private static final Map<WebSocketSession, String> SESSION_USER_MAP=new ConcurrentHashMap<>();
              /**
               * 用戶與 Session 的映射
               */
              private static final Map<String, WebSocketSession> USER_SESSION_MAP=new ConcurrentHashMap<>();
          
              /**
               * 添加 Session 。在這個方法中,會添加用戶和 Session 之間的映射
               * @param session Session
               * @param user 用戶
               */
              public static void addSession(WebSocketSession session, String user) {
                  // 更新 USER_SESSION_MAP
                  USER_SESSION_MAP.put(user, session);
                  // 更新 SESSION_USER_MAP
                  SESSION_USER_MAP.put(session, user);
              }
          
          
              /**
               * 發送消息給單個用戶的 Session
               * @param session Session
               * @param type 消息類型
               * @param message 消息體
               * @param <T> 消息類型
               */
              public static <T extends Message> void send(WebSocketSession  session, String type, T message) {
                  // 創建消息
                  TextMessage  messageText=buildTextMessage(type, message);
                  // 遍歷給單個 Session ,進行逐個發送
                  sendTextMessage(session, messageText);
              }
              /**
               * 廣播發送消息給所有在線用戶
               * @param type 消息類型
               * @param message 消息體
               * @param <T> 消息類型
               */
              public static <T extends Message> void broadcast(String type, T message) {
                  // 創建消息
                  TextMessage messageText=buildTextMessage(type, message);
                  // 遍歷 SESSION_USER_MAP ,進行逐個發送
                  for (WebSocketSession session : SESSION_USER_MAP.keySet()) {
                      sendTextMessage(session, messageText);
                  }
              }
          
              /**
               * 發送消息給指定用戶
               * @param user 指定用戶
               * @param type 消息類型
               * @param message 消息體
               * @param <T> 消息類型
               * @return 發送是否成功
               */
              public static <T extends Message> boolean send(String user, String type, T message) {
                  // 獲得用戶對應的 Session
                  WebSocketSession session=USER_SESSION_MAP.get(user);
                  if (session==null) {
                      LOGGER.error("[send][user({}) 不存在對應的 session]", user);
                      return false;
                  }
                  // 發送消息
                  send(session, type, message);
                  return true;
              }
          
              /**
               * 構建完整的消息
               * @param type 消息類型
               * @param message 消息體
               * @param <T> 消息類型
               * @return 消息
               */
              private static <T extends Message> TextMessage  buildTextMessage(String type, T message) {
                  JSONObject messageObject=new JSONObject();
                  messageObject.put("type", type);
                  messageObject.put("body", message);
                  return new TextMessage(messageObject.toString());
              }
          
              /**
               * 真正發送消息
               *
               * @param session Session
               * @param textMessage 消息
               */
              private static void sendTextMessage(WebSocketSession  session, TextMessage textMessage) {
                  if (session==null) {
                      LOGGER.error("[sendTextMessage][session 為 null]");
                      return;
                  }
                  try {
                      session.sendMessage(textMessage);
                  } catch (IOException e) {
                      LOGGER.error("[sendTextMessage][session({}) 發送消息{}) 發生異常",
                              session, textMessage, e);
                  }
              }
          
          }

          3.編寫處理類MyHandler

          處理類,在Spring中,處理消息的具體業務邏輯,進行開啟、關閉連接等操作。

          public class MyHandler extends TextWebSocketHandler implements InitializingBean {
              private Logger logger=LoggerFactory.getLogger(getClass());
              /**
               * 消息類型與 MessageHandler 的映射
               * 無需設置成靜態變量
               */
              private final Map<String, MessageHandler> HANDLERS=new HashMap<>();
              @Autowired
              private ApplicationContext applicationContext;
          
          
              @Override
              public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
                  System.out.println("獲取到消息 >> " + message.getPayload());
                  logger.info("[handleMessage][session({}) 接收到一條消息({})]", session, message);
                  // 獲得消息類型
                  JSONObject jsonMessage=JSON.parseObject(message.getPayload());
                  String messageType=jsonMessage.getString("type");
                  // 獲得消息處理器
                  MessageHandler messageHandler=HANDLERS.get(messageType);
                  if (messageHandler==null) {
                      logger.error("[onMessage][消息類型({}) 不存在消息處理器]", messageType);
                      return;
                  }
                  // 解析消息
                  Class<? extends Message> messageClass=this.getMessageClass(messageHandler);
                  // 處理消息
                  Message messageObj=JSON.parseObject(jsonMessage.getString("body"), messageClass);
                  messageHandler.execute(session, messageObj);
              }
          
              /**
               * 連接建立時觸發
               **/
              @Override
              public void afterConnectionEstablished(WebSocketSession session) throws Exception {
                  logger.info("[afterConnectionEstablished][session({}) 接入]", session);
                  // 解析 accessToken
                  String accessToken=(String) session.getAttributes().get("accessToken");
                  // 創建 AuthRequest 消息類型
                  AuthRequest authRequest=new AuthRequest();
                  authRequest.setAccessToken(accessToken);
                  // 獲得消息處理器
                  MessageHandler<AuthRequest> messageHandler=HANDLERS.get(AuthRequest.TYPE);
                  if (messageHandler==null) {
                      logger.error("[onOpen][認證消息類型,不存在消息處理器]");
                      return;
                  }
                  messageHandler.execute(session, authRequest);
              }
          
              /**
               * 關閉連接時觸發
               **/
              @Override
              public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
                  System.out.println("斷開連接!");
              }
          
              @Override
              public void afterPropertiesSet() throws Exception {
                  // 通過 ApplicationContext 獲得所有 MessageHandler Bean
                  applicationContext.getBeansOfType(MessageHandler.class).values()
                          // 添加到 handlers 中
                          .forEach(messageHandler -> HANDLERS.put(messageHandler.getType(), messageHandler));
                  logger.info("[afterPropertiesSet][消息處理器數量:{}]", HANDLERS.size());
              }
          
              private Class<? extends Message> getMessageClass(MessageHandler handler) {
                  // 獲得 Bean 對應的 Class 類名。因為有可能被 AOP 代理過。
                  Class<?> targetClass=AopProxyUtils.ultimateTargetClass(handler);
                  // 獲得接口的 Type 數組
                  Type[] interfaces=targetClass.getGenericInterfaces();
                  Class<?> superclass=targetClass.getSuperclass();
                  // 此處,是以父類的接口為準
                  while ((Objects.isNull(interfaces) || 0==interfaces.length) && Objects.nonNull(superclass)) {
                      interfaces=superclass.getGenericInterfaces();
                      superclass=targetClass.getSuperclass();
                  }
                  if (Objects.nonNull(interfaces)) {
                      // 遍歷 interfaces 數組
                      for (Type type : interfaces) {
                          // 要求 type 是泛型參數
                          if (type instanceof ParameterizedType) {
                              ParameterizedType parameterizedType=(ParameterizedType) type;
                              // 要求是 MessageHandler 接口
                              if (Objects.equals(parameterizedType.getRawType(), MessageHandler.class)) {
                                  Type[] actualTypeArguments=parameterizedType.getActualTypeArguments();
                                  // 取首個元素
                                  if (Objects.nonNull(actualTypeArguments) && actualTypeArguments.length > 0) {
                                      return (Class<Message>) actualTypeArguments[0];
                                  } else {
                                      throw new IllegalStateException(String.format("類型(%s) 獲得不到消息類型", handler));
                                  }
                              }
                          }
                      }
                  }
                  throw new IllegalStateException(String.format("類型(%s) 獲得不到消息類型", handler));
              }
          }

          4.創建攔截器MyHandshakeInterceptor

          在Spring中提供了websocket攔截器,可以在建立連接之前寫些業務邏輯,比如校驗登錄等。

          public class MyHandshakeInterceptor extends HttpSessionHandshakeInterceptor {
          
              /**
              * @Description 握手之前,若返回false,則不建立鏈接
              * @Date 21:59 2021/5/16
              * @return boolean
              **/
              @Override
              public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> attributes) throws Exception {
                  //獲得 accessToken ,將用戶id放入socket處理器的會話(WebSocketSession)中
                  if (serverHttpRequest instanceof ServletServerHttpRequest) {
                      ServletServerHttpRequest serverRequest=(ServletServerHttpRequest) serverHttpRequest;
                      attributes.put("accessToken", serverRequest.getServletRequest().getParameter("accessToken"));
                  }
                  // 調用父方法,繼續執行邏輯
                  return super.beforeHandshake(serverHttpRequest, serverHttpResponse, webSocketHandler, attributes);
              }

          5.創建配置類

          @Configuration
          @EnableWebSocket //開啟spring websocket功能
          public class WebSocketConfig implements WebSocketConfigurer {
          
              @Override
              public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
                  //配置處理器
                  registry.addHandler(this.myHandler(), "/")
                          //配置攔截器
                          .addInterceptors(new MyHandshakeInterceptor())
                          .setAllowedOrigins("*");
              }
          
              @Bean
              public WebSocketHandler myHandler() {
                  return new MyHandler();
              }
          
              @Bean
              public MyHandshakeInterceptor webSocketShakeInterceptor() {
                  return new MyHandshakeInterceptor();
              }
          }

          6.創建啟動類

          @SpringBootApplication
          public class MyWebsocketApplication {
          
              public static void main(String[] args) {
                  SpringApplication.run(MyWebsocketApplication.class,args);
              }
          }

          7.實現效果


          打開三個瀏覽器,輸入在線測試websocket地址:

          http://www.easyswoole.com/wstool.html

          創建三個連接。分別設置服務地址如下:

          • ws://localhost:8080/?accessToken=1001
          • ws://localhost:8080/?accessToken=1002
          • ws://localhost:8080/?accessToken=1003

          發送單人消息

          {
             tpye: "SEND_TO_ONE_REQUEST",
             boby: {
                          toUser: "1002",
                          msgId: "qwwerqrsfd123",
                          centent: "這是1001發送給1002的單聊消息"
              }
          }

          可以看到1002收到了1001發的單聊信息,1003未收到。效果圖如下:

          發送多人消息

          {
             tpye: "SEND_TO_ALL_REQUEST",
             boby: {
                          msgId: "qwerqcfwwerqrsfd123",
                          centent: "我是一條群聊消息"
              }
          }

          可以看到1001,1002,1003都收到了消息,效果圖如下:


          結語

          好了,以上就是今天要講的內容,本文介紹了WebSocket協議以及使用它簡單的實現及時聊天的場景。

          感謝大家的閱讀,喜歡的朋友,歡迎點贊支持一下。


          主站蜘蛛池模板: 国产在线一区二区视频| 久久影院亚洲一区| 国产伦精品一区二区三区免费下载| 久久99精品波多结衣一区| 国产激情视频一区二区三区| 久久er99热精品一区二区| 97久久精品无码一区二区天美 | 国产在线视频一区二区三区98| 国产一区二区高清在线播放| 亚洲一区二区三区偷拍女厕| 2022年亚洲午夜一区二区福利 | 视频在线观看一区二区三区| 日本大香伊一区二区三区| 亚洲一区二区三区在线观看蜜桃| 久久一区二区三区精华液使用方法| 老鸭窝毛片一区二区三区| 亚洲国产精品自在线一区二区| 人妻精品无码一区二区三区| 国产高清一区二区三区四区| 无码乱人伦一区二区亚洲一| 亚洲高清毛片一区二区| 久99精品视频在线观看婷亚洲片国产一区一级在线 | 精品一区二区三区免费| 日韩免费一区二区三区在线播放| 免费无码AV一区二区| 无码人妻久久久一区二区三区| 无码一区二区三区免费视频| 中文字幕一区在线播放| 亚洲一区二区无码偷拍| 国产精品 一区 在线| 欧美日韩国产免费一区二区三区 | 国产99精品一区二区三区免费| 无码精品一区二区三区在线| 国产精品亚洲专一区二区三区| 久久4k岛国高清一区二区| 色噜噜一区二区三区| 91精品一区二区三区久久久久| 合区精品久久久中文字幕一区| 精品少妇人妻AV一区二区三区| 国产午夜精品一区二区三区 | 久久久国产一区二区三区|