• spring boot集成Websocket


    websocket实现后台像前端主动推送消息的模式,可以减去前端的请求获取数据的模式。而后台主动推送消息一般都是要求消息回馈比较及时,同时减少前端ajax轮询请求,减少资源开销。

    spring boot已经集成了websocket,tomcat亦是如此。所以WebSocketConfig配置类就不需要了,不需要开启什么支持,本来就支持。

    一、导入依赖

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

    二、websocket多线程,线上真实环境已经测试过。

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    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.HashMap;
    import java.util.Map;


    /**
    * @Auther: lanhaifeng
    * @Date: 2018/11/6 0006 17:59
    * @Description: websocket服务端
    * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
    * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
    * @ServerEndpoint 可以把当前类变成websocket服务类
    */
    @ServerEndpoint("/websocket/{sid}")
    @Component
    public class WebSocketServer {

    private static Logger logger = LoggerFactory.getLogger(WebSocketServer.class);

    //存储连接用户的session
    private static CopyOnWriteArraySet<String, Session> connections = new CopyOnWriteArraySet<>();


    /**
    * 打开连接
    * @param session
    * @param sid
    */
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid) {
    connections.put(sid, session);
    }

    /**
    * 接收消息
    * @param text
    */
    @OnMessage
    public void onMessage(String text) {
    logger.info("收到来新的信息:"+text);
    }

    /**
    * 异常处理
    * @param throwable
    */
    @OnError
    public void onError(Throwable throwable) {
    throwable.printStackTrace();
    }

    /**
    * 关闭连接
    * @param sid
    */
    @OnClose
    public void onClosing(@PathParam("sid") String sid) throws IOException {
    connections.remove(sid);
    }


    /**
    * 根据IP发送消息
    * @param sid
    * @param text
    */
    public static void sendInfo(String text,@PathParam("sid") String sid) {
    try {
    Session session = connections.get(sid);
    if (session != null && session.isOpen()) {
    session.getAsyncRemote().sendText(text);
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    /**
    * 遍历群发消息
    * @param text
    */
    public static void send(String text) {
    for (Map.Entry<String, Session> entry : connections.entrySet()) {
    sendInfo(text,entry.getKey());
    }
    }


    }

    在业务中的调用就不介绍了,直接  WebSocketServer.sendInfo(text,sid)

    特别注意sendInfo(String message,@PathParam("sid") String sid)两个参数在实际应用中的先后顺序,否则将发送失败。因为找不到该sid的连接。

    同时无论是反向代理还是socket本身,60S没有消息会自动断开连接,于是乎

    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.annotation.Scheduled;
    
    /**
     * @Auther: lanhaifeng
     * @Date: 2019/5/16 0016 14:29
     * @Description:webSocket定时发送消息类
     * @statement: 以<60s的频率发送给websocket连接的对象,以防止反向代理的60s超时限制
     */
    @Configuration      //1.主要用于标记配置类,兼备Component的效果。
    @EnableScheduling   // 2.开启定时任务
    public class SaticScheduleTask {
    
    
        //3.添加定时任务,55秒是考虑5秒的延迟,从而保证60s的心跳
        //@Scheduled(cron = "0/55 * * * * ?")
        //或直接指定时间间隔,例如:55秒
        @Scheduled(fixedRate=55*1000)
        private void configureTasks() throws Exception{
            WebSocketServer.send("呼叫动拐,呼叫动拐!");
        }
    }
  • 相关阅读:
    CF741C.Arpa’s overnight party and Mehrdad’s silent entering [构造 二分图染色]
    CF719E. Sasha and Array [线段树维护矩阵]
    洛谷7月月赛
    CF666B. World Tour
    BZOJ4668: 冷战 [并查集 按秩合并]
    水题练习 2
    CF715B. Complete The Graph
    关于最短路、负环、差分约束系统的一点笔记
    关于最小生成树,拓扑排序、强连通分量、割点、2-SAT的一点笔记
    hdu1814 Peaceful Commission
  • 原文地址:https://www.cnblogs.com/zeussbook/p/10899630.html
Copyright © 2020-2023  润新知