All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.benma666.sjsj.web.XtxxWebSocket Maven / Gradle / Ivy

package cn.benma666.sjsj.web;

import cn.benma666.constants.UtilConst;
import cn.benma666.constants.UtilConstInstance;
import cn.benma666.dict.Cllx;
import cn.benma666.dict.Ljpd;
import cn.benma666.domain.SysPtglXtxx;
import cn.benma666.domain.SysQxYhxx;
import cn.benma666.exception.MyException;
import cn.benma666.iframe.BasicObject;
import cn.benma666.iframe.MyParams;
import cn.benma666.iframe.Result;
import cn.benma666.myutils.StringUtil;
import cn.benma666.vo.WebSocketKhdxxVo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;

/**
 * 系统消息
 */
@Component
@ServerEndpoint("/xtxx/{token}")
public class XtxxWebSocket extends BasicObject implements UtilConstInstance {
    public XtxxWebSocket(){
        log.info("websocket启动");
    }

    private static final Map xtxxMap = Collections.synchronizedMap(new HashMap<>());
    /**
     * 监听目的地集合
     */
    private final Set jtmddSet = Collections.synchronizedSet(new HashSet<>());
    /**
     *  与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    private Session session;
    /**
     * 会话id
     */
    private String token;
    /**
     * 当前会话对应的用户
     */
    private SysQxYhxx user;
    /**
     * 系统消息参数对象
     */
    private static MyParams xtxxParams;
    /**
     *  连接建立成功调用的方法
     * @param session  可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        token = session.getPathParameters().get("token");
        user = UserManager.getUser(token);
        //系统消息注册,默认每个人都有
        jtmddSet.add(SysPtglXtxx.SYS_PTGL_XTXX);
        xtxxMap.put(token,this);
        log.info("新增一连接!当前在线人数为"+ getOnlineCount());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(){
        xtxxMap.remove(token);
        log.info("有一连接关闭!当前在线人数为"+ getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.debug("来自客户端的消息:"+message);
        WebSocketKhdxxVo wsk = JSON.parseObject(message, WebSocketKhdxxVo.class);
        wsk.setToken(token);
        MyParams jcxx = LjqManager.jcxxByDxdm(wsk.getMdddl(), user);
        //设置客户端消息
        jcxx.sys().setWskhdxx(wsk);
        Result r;
        try{
            switch (wsk.getXxlb()){
                case "1":
                    //注册目的地
                    jtmddSet.add(wsk.getMdd());
                    //设置处理类型
                    jcxx.sys().setCllx(Cllx.wsmddzc.name());
                    r = LjqManager.data(jcxx);
                    break;
                case "2":
                    //取消目的地
                    jtmddSet.remove(wsk.getMdd());
                    //设置处理类型
                    jcxx.sys().setCllx(Cllx.wsmddqx.name());
                    r = LjqManager.data(jcxx);
                    break;
                default:
                    throw new MyException("暂不支持的消息类型:"+wsk);
            }
        }catch (Throwable t){
            r = failed(t.getMessage());
            log.error(r.getMsg(),t);
        }
        if(!r.isStatus()){
            //回调失败
            SysPtglXtxx xx = SysPtglXtxx.builder().xxnr(wsk.getMdd() + ":消息处理失败》"+r.getMsg())
                            .mdddl(wsk.getMdddl()).mddxl(wsk.getMddxl()).tshh(token).build();
            XtxxWebSocket.sendMsg(xx,user);
        }
    }

    /**
     * 发生错误时调用
     */
    @OnError
    public void onError(Session session, Throwable error){
        log.trace("websocket发生错误:{},用户:{}",token,user==null?null:user.getYhdm(),error);
//        SysPtglXtxx xx = new SysPtglXtxx("异常:" + error.getMessage());
//        xx.setTshh(token);
//        sendMsg(xx,user);
    }

    /**
     * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
     */
    public void sendMessage(SysPtglXtxx xx) throws IOException {
        this.session.getBasicRemote().sendText(success("正常推送",xx).toString());
    }

    /**
     * 通过websoket向前端推送消息
     * @param xtxx 消息体
     * @param user 推送人
     */
    public synchronized static Result sendMsg(SysPtglXtxx xtxx, SysQxYhxx user){
        if(!SysPtglXtxx.XXLB_SXXX.equals(xtxx.getXxlb())&&isBlank(xtxx.getTshh())
                &&SysPtglXtxx.SYS_PTGL_XTXX.equals(xtxx.getMdd())){
            //非要求客户端刷新的消息 且 推送目的地为空,系统消息 且 非按会话推送
            //添加到消息表
            xtxx.setYdzt(Ljpd.FALSE.getCode());
            xtxx.setId(StringUtil.getUUIDUpperStr());
            getXtxxParams().put(LjqInterface.KEY_USER,user);
            xtxxParams.put(LjqInterface.KEY_YOBJ,xtxx);
            LjqManager.data(xtxxParams);
        }
        try {
            List xxList = new ArrayList<>(xtxxMap.values());
            if(!isBlank(xtxx.getTshh())){
                //推送会话
                xxList = new ArrayList<>();
                XtxxWebSocket xx = xtxxMap.get(xtxx.getTshh());
                if(xx==null){
                    return failed("推送的会话不存在:"+xtxx.getTshh());
                }
                xxList.add(xx);
            }
            Iterator it;
            XtxxWebSocket item;
            if(!isBlank(xtxx.getJsr())){
                it = xxList.iterator();
                while (it.hasNext()){
                    item = it.next();
                    if(!item.user.getId().equals(xtxx.getJsr())){
                        it.remove();
                    }
                }
            }
            if(!isBlank(xtxx.getJsdw())){
                it = xxList.iterator();
                while (it.hasNext()){
                    item = it.next();
                    if(!item.user.getSsjg().equals(xtxx.getJsdw())){
                        it.remove();
                    }
                }
            }
            if(!isBlank(xtxx.getMdd())){
                it = xxList.iterator();
                while (it.hasNext()){
                    item = it.next();
                    if(!item.jtmddSet.contains(xtxx.getMdd())){
                        it.remove();
                    }
                }
            }
            for(XtxxWebSocket i : xxList){
                i.sendMessage(xtxx);
            }
            return success("成功向"+xxList.size()+"人推送消息:"+xtxx.getXxnr());
        }catch (Exception e){
            slog.error("消息推送异常",e);
            throw new MyException("推送消息异常:"+ e.getMessage(),e);
        }
    }
    /**
     * @return 在线用户数
     */
    public static int getOnlineCount() {
        return xtxxMap.size();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        XtxxWebSocket that = (XtxxWebSocket) o;
        return Objects.equals(session, that.session);
    }

    @Override
    public int hashCode() {
        return Objects.hash(session);
    }

    private static MyParams getXtxxParams(){
        if(xtxxParams==null){
            xtxxParams = LjqManager.jcxxByDxdm("SYS_PTGL_XTXX");
            xtxxParams.sys().setCllx(Cllx.insert.name());
        }
        return xtxxParams;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy