0


@ServerEndpoint注解:2023最新分享,springboot中轻量级websocket

@ServerEndpoint:

主要是将目前的类定义成一个websocket服务器端, 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端

说明:本项目是springboot集成websocket
我项目用的是gradel引入依赖,下边附上maven的依赖,version与springboot保持一致即可

build.gradle
    compile group:'org.springframework.boot', name:'spring-boot-starter-websocket', version:'2.0.4.RELEASE'

pom.xml
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>

本文采用注解式编程,快速开发如下:
核心处理器 MyWebSocketServer.java

@ServerEndpoint(value ="/mysocket", encoders =AnswerEncoder.class)@Component@Slf4jpublicclassMyWebSocketServer{/**
     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
     */privatestaticint onlineCount =0;/**
     * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
     */privatestaticfinalCopyOnWriteArraySet<ScreenWebSocketServer> WEB_SOCKET_SET =newCopyOnWriteArraySet<ScreenWebSocketServer>();/**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据。
     */privateSession session;/**
     * 连接建立成功调用的方法
     */@OnOpenpublicvoidonOpen(Session session){this.session = session;// 将当前连接加入到set中
        WEB_SOCKET_SET.add(this);// 连接数+1addOnlineCount();
        log.info("MyWebSocketServer 加入新的连接,当前连接数为"+getOnlineCount());}/**
     * 连接关闭调用的方法
     */@OnClosepublicvoidonClose(){// 将当前连接从set中移除
        WEB_SOCKET_SET.remove(this);// 连接数-1subOnlineCount();
        log.info("MyWebSocketServer 有一连接关闭!当前连接数为"+getOnlineCount());}/**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */@OnMessagepublicvoidonMessage(String message,Session session){
        log.info("MyWebSocketServer 收到来自窗口"+ session.getId()+"的信息:"+ message);}/**
     * @param session 连接session
     * @param error   措施信息
     */@OnErrorpublicvoidonError(Session session,Throwable error){
        log.error("MyWebSocketServer 连接发生错误");
        error.printStackTrace();}/**
     * <p>@Description:給session连接推送消息</p>
     * <p>@param [message]</p>
     * <p>@return void</p>
     * <p>@throws </p>
     */privatevoidsendMessage(Object message)throwsIOException{try{this.session.getBasicRemote().sendObject(message);}catch(EncodeException e){
            e.printStackTrace();
            log.error("MyWebSocketServer 向客户端推送数据发生错误");}}/**
     * <p>@Description:向所有连接群发消息</p>
     * <p>@param [message]</p>
     * <p>@return void</p>
     * <p>@throws </p>
     */publicstaticvoidsendMessageToAll(Object message){for(ScreenWebSocketServer item : WEB_SOCKET_SET){try{
                item.sendMessage(message);}catch(IOException e){
                log.error("MyWebSocketServer 向客户端推送数据发生错误");}}}publicstaticsynchronizedintgetOnlineCount(){return onlineCount;}publicstaticsynchronizedvoidaddOnlineCount(){ScreenWebSocketServer.onlineCount++;}publicstaticsynchronizedvoidsubOnlineCount(){ScreenWebSocketServer.onlineCount--;}@Overridepublicbooleanequals(Object o){if(this== o){returntrue;}if(o ==null||getClass()!= o.getClass()){returnfalse;}ScreenWebSocketServer that =(ScreenWebSocketServer) o;returnObjects.equals(session, that.session);}@OverridepublicinthashCode(){returnObjects.hash(session);}}

发送消息的编码器 AnswerEncoder .java

publicclassAnswerEncoderimplementsEncoder.Text<Answer>{@Overridepublicvoiddestroy(){// TODO Auto-generated method stub}@Overridepublicvoidinit(EndpointConfig arg0){// TODO Auto-generated method stub}@OverridepublicStringencode(Answer answer)throwsEncodeException{returnJSONUtil.toJsonStr(answer);}}

最最最关键的一步:将ServerEndpointExporter 暴露给spring容器管理,它会帮我们注入标注了@ServerEndpoint注解的websocket处理器,否则上面配置的不生效。

importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.socket.server.standard.ServerEndpointExporter;/**
 * File Name: WebsocketConfiguration
 * Description: Websocket 相关配置类
 */@ConfigurationpublicclassWebSocketConfiguration{@BeanpublicServerEndpointExporterserverEndpointExporter(){returnnewServerEndpointExporter();}}

到此为止我们的websocket就配置好了,那么如何调用呢,如何从服务端主动推送message给客户端呢?请看如下实例代码:

@RequestMapping("socketPushTest")@RestControllerpublicclassMyWebSocketPushTest{@ApiOperation("给已连接的所有session进行群发")@PostMapping("/sendMessageToAll")publicvoidpush(@RequestBodyObject data){// 给前端群发数据变更消息Answer success =Answer.success("群发的消息-----啦啦啦");MyWebSocketServer.sendMessageToAll(success);}}

核心代码就是 MyWebSocketServer.sendMessageToAll(success);
好了,现在我们的springboot内嵌的websocket就配置好了,我们可以通过url的方式连接到这个服务

下面贴一下我测试的图
说明:我的springboot项目启动端口(也就是yml文件的server.port)是9090
ws://127.0.0.1:9090/mysocket
步骤1.模拟ws请求用户1
在这里插入图片描述
模拟ws请求用户2
在这里插入图片描述
查看idea控制台打印日志
在这里插入图片描述
此时ws连接都创建成功,调用ws推送接口,实现群发,然后查看用户1和用户2是否能收到
在这里插入图片描述
在这里插入图片描述

问题答疑:配置后,springboot项目启动报错
本博客使用范围是springboot+tomcat的,如果启动报错请在maven或者gradle依赖引入的时候排除
spring-boot-starter-tomcat,配置如下:

build.gradle
compile("org.springframework.boot:spring-boot-starter-web:2.1.4.RELEASE"){
        exclude module:"spring-boot-starter-tomcat"
        exclude group:'org.springframework.boot',module:'spring-boot-starter-logging'}
pom.xml
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>tomcat-embed-websocket</artifactId></exclusion></exclusions></dependency>

如果您的项目发布服务器是jetty,可以出门左转了,本博客不适用。本博客所写代码是将websocket用tomcat发布,与本身的springboot是一体的,不额外启用端口!!!!


本文转载自: https://blog.csdn.net/lzq2357639195/article/details/130746392
版权归原作者 吴巴格 所有, 如有侵权,请联系我们删除。

“@ServerEndpoint注解:2023最新分享,springboot中轻量级websocket”的评论:

还没有评论