千家信息网

springboot如何使用websocket技术主动给前端发送消息

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章将为大家详细讲解有关springboot如何使用websocket技术主动给前端发送消息,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。使用websocket
千家信息网最后更新 2026年11月04日springboot如何使用websocket技术主动给前端发送消息

这篇文章将为大家详细讲解有关springboot如何使用websocket技术主动给前端发送消息,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

使用websocket技术主动给前端发送消息

springBoot2.0对WebSocket的支持简直太棒了,直接就有包可以引入

             org.springframework.boot             spring-boot-starter-websocket         

WebSocketConfig

启用WebSocket的支持也是很简单

package com.spark.common.config; import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.server.standard.ServerEndpointExporter; /** * @Author Lxq * @Date 2021-06-12 17:11 * @Version 1.0 * 开启websocket支持 */@Configurationpublic class WebSocketConfig {     @Bean    public ServerEndpointExporter serverEndpointExporter() {        return new ServerEndpointExporter();    }}

WebSocketServer

这就是重点了,核心都在这里。

因为WebSocket是类似客户端服务端的形式(采用ws协议),那么这里的WebSocketServer其实就相当于一个ws协议的Controller

直接@ServerEndpoint("/socketServer/{userId}") 、@Component启用即可,然后在里面实现@OnOpen开启连接,@onClose关闭连接,@onMessage接收消息等方法。

新建一个ConcurrentHashMap webSocketMap 用于接收当前userId的WebSocket,方便IM之间对userId进行推送消息。单机版实现到这里就可以。

package com.spark.common.utils.websocket; import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.spark.common.utils.StringUtils;import lombok.extern.slf4j.Slf4j;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 Lxq * @Date 2021-06-12 17:13 * @Version 1.0 */@ServerEndpoint("/socketServer/{userId}")@Component@Slf4jpublic class WebSocketServer {     /**     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。     */    private static int onlineCount = 0;    /**     * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。     */    private static ConcurrentHashMap 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.remove(userId);            webSocketMap.put(userId, this);            //加入set中        } else {            webSocketMap.put(userId, this);            //加入set中            addOnlineCount();            //在线数加1        }         log.info("用户连接:" + userId + ",当前在线人数为:" + getOnlineCount());         try {            sendMessage("连接成功");        } catch (IOException e) {            log.error("用户:" + userId + ",网络异常!");        }    }      /**     * 连接关闭调用的方法     */    @OnClose    public void onClose() {        if (webSocketMap.containsKey(userId)) {            webSocketMap.remove(userId);            //从set中删除            subOnlineCount();        }        log.info("用户退出:" + userId + ",当前在线人数为:" + getOnlineCount());    }      /**     * 收到客户端消息后调用的方法     *     * @param message 客户端发送过来的消息     */    @OnMessage    public void onMessage(String message, Session session) {        log.info("用户消息:" + userId + ",报文:" + message);        //可以群发消息        //消息保存到数据库、redis        if (StringUtils.isNotBlank(message)) {            try {                //解析发送的报文                JSONObject jsonObject = JSON.parseObject(message);                //追加发送人(防止串改)                jsonObject.put("fromUserId", this.userId);                String toUserId = jsonObject.getString("toUserId");                //传送给对应toUserId用户的websocket                if (StringUtils.isNotBlank(toUserId) && webSocketMap.containsKey(toUserId)) {                    webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());                } else {                    log.error("请求的userId:" + toUserId + "不在该服务器上");                    //否则不在这个服务器上,发送到mysql或者redis                }            } catch (Exception e) {                e.printStackTrace();            }        }    }     /**     * @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 + ",不在线!");        }    }     /**     * 获取当前在线人数     *     * @return     */    public static synchronized int getOnlineCount() {        return onlineCount;    }     /**     * 添加人数     */    public static synchronized void addOnlineCount() {        WebSocketServer.onlineCount++;    }     /**     * 减少人数     */    public static synchronized void subOnlineCount() {        WebSocketServer.onlineCount--;    } }

websocket基础入门-前端发送消息

项目结构如下图

TestSocket.java

package com.charles.socket; import javax.websocket.OnMessage;import javax.websocket.OnOpen;import javax.websocket.Session;import javax.websocket.server.ServerEndpoint; @ServerEndpoint(value = "/helloSocket")public class TestSocket {     /***     * 当建立链接时,调用的方法.     * @param session     */    @OnOpen    public void open(Session session) {                System.out.println("开始建立了链接...");        System.out.println("当前session的id是:" + session.getId());    }        /***     * 处理消息的方法.     * @param session     */    @OnMessage    public void message(Session session, String data) {                System.out.println("开始处理消息...");        System.out.println("当前session的id是:" + session.getId());        System.out.println("从前端页面传过来的数据是:" + data);    }}

index.jsp 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>Charles-WebSocket             

注意:

和后台交互的时候,一定要先点击:开始建立连接。你懂的...没有建立连接的话,是不能发送消息的。

先点击,开始建立连接,然后在文本框中输入内容:我是Charles,点击消息发送,在看后台日志。

关于"springboot如何使用websocket技术主动给前端发送消息"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

消息 用户 客户 方法 在线 服务 前端 人数 客户端 服务器 主动 后台 支持 技术 报文 数据 篇文章 链接 安全 成功 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 新华互联网科技 科技互联网公司装修 科技互联网技术 港股互联网科技股 互联网未来科技 互联网科技股票 碳银互联网科技有限公司 互联网科技小额贷款 猫创互联网科技 互联网科技产业特征 四川慕妮娅互联网科技有限公司 广州有谷有贝互联网科技有限公司 广州梦谷互联网科技有限公司领导 全球科技与互联网公司市值变化 互联网领先科技活动 绵阳真晨互联网科技有限公司 杭州融税互联网科技有限公司 互联网对科技影响 平安好医生打造互联网科技医疗 中国主要互联网科技公司 互联网科技工作委员会副主任毛军 北京互联网科技有限公司 成都互联网科技公司 互联网科技大会案例 北京三清互联网科技 贵州叶脉互联网科技有限公司所属行业 佛山市拉法互联网科技有限公司 九思连强互联网电子科技有限公司 万物互联网智能科技 盐城市攀科互联网科技有限公司
0