小工具知识网

当前位置: 首页 > 行业知识 > @ServerEndpoint注解:2023最新分享,springboot中轻量级websocket

行业知识

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

2026-11-11 00:48:52 来源:互联网转载

@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    org.springframework.boot    spring-boot-starter-websocket

本文采用注解式编程,快速开发如下:

核心处理器 MyWebSocketServer.java

@ServerEndpoint(value = "/mysocket", encoders = AnswerEncoder.class)@Component@Slf4jpublic class MyWebSocketServer {    /**     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。     */    private static int onlineCount = 0;    /**     * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。     */    private static final CopyOnWriteArraySet WEB_SOCKET_SET = new CopyOnWriteArraySet();    /**     * 与某个客户端的连接会话,需要通过它来给客户端发送数据。     */    private Session session;    /**     * 连接建立成功调用的方法     */    @OnOpen    public void onOpen(Session session) {        this.session = session;        // 将当前连接加入到set中        WEB_SOCKET_SET.add(this);        // 连接数+1        addOnlineCount();        log.info("MyWebSocketServer 加入新的连接,当前连接数为" + getOnlineCount());    }    /**     * 连接关闭调用的方法     */    @OnClose    public void onClose() {        // 将当前连接从set中移除        WEB_SOCKET_SET.remove(this);        // 连接数-1        subOnlineCount();        log.info("MyWebSocketServer 有一连接关闭!当前连接数为" + getOnlineCount());    }    /**     * 收到客户端消息后调用的方法     *     * @param message 客户端发送过来的消息     */    @OnMessage    public void onMessage(String message, Session session) {        log.info("MyWebSocketServer 收到来自窗口" + session.getId() + "的信息:" + message);    }    /**     * @param session 连接session     * @param error   措施信息     */    @OnError    public void onError(Session session, Throwable error) {        log.error("MyWebSocketServer 连接发生错误");        error.printStackTrace();    }    /**     * 

@Description:給session连接推送消息

*

@param [message]

*

@return void

*

@throws

*/ private void sendMessage(Object message) throws IOException { try { this.session.getBasicRemote().sendObject(message); } catch (EncodeException e) { e.printStackTrace(); log.error("MyWebSocketServer 向客户端推送数据发生错误"); } } /** *

@Description:向所有连接群发消息

*

@param [message]

*

@return void

*

@throws

*/ public static void sendMessageToAll(Object message){ for (ScreenWebSocketServer item : WEB_SOCKET_SET) { try { item.sendMessage(message); } catch (IOException e) { log.error("MyWebSocketServer 向客户端推送数据发生错误"); } } } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { ScreenWebSocketServer.onlineCount++; } public static synchronized void subOnlineCount() { ScreenWebSocketServer.onlineCount--; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } ScreenWebSocketServer that = (ScreenWebSocketServer) o; return Objects.equals(session, that.session); } @Override public int hashCode() { return Objects.hash(session); }}

发送消息的编码器 AnswerEncoder .java

public class AnswerEncoder implements Encoder.Text {    @Override    public void destroy() {        // TODO Auto-generated method stub    }    @Override    public void init(EndpointConfig arg0) {        // TODO Auto-generated method stub    }    @Override    public String encode(Answer answer) throws EncodeException {        return JSONUtil.toJsonStr(answer);    }}

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

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.server.standard.ServerEndpointExporter;/** * File Name: WebsocketConfiguration * Description: Websocket 相关配置类 */@Configurationpublic class WebSocketConfiguration {    @Bean    public ServerEndpointExporter serverEndpointExporter() {        return new ServerEndpointExporter();    }}

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

@RequestMapping("socketPushTest")@RestControllerpublic class MyWebSocketPushTest {    @ApiOperation("给已连接的所有session进行群发")    @PostMapping("/sendMessageToAll")    public void push(@RequestBody Object 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.gradlecompile("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.xmlorg.springframework.bootspring-boot-starter-websocketorg.springframework.boottomcat-embed-websocket

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

上一篇:公司邮箱怎么更改模板?

下一篇:RocketMQ教程(一):RocketMQ的基本概念