SpringBoot项目使用websocket--随笔

导入maven依赖
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
在WebConfig中添加以下配置【若是使用内置tomcat】
 @Bean
    public ServerEndpointExporter createServerEndExporter() {
        return new ServerEndpointExporter();
    }
具体实现类

import com.alibaba.fastjson.JSONObject;
import com.framework.common.utils.DateUtils;
import com.framework.common.utils.RedisUtils;
import com.framework.common.utils.SpringContextUtils;
import com.framework.common.utils.StringUtil;
import com.framework.common.websocket.EpidemicData;
import com.framework.common.websocket.EpidemicWebSocketClient;
import com.framework.common.websocket.WebSocketMsg;
import com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.*;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * 可在路径上添加参数,并在建立连接[onOpen]时读取
 *  路径参数/{entId}
 */
@ServerEndpoint("/websocket/epidemic")
@Component
public class EpidemicController {

    public static final Logger logger = LoggerFactory.getLogger(EpidemicController.class);

    @Autowired
    private RedisUtils redisUtils;

    private static CopyOnWriteArraySet<EpidemicController> user = new CopyOnWriteArraySet<EpidemicController>();
    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;
    // 登录企业ID
    private Integer entId;

    /**
     * 连接建立成功调用的方法
     *
     * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
     *   entId 路径上携带的参数,已弃用
     * , @PathParam("entId") Integer entId
     */
    @OnOpen
    public void onOpen(Session session) {
//        this.entId = entId;
        this.session = session;
        user.add(this);
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("pageCode") String pageCode,Session session) {
        user.remove(this);
    }

    /**
     * 向符合条件的客户端发送信息【业务逻辑处理】
     * @param jsonMsg
     */
    public static void sendAllClients(String jsonMsg, int entId){
        if(StringUtil.isBlank(jsonMsg)){
            return;
        }
        try{
            for(EpidemicController webSocket : user) {
                if (webSocket.getEntId() == entId) {
                    webSocket.session.getBasicRemote().sendText(jsonMsg);
                }
            }
        }catch (Exception e){
            logger.error("向"+entId+"企业发送通行信息异常:"+e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        try {
            if(StringUtil.isBlank(message)){
                return;
            }
            WebSocketMsg webSocketMsg = new Gson().fromJson(message, WebSocketMsg.class);
            String jsonMsg = webSocketMsg.getJsonMsg();
            //获取客户端参数
            this.entId = webSocketMsg.getEntId();

			//遍历存储的webSocket对象
            for(EpidemicController webSocket : user){
            	//获取当前webSocket对象
                if(webSocket.getSession().getId() == this.session.getId()){
                	//业务逻辑处理,并将处理后的结果转化为 json字符串并发送给响应的客户端
                    webSocket.session.getBasicRemote().sendText(jsonMsg);
                }
            }
        } catch (IOException e) {
            logger.error("后台异常", e);
            e.printStackTrace();
        }
    }

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

    public Session getSession() {
        return session;
    }

    public Integer getEntId() {
        return entId;
    }

}

相应的js
 websocketService() {
     var that = this;
     var websocket = null;
     //判断当前浏览器是否支持WebSocket
     if ("WebSocket" in window) {
         websocket = new WebSocket(
             "ws://127.0.0.1:80/websocket/epidemic"
         );
     } else {
         alert("当前浏览器不支持websocket");
     }

     //发送消息
     function send() {
     	//websocket所发送的消息内容
         var msg = '{"entId": "'+ that.entId + '","jsonMsg": ""}';
         try {
             websocket.send(msg);
         } catch (err) {
             var tryTime = 0;
             // 重试1次,间隔3秒
             if (tryTime < 1) {
                 var t1 = setTimeout(function() {
                     tryTime++;
                     websocket.send(msg);
                 }, 3 * 1000);
             } else {
                 console.error("重连失败.");
             }
         }
     }
     //接收到消息的回调方法
     websocket.onmessage = function(event) {
     	//业务逻辑处理
         //var result = JSON.parse(event);
         //var result = JSON.parse(result.jsonMsg.replace(/'/g, '"'));
     };

     //连接成功建立的回调方法
     websocket.onopen = function() {
         console.log("websocket连接成功----")
     };
     //连接关闭的回调方法
     websocket.onclose = function() {
         /*var tryTime = 0;
                     // 重试10次,每次之间间隔3秒
                     if (tryTime < 10) {
                         setTimeout(function () {
                             webSocket2 = null;
                             tryTime++;
                             that.websocket();
                         }, 3*1000);
                     } else {
                         console.error("重连失败.");
                     }*/
     };
     //连接发生错误的回调方法
     websocket.onerror = function() {
        console.log("websocket连接错误...");
     };
     //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
     window.onbeforeunload = function() {
         //					closeWebSocket();
     };
     //关闭WebSocket连接
     function closeWebSocket() {
         //websocket.close();
     }

     $(function() {
         //发送一条消息,从服务器获取消息
         send();
     });
 },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值