springboot集成websocket发送消息通知给客户端

一、添加依赖包

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

二、直接上代码

1、添加配置

/**
 * @author fanxf
 * @since 2019/11/29 15:40
 */
@Configuration
public class WebSocketConfig {

    /**
     * socket配置类,往 spring 容器中注入ServerEndpointExporter实例
     *
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

2、编写服务类

/**
 * @author fanxf
 * @since 2019/11/29 15:42
 */
@Slf4j
@Component
@ServerEndpoint("/websocket/{name}")
public class WebSocketServer {

    /**
     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
     */
    private static AtomicInteger online = new AtomicInteger();
    /**
     * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
     */
    private static Map<String, Session> sessionPools = new HashMap<>();

    /**
     * 接收name
     */
    private String name = "";

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("name") String name) {
        sessionPools.put(name, session);
        addOnlineCount();
        log.info("有新窗口开始监听:" + name + ",当前在线人数为" + online);
        try {
            sendMessage(session, "success");
        } catch (IOException e) {
            log.error("websocket IO异常");
            e.printStackTrace();
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("name") String name) {
        sessionPools.remove(name);
        //在线数减1
        subOnlineCount();
        log.info(name+ "断开webSocket连接!当前在线人数为" + online);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message) {
        //群发消息
        for (Session session: sessionPools.values()) {
            try {
                sendMessage(session, message);
            } catch(IOException e){
                e.printStackTrace();
                continue;
            }
        }
    }

    /**
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }

    /**
     * 实现服务器主动推送
     */
    public void sendMessage(Session session, String message) throws IOException{
        if(session != null){
            session.getBasicRemote().sendText(message);
        }
    }

    /**
     * 给指定用户发送消息
     * @param name 用户名
     * @param message 消息
     * @throws IOException
     */
    public void sendInfo(String name, String message){
        log.info("收到来自窗口" + name + "的信息:" + message);
        Session session = sessionPools.get(name);
        try {
            sendMessage(session, message);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void addOnlineCount(){
        online.incrementAndGet();
    }

    public static void subOnlineCount() {
        online.decrementAndGet();
    }
}

3、测试类

/**
 * @author fanxf
 * @since 2019/11/29 15:48
 */
@RestController
@RequestMapping("/notify")
public class NotifyController {

    @Resource
    private WebSocketServer webSocketServer;

    /**
     * 推送数据接口
     *
     * @param message
     * @return
     */
    @RequestMapping("/socket/push")
    public BaseResult pushToWeb(String message) {
        webSocketServer.onMessage(message);
        return BaseResult.newSuccess(message);
    }

    /**
     * 推送给指定用户
     *
     * @param message
     * @return
     */
    @RequestMapping("/socket/push/{cid}")
    public BaseResult pushToWeb(@PathVariable String cid, String message) {
        webSocketServer.sendInfo(cid, message);
        return BaseResult.newSuccess(message);
    }
}

直接调用onMessage或sendInfo方法进去测试

4、推荐测试工具

地址:在线测试地址

如图:

显示连接已建立,正在等待数据说明连接成功

5、也可调用手写测试类进行模拟测试

到这完成,写的有点马虎,如有不正请指正!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值