|
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.handler.req;
|
|
|
|
|
|
|
|
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
|
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.SipDate;
|
|
import cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.SipDate;
|
|
|
|
|
+import cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.handler.IReqHandler;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.yanfan.utils.DigestAuthUtil;
|
|
import cn.iocoder.yudao.module.pms.controller.admin.yanfan.utils.DigestAuthUtil;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.yanfan.device.YfIotDeviceDO;
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.yanfan.device.YfIotDeviceDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.yanfan.sip.config.IotSipConfigDO;
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.yanfan.sip.config.IotSipConfigDO;
|
|
@@ -13,11 +14,13 @@ import cn.iocoder.yudao.module.pms.service.yanfan.config.SysSipConfig;
|
|
|
import cn.iocoder.yudao.module.pms.service.yanfan.device.YfIotDeviceService;
|
|
import cn.iocoder.yudao.module.pms.service.yanfan.device.YfIotDeviceService;
|
|
|
import cn.iocoder.yudao.module.pms.service.yanfan.sip.IGBListener;
|
|
import cn.iocoder.yudao.module.pms.service.yanfan.sip.IGBListener;
|
|
|
import cn.iocoder.yudao.module.pms.service.yanfan.sip.IMqttService;
|
|
import cn.iocoder.yudao.module.pms.service.yanfan.sip.IMqttService;
|
|
|
-import cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.handler.IReqHandler;
|
|
|
|
|
import cn.iocoder.yudao.module.pms.service.yanfan.sip.MessageInvoker;
|
|
import cn.iocoder.yudao.module.pms.service.yanfan.sip.MessageInvoker;
|
|
|
import cn.iocoder.yudao.module.pms.service.yanfan.sip.config.IotSipConfigService;
|
|
import cn.iocoder.yudao.module.pms.service.yanfan.sip.config.IotSipConfigService;
|
|
|
import cn.iocoder.yudao.module.pms.service.yanfan.sip.device.YfSipDeviceService;
|
|
import cn.iocoder.yudao.module.pms.service.yanfan.sip.device.YfSipDeviceService;
|
|
|
import cn.iocoder.yudao.module.pms.service.yanfan.sip.device.channel.YfSipDeviceChannelService;
|
|
import cn.iocoder.yudao.module.pms.service.yanfan.sip.device.channel.YfSipDeviceChannelService;
|
|
|
|
|
+import com.google.common.cache.Cache;
|
|
|
|
|
+import com.google.common.cache.CacheBuilder;
|
|
|
|
|
+import com.google.common.util.concurrent.RateLimiter;
|
|
|
import gov.nist.javax.sip.address.AddressImpl;
|
|
import gov.nist.javax.sip.address.AddressImpl;
|
|
|
import gov.nist.javax.sip.address.SipUri;
|
|
import gov.nist.javax.sip.address.SipUri;
|
|
|
import gov.nist.javax.sip.header.Expires;
|
|
import gov.nist.javax.sip.header.Expires;
|
|
@@ -41,6 +44,8 @@ import java.time.LocalDateTime;
|
|
|
import java.util.Calendar;
|
|
import java.util.Calendar;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.Locale;
|
|
import java.util.Locale;
|
|
|
|
|
+import java.util.concurrent.ExecutionException;
|
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
@Slf4j
|
|
@Slf4j
|
|
|
@Component
|
|
@Component
|
|
@@ -74,6 +79,12 @@ public class RegisterReqHandler extends ReqAbstractHandler implements Initializi
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private YfSipDeviceChannelMapper yfSipDeviceChannelMapper;
|
|
private YfSipDeviceChannelMapper yfSipDeviceChannelMapper;
|
|
|
|
|
|
|
|
|
|
+ // 类内定义本地缓存,记录sipId的401请求次数和限流器
|
|
|
|
|
+ private Cache<String, RateLimiter> sipIdRateLimiterCache = CacheBuilder.newBuilder()
|
|
|
|
|
+ .expireAfterWrite(5, TimeUnit.MINUTES) // 5分钟过期
|
|
|
|
|
+ .maximumSize(1000) // 最多缓存1000个设备
|
|
|
|
|
+ .build();
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public void processMsg(RequestEvent evt) {
|
|
public void processMsg(RequestEvent evt) {
|
|
|
TenantUtils.executeIgnore(() -> {
|
|
TenantUtils.executeIgnore(() -> {
|
|
@@ -93,7 +104,12 @@ public class RegisterReqHandler extends ReqAbstractHandler implements Initializi
|
|
|
AuthorizationHeader authorhead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME);
|
|
AuthorizationHeader authorhead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME);
|
|
|
// 校验密码是否正确
|
|
// 校验密码是否正确
|
|
|
if (authorhead == null && !ObjectUtils.isEmpty(sipConfig.getPassword())) {
|
|
if (authorhead == null && !ObjectUtils.isEmpty(sipConfig.getPassword())) {
|
|
|
- log.info("未携带授权头 回复401,sipId:"+ sipId);
|
|
|
|
|
|
|
+ // 获取该sipId的限流器(每秒最多打印1条日志,避免刷屏)
|
|
|
|
|
+ RateLimiter limiter = sipIdRateLimiterCache.get(sipId, () -> RateLimiter.create(1.0));
|
|
|
|
|
+ if (limiter.tryAcquire()) { // 限流控制:每秒仅1次打印日志
|
|
|
|
|
+ log.info("未携带授权头 回复401,sipId:"+ sipId);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 401响应逻辑不变
|
|
|
response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request);
|
|
response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request);
|
|
|
new DigestAuthUtil().generateChallenge(getHeaderFactory(), response, sipConfig.getDomain());
|
|
new DigestAuthUtil().generateChallenge(getHeaderFactory(), response, sipConfig.getDomain());
|
|
|
getServerTransaction(evt).sendResponse(response);
|
|
getServerTransaction(evt).sendResponse(response);
|
|
@@ -191,6 +207,8 @@ public class RegisterReqHandler extends ReqAbstractHandler implements Initializi
|
|
|
}
|
|
}
|
|
|
} catch (SipException | InvalidArgumentException | NoSuchAlgorithmException | ParseException e) {
|
|
} catch (SipException | InvalidArgumentException | NoSuchAlgorithmException | ParseException e) {
|
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
|
|
|
+ } catch (ExecutionException e) {
|
|
|
|
|
+ throw new RuntimeException(e);
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|