51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 554|回复: 0
打印 上一主题 下一主题

分享springBoot集成webSocket并使用postMan进行测试

[复制链接]
  • TA的每日心情
    擦汗
    4 小时前
  • 签到天数: 1047 天

    连续签到: 5 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2023-4-10 13:38:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    简单描述
      简单来讲,webSocket是一种在http协议基础上的另一种新协议,叫ws协议。
      http协议是单工通信,客户端发起请求,服务端收到请求并处理,返回给客户端,然后客户端收到服务端的请求。
      ws协议是全双工通信,客户端发起请求后,相当于搭建了一个通道,在不断开的情况下,在这期间,服务端可以把请求发给客户端,客户端也可以在这期间处理别的事情,不必等待服务端的响应。
      webSockt实现
      此次webSocket实现不包含前端代码,将使用postMan来实现前端的功能。
      依赖
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-websocket</artifactId>
              </dependency>


      配置类
      @Configuration
      public class WebSocketConfig {
          @Bean
          public ServerEndpointExporter serverEndpointExporter(){
              return new ServerEndpointExporter();
          }
      }


      webSocketServer
      package com.czf.study.wevSocket;
      import lombok.extern.slf4j.Slf4j;
      import org.junit.platform.commons.util.StringUtils;
      import org.springframework.stereotype.Component;
      import javax.websocket.*;
      import javax.websocket.server.PathParam;
      import javax.websocket.server.ServerEndpoint;
      import java.io.IOException;
      import java.util.concurrent.ConcurrentHashMap;
      /**
       * @Author zfChen
       * @create 2022/11/14 15:11
       */
      @ServerEndpoint("/websocket/{userId}")
      @Component
      @Slf4j
      public class WebSocketServer {
          /**静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。*/
          private static int onlineCount = 0;
          /**concurrent包的线程安全集合,也可以map改成set,用来存放每个客户端对应的MyWebSocket对象。*/
          private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
          /**与某个客户端的连接会话,需要通过它来给客户端发送数据*/
          private Session session;
          /**接收userId*/
          private String userId="";
          /**
           * 连接建立成功调用的方法*/
          @OnOpen
          public void onOpen(Session session,@PathParam("userId") String userId) {
              this.session = session;
              this.userId=userId;
              if(!webSocketMap.containsKey(userId)){
                  //加入集合中
                  webSocketMap.put(userId,this);
                  //在线数加1
                  addOnlineCount();
              }
              log.info("用户连接:"+userId+",当前在线人数为:" + getOnlineCount());
              try {
                  sendMessage("连接成功");
              } catch (IOException e) {
                  log.error("用户:"+userId+",网络异常!!!!!!");
              }
          }
          /**
           * 连接关闭调用的方法
           */
          @OnClose
          public void onClose() {
              if(webSocketMap.containsKey(userId)){
                  webSocketMap.remove(userId);
                  //从集合中删除
                  subOnlineCount();
              }
              log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount());
          }
          /**
           * 收到客户端消息后调用的方法
           *
           * @param message 客户端发送过来的消息*/
          @OnMessage
          public void onMessage(String message, Session session) {
              log.info("【websocket消息】收到客户端发来的消息:{}", message);
          }
          /**
           *
           * @param session
           * @param error
           */
          @OnError
          public void onError(Session session, Throwable error) {
              log.error("用户错误:"+this.userId+",原因:"+error.getMessage());
              error.printStackTrace();
          }
          /**
           * 实现服务器主动推送
           */
          public void sendMessage(String message) throws IOException {
              this.session.getBasicRemote().sendText(message);
          }
          /**
           * 发送自定义消息
           * */
          public static void sendInfo(String message,@PathParam("userId") String userId) throws IOException {
              log.info("发送消息到:"+userId+",报文:"+message);
              if(StringUtils.isNotBlank(userId)&&webSocketMap.containsKey(userId)){
                  webSocketMap.get(userId).sendMessage(message);
              }else{
                  log.error("用户"+userId+",不在线!");
              }
          }
          public static synchronized int getOnlineCount() {
              return onlineCount;
          }
          public static synchronized void addOnlineCount() {
              WebSocketServer.onlineCount++;
          }
          public static synchronized void subOnlineCount() {
              WebSocketServer.onlineCount--;
          }
      }


      服务端发请求接口
      外面创建一个接口,模拟服务端发请求给客户端。
      @RestController
      public class DemoController {

          @RequestMapping("/push/{toUserId}")
          public ResponseEntity<String> pushToWeb(String message, @PathVariable String toUserId) throws IOException {
              WebSocketServer.sendInfo(message,toUserId);
              return ResponseEntity.ok("MSG SEND SUCCESS");
          }
      }


      测试
      使用postMan创建webSocket请求:

      输入webSocket的地址,1表示userId=1

      此时控制台输出
      2022-11-15 11:51:43.009  INFO 28972 --- [nio-8787-exec-5] com.czf.study.wevSocket.WebSocketServer  : 用户连接:1,当前在线人数为:1

      接下来,模拟服务端给客户端发送请求,建立一个http请求。

      控制台输出:
      2022-11-15 11:53:48.235  INFO 28972 --- [nio-8787-exec-4] com.czf.study.wevSocket.WebSocketServer  : 发送消息到:1,报文:hello

      客户端收到请求:

      双人聊天室
      webSocket经常被用作聊天室,两个客户端,通过一个服务端分发请求,进行沟通。
      在此案例中,通过/来区分,前一个是消息,后一个是发送的对象。
          /**
           * 收到客户端消息后调用的方法
           *
           * @param message 客户端发送过来的消息*/
          @OnMessage
          public void onMessage(String message, Session session) {
              log.info("【websocket消息】收到客户端发来的消息:{}", message);
              String[] split = message.split("/");
              try {
                  sendInfo(split[0],split[1]);
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }


      比如:

      2号用户收到1号发送的消息:

      同样的,2号也可以发送消息给1号。

    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-15 13:29 , Processed in 0.063708 second(s), 22 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表