开发者

java注解实现websocket服务的两种方式

开发者 https://www.devze.com 2024-08-10 14:03 出处:网络 作者: humannoid
目录1.基于Java注解实现websocket服务器端1.1需要的类1.1.1服务终端类1.1.2配置类2.1代码示例2.1.1 maven配置2.1.2 WsServerEndpoint类2.1.3 WebSocketConfig2.1.3 前端测试代码2.1.4测试结果2.基于spring
目录
  • 1.基于Java注解实现websocket服务器端
    • 1.1需要的类
      • 1.1.1服务终端类
      • 1.1.2配置类
    • 2.1代码示例
      • 2.1.1 maven配置
      • 2.1.2 WsServerEndpoint类
      • 2.1.3 WebSocketConfig
      • 2.1.3 前端测试代码
      • 2.1.4测试结果
  • 2.基于spring提供的类和接口刷新websocket服务器端
    • 2.1:HttpSessionHandShakeInter 握手拦截器
      • 2.2  MyWsHandler 主处理程序
        • sessionbean封装类
        •  主处理程序
      • 2.3 WebSocketConfigurer 注册拦截器和主处理程序以及监听路径
        • 2.4 前端测试
        • 总结 

          1.基于java注解实现websocket服务器端

          1.1需要的类

          1.1.1服务终端类

          用java注解来监听连接@ServerEndpoint、连接成功@OnOpen、连接失败@OnClose、收到消息等状态@OnMessage

          1.1.2配置类

          把spring中的ServerEndpointExporter对象注入进来

          2.1代码示例

          2.1.1 maven配置

          <?XML version="1.0" encoding="UTF-8"?>
          <project xmlns="http://maven.apache.org/POM/4.0.0"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
              <modelVersion>4.0.js0</modelVersion>
          
              <groupId>com.heima</groupId>
              <artifactId>ws-demo</artifactId>
              <version>1.0-SNAPSHOT</version>
          
              <properties>
                  <maven.compiler.source>8&www.devze.comlt;/maven.compiler.source>
                  <maven.compiler.target>8</maven.compiler.target>
                  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
              </properties>
              <dependencies>
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter</artifactId>
                     <version>2.7.3</version>
                  </dependency>
                  <dependency>
                      <groupId>org.projectlombok</groupId>
                      <artifactId>lombok</artifactId>
                      <version>1.16.22</version&g编程客栈t;
                  </dependency>
                  <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-websocket -->
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-websocket</artifactId>
                      <version>2.7.14</version>
                  </dependency>
          
          
          
              </dependencies>
          
          </project>

          2.1.2 WsServerEndpoint类

          package com.heima;
          
          import lombok.extern.slf4j.Slf4j;
          import org.springframework.scheduling.annotation.EnableScheduling;
          import org.springframework.scheduling.annotation.Scheduled;
          import org.springframework.stereotype.Component;
          
          import javax.websocket.OnClose;
          import javax.websocket.OnMessage;
          import javax.websocket.OnOpen;
          import javax.websocket.Session;
          import javax.websocket.server.ServerEndpoint;
          import java.io.IOException;
          import java.util.HashMap;
          import java.util.Map;
          import java.util.concurrent.ConcurrentHashMap;
          
          /***
           * 监听websocket地址  /myWs
           */
          @ServerEndpoint("/myWs")
          @Component
          @Slf4j
          @EnableScheduling
          public class WsServerEndpoint {
          
              static Map<String,Session> map = new ConcurrentHashMap<String,Session>();
          
              /***
               * 连接建立时执行的操作
               * @param session
               */
              @OnOpen
              public void onOpen(Session session)
              {
                  map.put(session.getId(),session);
                  log.info("websocket is open");
              }
          
              /***
               * 收到客户端消息执行的操作
               * @param text
               */
              @OnMessage
              public String OnMessage(String text)
              {
                  log.info("收到了一条信息"+text);
                  return "已收到你的信息" ;
              }
          
              /***
               * 连接关闭时执行的操作
               * @param session
               */
              @OnClose
              public void OnClose(Session session)
              {
                  map.remove(session.getId());
                  log.info("连接关闭时执行的操作");
              }
          
              /***
               * 向客户端发送信息
               */
              @Scheduled(fixedRate = 2000)
              public void sendMsg() throws IOException {
                  for (String key : map.keySet())
                  {
                      map.get(key).getBasicRemote().sendText("你好,你好");
                  }
              }
          }
          

          2.1.3 WebSocketConfig

          package com.heima;
          
          import org.springframework.context.annotation.Bean;
          import org.springframework.context.annotation.Configuration;
          import org.springframework.web.socket.server.standard.ServerEndpointExporter;
          
          @Configuration
          public class WebSocketConfig {
          
          
              @Bean
           public ServerEndpointExporter serverEndpointExporter()
           {
               return new ServerEndpointExporter();
           }
          
          
          
          }
          

          2.1.3 前端测试代码

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>wsClient</title>
          </head>
          <body>
          
          <script>
               // 创建websocket
              let ws = new WebSocket("ws://localhost:8080/myWs")
               //向服务器发送hello
              ws.onopen=function (){
                  ws.send("hello")
              }
              //监听数据ws://localhost:8080/myWs
              ws.onmessage=function (message){
                  console.log(message.data)
              }
          </script>
          </body>
          </html>

          2.1.4测试结果

          2.1.4.1 当打开浏览器时

          java注解实现websocket服务的两种方式

          2.1.4.2 当关闭浏览器时

          java注解实现websocket服务的两种方式

          2.1.4.3 当刷新浏览器的时候

          java注解实现websocket服务的两种方式

          java注解实现websocket服务的两种方式

          java注解实现websocket服务的两种方式

          2.基于spring提供的类和接口刷新websocket服务器端

          2.1:HttpSessionHandShakeInter 握手拦截器

          package com.spring;
          
          import lombok.extern.slf4j.Slf4j;
          import org.springframework.context.annotation.Configuration;
          import org.springframework.http.server.ServerHttpRequest;
          import org.springframework.http.server.ServerHttpResponse;
          import org.springframework.stereotype.Component;
          import org.springframework.web.socket.WebSocketHandler;
          import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
          
          import java.util.Map;
          
          /***
           * 握手拦截器
           */
          @Component
          @Slf4j
          public class MyWsInterceptor extends HttpSessionHandshakeInterceptor {
          
          
              @Override
              public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
                  log.info(request.getRemoteAddress().toString()+"开始握手");
                  return super.beforeHandshake(request, response, wsHandler, attributes);
              }
          
              @Override
              public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
                   log.info(request.getRemoteAddress().toString()+"完成握手");
                  super.afterHandshake(request, response, wsHandler, ex);
              }
          }
          

          2.2  MyWsHandler 主处理程序

          sessionbean封装类

          import lombok.AllArgsConstructor;
          import lombok.Data;
          import org.springframework.web.socket.WebSocketSession;
          
          @Data
          @AllArgsConstructor
          public class SessionBean {
              private WebSocketSession webSocketSession;
              private Integer clientId;
          }
          

           主处理程序

          package com.spring;
          
          import lombok.extern.slf4j.Slf4j;
          import org.springframework.boot.web.servlet.server.Session;
          import org.springframework.scheduling.annotation.EnableScheduling;
          import org.springframework.scheduling.annotation.Scheduled;
          import org.springframework.stereotype.Component;
          import org.springframework.web.socket.CloseStatus;
          import org.springframework.web.socket.TextMessage;
          import org.springframework.web.socket.WebSocketSession;
          import org.springframework.web.socket.handler.AbstractWebSocketHandler;
          
          import java.io.IOException;
          import java.util.Map;
          import java.util.concurrent.ConcurrentHashMap;
          import java.util.concurrent.atomic.AtomicInteger;
          
          /***
           * webSocket 主处理程序
           */
          @Component
          @Slf4j
          @EnableScheduling
          public class MyWsHandler extends AbstractWebSocketHandler {
              //map有并发线程问题  所以用ConcurrentHashMap
              private static Map<String, SessionBean> map ;
              //id有并发问题 所以用Integer的安全类型
              private static AtomicInteger clientIdMaker;
              static {
          
                  map = new ConcurrentHashMap<>();
                  clientIdMaker=new AtomicInteger(0);
              }
              //连接建立
              @Override
              public void afterConnectionEstablished(WebSocketSessphpion session) throws Exception {
                  super.afterConnectionEstablished(session);
                  //将session 进一步封装  id采用的是自增
                  SessionBean sessionBean = new SessionBean(session, clientIdMaker.getAndIncrement());
                  map.put(session.getId(),sessionBean);
                  log.info(map.get(session.getId()).getClientId()+"建立了连接");
              }
          
              //收到消息
              @Override
              protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
                  super.handleTextMessage(session, message);
                  log.info(map.get(session.getId()).getClientId()+":"+message.getPayload());
              }
          
              //传输异常
              @Override
              public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
                  super.handleTransportError(session, exception);
          
                  if (session.isOpen())
                  {
                      session.close();
                  }
                  map.remove(session.getId());
          
              }
           php   //连接关闭
              @Override
              public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
                  super.afterConnectionClosed(session, status);
                  log.info(map.get(session.getId()).getClientId()+"关闭连接");
              }
          
              /***
               * 向客户端发送信息
               */
              @Scheduled(fixedRate = 2000)
              public void sendMsg() throws IOException {
                  for (String key : map.keySet())
                  {
                      map.get(key).getWebSocketSession().sendMessage(new TextMessage("hello," +
                              "spring socket"));
                  }
              }
          }
          

          2.3 WebSocketConfigurer 注册拦截器和主处理程序以及监听路径

          package com.spring;
          
          import org.springframework.context.annotation.Configuration;
          import org.springframework.web.socket.config.annotation.EnableWebSocket;
          import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
          import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
          
          import javax.annotation.Resource;
          
          @Configuration
          @EnableWebSocket
          public class MyWsConfig implements WebSocketConfigurer {
              @Resource
              private MyWsHandler wsHandler;
              @Resource
              private MyWsInterceptor wsInterceptor;
              @Override
              public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
                  registry.addHandler(wsHandler,"/myWs1").addInterceptors(wsInterceptor).setAllowedOriginPatterns("*");
              }
          }
          

          2.4 前端测试

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>wsClient</title>
          </head>
          <body>
          
          <script>
               // 创建websocket
              let ws = new WebSocket("ws://localhost:8080/myWs1")
               //向服务器发送hello
              ws.onopen=function (){
                  ws.send("hello")
              }
              //监听数据ws://localhost:8080/myWs
              ws.onmessage=function (message){
                  console.log(message.data)
              }
          </script>
          </body>
          </html>

          总结 

          到此这篇关于java注解实现websocket服务两种方式的文章就介绍到这了,更多相关java websocket服务实现内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

          0

          精彩评论

          暂无评论...
          验证码 换一张
          取 消