java websocket 断线_WebSocket移动端访问时断开连接报错问题。

本文探讨了在Java WebSocket实现中遇到的断线问题,特别是在移动端访问时可能出现的连接报错。文章详细分析了WebSocket的生命周期方法,如`@OnOpen`、`@OnClose`和`@OnMessage`,并展示了如何处理连接建立、关闭和消息传递。同时,提到了使用`ConcurrentHashMap`存储客户端连接,并提供了错误处理示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

package com.ruoyi.web.core;

/**

* @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,

* 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端

*/

@ServerEndpoint("/websocket/{fromUser}")

@Component

public class WebSocket {

private static final Logger log = LoggerFactory.getLogger(WebSocket.class);

// @Autowired

// private IQywxAccessTokenService qywxAccessTokenService;

private static IQywxAccessTokenService qywxAccessTokenService;

private static IWxTalkingInfoService wxTalkingInfoService;

//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。

private static int onlineCount = 0;

//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识

// private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet();

private static ConcurrentHashMap webSocketSetMap = new ConcurrentHashMap<>();

//与某个客户端的连接会话,需要通过它来给客户端发送数据

// private Session session;

// 毫秒转换单位

final static int SECOND = 1000;

// 注入的时候,给类的 service 注入

@Autowired

public void setChatService(IQywxAccessTokenService qywxAccessTokenService) {

WebSocket.qywxAccessTokenService = qywxAccessTokenService;

}

@Autowired

public void setIWxTalkingInfoService(IWxTalkingInfoService wxTalkingInfoService) {

WebSocket.wxTalkingInfoService = wxTalkingInfoService;

}

//@本地启动不能注释,打成war包的时候需要注释,否则在linux中部署会报错

@Bean

public ServerEndpointExporter serverEndpointExporter() {

return new ServerEndpointExporter();

}

/**

* 连接建立成功调用的方法

* @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据

*/

@OnOpen

public void onOpen(@PathParam("fromUser")String fromUser, Session session){

System.err.println("连接成功");

// this.session = session;

if(webSocketSetMap == null) {

webSocketSetMap = new ConcurrentHashMap();

}

webSocketSetMap .put(fromUser,session);

// webSocketSet.add(this); //加入set中

// addOnlineCount(); //在线数加1

}

/**

* 连接关闭调用的方法

*/

@OnClose

public void onClose(@PathParam("fromUser") String fromUser){

System.err.println(fromUser+ "退出了聊天界面");

webSocketSetMap.remove(fromUser);

// webSocketSet.remove(this); //从set中删除

// subOnlineCount(); //在线数减1

}

/**

* 收到客户端消息后调用的方法

* @param message 客户端发送过来的消息

* @param session 可选的参数

*/

@OnMessage

public void onMessage(String message, Session session) {

//{"fromUser":3,"toUser":4,"msgInfo":测试}

System.err.println("message : " + message);

JSONObject jsonObj = JSONObject.parseObject(message);

String msgInfo = "";

if(StringUtils.isNotNull(jsonObj)){

String fromUser = jsonObj.getString("fromUser");

String toUser = jsonObj.getString("toUser");

msgInfo = jsonObj.getString("msgInfo");

String fromUserType = jsonObj.getString("fromUserType");

if(fromUser.length() > toUser.length()){

System.err.println("2222222222222222222222222222222222222");

//说明是用户给理财经理发消息,需要调接口

if(StringUtils.isNotEmpty(fromUser) && StringUtils.isNotEmpty(toUser)){

//调企业微信接口,向理财经理推送文本消息

String corpid = (String) YMLUtils.getCommonYml("qyapi.corpid");

String corpsecret = (String) YMLUtils.getCommonYml("qyapi.corpsecret");

String agentid = YMLUtils.getCommonYml("qyapi.agentid").toString();

String sendUrl = YMLUtils.getCommonYml("qyapi.sendUrl").toString();

log.info("corpid : " + corpid);

log.info("corpsecret : " + corpsecret);

if(qywxAccessTokenService != null){

QywxAccessToken qywxAccessToken = new QywxAccessToken();

qywxAccessToken.setCorpsecret(corpsecret);

List qywxAccessTokenList = qywxAccessTokenService.selectQywxAccessTokenList(qywxAccessToken);

String qyAccessToken = getQyAccessToken(qywxAccessTokenList);

JSONObject jsonObject = new JSONObject();

Text text = new Text();

// text.setContent(msgInfo);

text.setContent("点击查看新消息");

TextMessage msg = new TextMessage();

msg.setText(text);

msg.setTouser("SunZhiQiang");

msg.setAgentid(agentid);

msg.setMsgtype("text");

String msgJson = JSONObject.toJSONString(msg);

String result = HttpUtils.sendSSLPost(sendUrl.replace("ACCESS_TOKEN",qyAccessToken), msgJson);

System.err.println("result : " + result);

}else{

System.err.println("..................");

}

}

}else{

}

// if(webSocketSetMap.containsKey(toUser) && StringUtils.isNotNull(webSocketSetMap.get(toUser))){

// try {

// webSocketSetMap.get(toUser).sendMessage(message);

// } catch (IOException e) {

// e.printStackTrace();

// }

// }

for(Session session_ : webSocketSetMap.values()) {

session_.getAsyncRemote().sendText(message);

}

}

}

/**

* 发生错误时调用

* @param session

* @param error

*/

@OnError

public void onError(Throwable error){

System.err.println("....................................");

error.printStackTrace();

}

/**

* 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。

* @param message

* @throws IOException

*/

// public void sendMessage(String message) throws IOException{

// this.session.getBasicRemote().sendText(message);

// }

public static synchronized int getOnlineCount() {

return onlineCount;

}

public static synchronized void addOnlineCount() {

WebSocket.onlineCount++;

}

public static synchronized void subOnlineCount() {

WebSocket.onlineCount--;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值