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;
}
}