关于websocket的重复登陆问题

需求是:要求PC和平板建立连接关系,服务器充当转发作用。

功能比较简单,就PC和平板各自脸上socket然后服务器转发消息就是了。

遇到一个难题是,重复登陆问题,比如A设备登录了,B设备登录了同样的ID,建立了socket连接,这时候A就会收不到消息了(都发到B那里了)。

为了解决这个问题,采用的方法是在B登录时,判断socket连接池里是否已有该id的socket连接,如果有则在B连接之前,先给这个id的socket发送消息,告知已在其他设备登陆,强制退出。

代码比较简单,在OnOpen方法中

 if(webSocketSet.get(operatorId) != null && webSocketSet.get(operatorId).session != null){
    	statusManager.put(operatorId, "repeatLogin");
    	System.out.println("该操作员已登录,强制退出");
		JSONObject result = new JSONObject();
		result.put("message", "您已在别处登录,该设备自动退出");
		result.put("msgType",MSG_TYPE_REPEAT_LOGIN);
		result.put("recipientId",operatorId);
		if(this.OnMessage(result.toString())){
			 webSocketSet.remove(operatorId);
		}
}

但是这样存在一个问题,A收到强制退出,然后A断开连接了,但是A断开的时候,服务器端的onClose监听到这个A断开了,然后从socket连接池里remove掉这个id,这时候这个id已经是B连接着的了,因为它俩是一样的id,所以把B也带掉了。
于是解决办法是加一个标志位

    private static ConcurrentHashMap<String, String> statusManager = new ConcurrentHashMap<>();

当强制登陆的时候,给这个id置为 repeatLogin

statusManager.put(operatorId, "repeatLogin");

如果是正常登录,给这个id置为firstLogin

statusManager.put(operatorId, "firstLogin");

然后在onClose中进行判断

if("firstLogin".equals(statusManager.get(operatorId))){
	webSocketSet.remove(this.operatorId);
	statusManager.remove(this.operatorId);
	System.out.println("删除成功");
	}else{
	statusManager.put(this.operatorId,"firstLogin");
}

如果是强制登陆的,也就是B用户,那就啥也不做,不remove,把A用户remove掉

Tip:还遇到一个小问题,之前做的功能有一个服务器接收到消息,完成转发后,会给发送端一个回应,其实可以在onMessage中的return中返回就可以,不必要在onMessage代码块中进行主动发送,真是太蠢了。。。

// 服务器响应消息
if (jo.containsKey("senderId") && jo.getString("senderId").equals(this.operatorId)) {
	try {
		
		JSONObject messageResult = new JSONObject();
		messageResult.put("msgType", MSG_TYPE_RESPONSE);
		messageResult.put("type", SEND_MSG_RESULT_TYPE_SUCCESS);
		messageResult.put("message", "发送成功");
		AppointSending(this.operatorId, messageResult.toJSONString());
	} catch (Exception e) {
		// TODO Auto-generated catch block
		// e1.printStackTrace();
		log.error(e.getMessage());
	}
}

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值