java-websocket服务端、客户端及如何测试

这篇具有很好参考价值的文章主要介绍了java-websocket服务端、客户端及如何测试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

JAVA Websocket服务端

1. 导入依赖

<!-- 实际使用包 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!--websocket作为客户端-->
<dependency>
    <groupId>org.java-websocket</groupId>
    <artifactId>Java-WebSocket</artifactId>
    <version>1.3.5</version>
</dependency>

2. 服务端实现

(1)基础版
package com.xie.websocket;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
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.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @Description
 * @Date 2022-04-01 11:28
 * @Author xie
 */
@Slf4j
@Component
@ServerEndpoint(value = "/ws/data/{param}")
public class WebSocketServer {

    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();

    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    // 业务service
    private TestService testService = (TestService) ApplicationContextHandle.getBean(TestService.class);

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("param") String param) {
        this.session = session;   //加入set中
        webSocketSet.add(this);
        try {
            while (true) {
                // 处理数据并发送
                List<Map<String, Object>> result = testService.findDataByParam(param);
                sendMessage(JSONObject.toJSONString(result));
                Thread.sleep(3000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  //从set中删除
    }

    /**
     * 收到客户端消息后调用的方法
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到客户端的消息:{}", message);
    }

    /**
     * 发生错误时调用
     */
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    /**
     * 发送消息
     */
    public void sendMessage(String message) throws IOException {
        this.session.getAsyncRemote().sendText(message);
    }


    /**
     * 群发自定义消息
     */
    public static void sendInfo(String message) throws IOException {
        for (WebSocketServer item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
                continue;
            }
        }
    }
}


(2)优化版
package com.cdzs.websocket;

import cn.hutool.core.util.RandomUtil;
import com.cdzs.common.core.constant.SecurityConstants;
import com.cdzs.common.core.exception.ServiceException;
import com.cdzs.common.redis.service.CacheService;
import com.cdzs.system.api.RemoteDeviceGrpcService;
import com.cdzs.system.api.domain.device.CdzsDevicesEntity;
import com.cdzs.system.api.domain.grpc.dto.RegisterFaceByAppointDeviceDTO;
import com.cdzs.websocket.util.ByteArraySplitter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * type: register/verify(注册/人证核验)
 */

@Component
@ServerEndpoint(value = "/person/{type}/{token}")
@Slf4j
public class CdzsPersonWebSocket {

    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    private static RemoteDeviceGrpcService remoteDeviceGrpcService;
	//只能通过set方法/getBean()来注入
    @Autowired
    public void setRemoteDeviceGrpcService(RemoteDeviceGrpcService remoteDeviceGrpcService) {
        CdzsPersonWebSocket.remoteDeviceGrpcService = remoteDeviceGrpcService;
    }

    private static CacheService cacheService;

    @Autowired
    public void setCacheService(CacheService cacheService) {
        CdzsPersonWebSocket.cacheService = cacheService;
    }

    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;

    private static ConcurrentHashMap<String, CdzsPersonWebSocket> socketServersMap = new ConcurrentHashMap<>();

    private String key = "";

    private final static String REGISTER = "register";
    private final static String VERIFY = "verify";

    /**
     * 建立连接
     *
     * @param session
     * @param type    type为register/verify
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("type") String type, @PathParam("token") String token) {
        this.session = session;
        //key = type + ":" + token + ":" + sessionId
        key = type + ":" + token + ":" + session.getId();
        log.info("onOpen->>key:{}", key);
        //判断当前是否已经连接过
        boolean flag = socketServersMap.containsKey(key);
        if (flag) {
            socketServersMap.remove(key);
            socketServersMap.put(key, this);
        } else {
            socketServersMap.put(key, this);
            addOnlineCount(); //在线数加1
        }
        //获取到token,查询该token下的设备
        CdzsDevicesEntity device = cacheService.getCacheObject("choose_device:" + token);
        if (device == null){
            throw new ServiceException("您登录时未选择注册平板");
        }
        String deviceIp = device.getDeviceIp();
        String deviceSn = device.getDeviceSn();
        log.info("token->>deviceIp:{}", deviceIp);
        if (REGISTER.equals(type)) {
            //注册
            RegisterFaceByAppointDeviceDTO registerFaceByAppointDeviceDTO = new RegisterFaceByAppointDeviceDTO();
            registerFaceByAppointDeviceDTO.setDeviceIp(deviceIp);
            registerFaceByAppointDeviceDTO.setSessionId(token);
            registerFaceByAppointDeviceDTO.setIsVerify(false);
            registerFaceByAppointDeviceDTO.setParams(0);
            registerFaceByAppointDeviceDTO.setPersonId("1000" + RandomUtil.randomNumbers(4));
            registerFaceByAppointDeviceDTO.setDeviceSn(deviceSn);
            remoteDeviceGrpcService.regFeaDataByAppointDevice(registerFaceByAppointDeviceDTO, SecurityConstants.INNER);
            log.info("register call success");
        } else if (VERIFY.equals(type)) {
            //人证核验
            remoteDeviceGrpcService.verifyPersonCard(deviceIp, token, SecurityConstants.INNER);
            log.info("verify call success");
        }
        log.info("online number:{}", getOnlineCount());
    }

    /**
     * 主要功能:收到客户端消息后调用的方法
     * 方法名:onMessage
     *
     * @param message 客户端发送过来的消息
     * @param session 返回类型:void
     *                时间:2019年8月14日 上午9:44:42
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("来自客户端的消息->>message:{};sessionId:{}", message, session.getId());
    }

    /**
     * 主要功能:关闭连接
     * 方法名:onClose
     * 返回类型:void
     * 时间:2019年8月14日 上午9:44:58
     */
    @OnClose
    public void onClose() {
        log.info("onClose : {}" + key);
        if (socketServersMap.containsKey(key)) {
            socketServersMap.remove(key);
            subOnlineCount();           //在线数减1
        }
        log.info("有一连接关闭!当前在线连接数为: {}", getOnlineCount());
    }

    /**
     * 发生错误时调用
     * 主要功能:
     * 方法名:onError
     *
     * @param error 返回类型:void
     *              时间:2019年8月14日 上午9:44:07
     */
    @OnError
    public void onError(Throwable error) {
        socketServersMap.remove(key);
        subOnlineCount();
        log.error("webSocket连接发生错误->>errorMessage:{}", error.getMessage());
    }


    /**
     * 人脸注册webSocket
     *
     * @param message   要发送给前端的数据
     * @param sessionId token
     */
    public synchronized void reproductiveSendToRegister(String message, String sessionId) {
        synchronized (this.getClass()) {
            for (Map.Entry<String, CdzsPersonWebSocket> stringMyWebSocketEntry : socketServersMap.entrySet()) {
                try {
                    String key = stringMyWebSocketEntry.getKey();
                    CdzsPersonWebSocket value = stringMyWebSocketEntry.getValue();
                    if (key.contains(sessionId) && key.contains(REGISTER)) {
                        log.info("reproductiveSendToRegister:推送的消息为:" + key);
                        List<byte[]> result = ByteArraySplitter.split(message, 64 * 1024);
                        for (byte[] bytes : result) {
                            String s = new String(bytes);
                            value.session.getBasicRemote().sendText(s);
                        }
                        // 推送结束符
                        value.session.getBasicRemote().sendText("########");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 人脸注册webSocket
     *
     * @param message   要发送给前端的数据
     * @param sessionId token
     */
    public synchronized void reproductiveSendToVerify(String message, String sessionId) {
        synchronized (this.getClass()) {
            for (Map.Entry<String, CdzsPersonWebSocket> stringMyWebSocketEntry : socketServersMap.entrySet()) {
                try {
                    String key = stringMyWebSocketEntry.getKey();
                    CdzsPersonWebSocket value = stringMyWebSocketEntry.getValue();
                    if (key.contains(sessionId) && key.contains(VERIFY)) {
                        log.info("reproductiveSendToVerify:推送的消息为:" + key);
                        List<byte[]> result = ByteArraySplitter.split(message, 64 * 1024);
                        for (byte[] bytes : result) {
                            String s = new String(bytes);
                            value.session.getBasicRemote().sendText(s);
                        }
                        // 推送结束符
                        value.session.getBasicRemote().sendText("########");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 获取在线数
     *
     * @return
     */
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    /**
     * 在线数+1
     */
    public static synchronized void addOnlineCount() {
        CdzsPersonWebSocket.onlineCount++;
    }

    /**
     * 在线数-1
     */
    public static synchronized void subOnlineCount() {
        CdzsPersonWebSocket.onlineCount--;
    }
}

  • 对String分片转换为List<byte[]>
package com.cdzs.websocket.util;

import cn.hutool.core.util.ArrayUtil;
import com.cdzs.common.core.utils.StringUtils;
import com.google.common.collect.Lists;

import java.util.List;

public class ByteArraySplitter {
    /**
     * 对String分片转换为List<byte[]>
     * @param source 字符串
     * @param size 分片的长度 单位字节
     * @return
     */
    public static List<byte[]> split(String source, int size) {
        // 存放最终结果
        List<byte[]> result = Lists.newArrayList();

        if (StringUtils.isEmpty(source)) {
            return null;
        }

        byte[] sourceBytes = source.getBytes();
        if (size > sourceBytes.length) {
            result.add(sourceBytes);
            return result;
        }
        // 开始进行split
        int startIndex = 0;
        int endIndex = sourceBytes.length - 1;
        boolean isRunning = true;
        while (isRunning) {
            if ((endIndex + 1) - startIndex > size) {
                result.add(ArrayUtil.sub(sourceBytes, startIndex, startIndex + size));
                startIndex += size;
            } else {
                result.add(ArrayUtil.sub(sourceBytes, startIndex, endIndex + 1));
                isRunning = false;
            }
        }
        return result;
    }
}

3. 客户端实现

package cn.weblab.plugin.socket;

import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.project.Project;
import cn.weblab.plugin.util.ConsoleUtil;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.WebSocket;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.framing.Framedata;
import org.java_websocket.handshake.ServerHandshake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

public class MyLogWebSocketClient extends WebSocketClient {
    Logger log=LoggerFactory.getLogger(MyLogWebSocketClient.class);
    private Project project;
    private static List<MyLogWebSocketClient> list = new ArrayList<>();

    /**
     * construct a instance
     *
     * @param serverUri need to be connected
     */
    public MyLogWebSocketClient(String serverUri, Project project) throws URISyntaxException {
        super(new URI(serverUri));
        this.project = project;
        this.setConnectionLostTimeout(0);
        if (list.isEmpty()) {
            return;
        }
        for (MyLogWebSocketClient client : list) {
            client.close();
        }
        list.clear();
        list.add(this);
    }

    @Override
    public void onOpen(ServerHandshake serverHandshake) {
        log.info("在线日志socket连接成功");
        ConsoleView logConsole = ConsoleUtil.getLogConsole(project);
        logConsole.print("连接建立成功\n", ConsoleViewContentType.ERROR_OUTPUT);
    }

    @Override
    public void onMessage(String s) {
        s = s.substring(8);
        // if (s.equals("---pong---")) {
        //     return;
        // }
        ConsoleView logConsole = ConsoleUtil.getLogConsole(project);
        logConsole.print(s, ConsoleViewContentType.NORMAL_OUTPUT);
    }

    @Override
    public void onClose(int i, String s, boolean b) {
        log.info("在线日志socket断开");
        ConsoleView logConsole = ConsoleUtil.getLogConsole(project);
        logConsole.print("在线日志socket断开,请重新连接\n", ConsoleViewContentType.ERROR_OUTPUT);
    }

    @Override
    public void onError(Exception e) {
        e.printStackTrace();
    }

    // @Override
    // public void onWebsocketPong(WebSocket conn, Framedata f) {
    //     try {
    //         Thread.sleep(1000 * 10);
    //     } catch (InterruptedException e) {
    //         e.printStackTrace();
    //     }
    //     System.out.println("pong");
    //     this.onWebsocketPing(conn, f);
    //     super.onWebsocketPong(conn, f);
    // }

    @Override
    public void onWebsocketPing(WebSocket conn, Framedata f) {
        try {
            Thread.sleep(1000 * 5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
       send("---pong---");
    }

    @Deprecated
    public static void destroy() {
        if (list.isEmpty())
            return;
        for (MyLogWebSocketClient client : list) {
            client.close();
        }
        list.clear();

    }

    public static void main(String[] args) throws URISyntaxException, InterruptedException {
        // MyWebSocketClient client = new MyWebSocketClient("ws://localhost:8080/websocket/A");
        // boolean b = client.connectBlocking();
        // System.out.println(b);
        // client.send("hello");
        // client.send("hello");
        // client.send("hello");
        // client.send("hello");
        // client.close();
    }
}

4. websocket服务端测试方法

(1)自己编写一个客户端

​ 使用上面的java客户端就可以直接调用测试。

(2)使用postman测试

​ postman版本需要在v8.0以上才有websocket的接口测试

java-websocket服务端、客户端及如何测试

java-websocket服务端、客户端及如何测试文章来源地址https://www.toymoban.com/news/detail-503780.html

到了这里,关于java-websocket服务端、客户端及如何测试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java】SpringBoot快速整合WebSocket实现客户端服务端相互推送信息

    目录 什么是webSocket? webSocket可以用来做什么? WebSocket操作类 一:测试客户端向服务端推送消息 1.启动SpringBoot项目 2.打开网站 3.进行测试消息推送 4.后端进行查看测试结果 二:测试服务端向客户端推送消息 1.接口代码 2.使用postman进行调用 3.查看测试结果         WebSocke

    2024年01月20日
    浏览(37)
  • Java:SpringBoot整合WebSocket实现服务端向客户端推送消息

    思路: 后端通过websocket向前端推送消息,前端统一使用http协议接口向后端发送数据 本文仅放一部分重要的代码,完整代码可参看github仓库 websocket 前端测试 :http://www.easyswoole.com/wstool.html 依赖 项目目录 完整依赖 配置 WebSocketServer.java 前端页面 websocket.html 前端逻辑 index.js 参

    2024年02月04日
    浏览(36)
  • 如何将本地websocket服务端从本地暴露至公网实现客户端远程连接

    1. Java 服务端demo环境 jdk1.8 框架:springboot+maven 工具IDEA 2. 在pom文件引入第三包封装的netty框架maven坐标 注意:pom文件里需注释掉springbootweb启动器,web启动器默认是tomcat服务启动,会和netty服务冲突 3. 创建服务端,以接口模式调用,方便外部调用 4. 启动服务,出现以下信息表示启动成功

    2024年04月10日
    浏览(35)
  • Java WebSocket客户端

    1.依赖 2.代码 1.依赖 2.代码 2.1 自定义 websocket handler 2.2 将websocket handler加入容器 2.3 定时器监控

    2024年02月16日
    浏览(29)
  • websocket客户端实现(java)

    其中,headers 参数是一个键值对,表示需要设置的请求头。在构造函数中,我们首先创建了一个 ClientEndpointConfig.Configurator 对象,重写了其中的 beforeRequest() 方法,用于在请求之前设置请求头。然后,我们使用 ClientEndpointConfig.Builder.create() 方法创建一个 ClientEndpointConfig 对象,并

    2024年02月15日
    浏览(34)
  • Java实现websocket客户端

    常规情况下,大多数时候Java后台作为websocket服务端,实现方式也比较简单,网上很多案例代码。但是很多时候项目中服务与服务之间也需要使用websocket通信,此时项目就需要实现客户端功能。 步骤一:导入依赖: 步骤二:实现WebSocketClient抽象类: 该类中和websocket服务端接口

    2024年02月16日
    浏览(33)
  • Java Websocket发送文件给Vue客户端接收并上传,实现检测U盘插入并将指定文件上传到服务器功能

    应用环境: B/S架构 需求描述: 1、判断U盘接入 2、扫描U盘指定文件,将满足条件的文件发送给服务器 解决思路: 1、因为bs架构,无法获取本机资源,计划在U盘所在服务器部署websocket服务 2、websocket服务扫描u盘,拿到指定文件,使用session.getBasicRemote().sendBinary(data)分批发送二

    2024年01月15日
    浏览(46)
  • SpringBoot+WebSocket实现服务端、客户端

    小编最近一直在使用springboot框架开发项目,毕竟现在很多公司都在采用此框架,之后小编也会陆续写关于springboot开发常用功能的文章。 什么场景下会要使用到websocket的呢? websocket主要功能就是实现网络通讯,比如说最经典的客服聊天窗口、您有新的消息通知,或者是项目与

    2024年02月13日
    浏览(35)
  • python用websockets创建服务端websocket创建客户端

    服务端 客户端

    2024年02月22日
    浏览(37)
  • Java WebSocket 获取客户端 IP 地址

    在开发 Web 应用程序时,我们通常需要获取客户端的 IP 地址用于日志记录、身份验证、限制访问等操作。当使用 WebSocket 协议时,我们可以使用 Java WebSocket API 来获取客户端的 IP 地址。 本文将介绍如何使用 Java WebSocket API 获取客户端 IP 地址,以及如何在常见的 WebSocket 框架中

    2024年02月05日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包