优化级联时的异常处理
This commit is contained in:
parent
f47d2edcf5
commit
3546ef7df3
@ -55,7 +55,7 @@ public class ApplicationCheckRunner implements CommandLineRunner {
|
|||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mediaIp.equals("localhost") || mediaIp.equals("127.0.0.1")) {
|
if (mediaIp.equals("localhost") || (mediaIp.equals("127.0.0.1") && mediaWanIp == null)) {
|
||||||
logger.warn("mediaIp.ip使用 {} ,将无法收到网络内其他设备的推流!!!", mediaIp );
|
logger.warn("mediaIp.ip使用 {} ,将无法收到网络内其他设备的推流!!!", mediaIp );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.genersoft.iot.vmp.conf;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.CommandLineRunner;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统启动时控制设备离线
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Order(value=4)
|
||||||
|
public class SipDeviceRunner implements CommandLineRunner {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(String... args) throws Exception {
|
||||||
|
// 设置所有设备离线
|
||||||
|
storager.outlineForAll();
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.conf;
|
|||||||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
|
||||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -28,6 +29,10 @@ public class SipPlatformRunner implements CommandLineRunner {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private EventPublisher publisher;
|
private EventPublisher publisher;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ZLMRTPServerFactory zlmrtpServerFactory;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(String... args) throws Exception {
|
public void run(String... args) throws Exception {
|
||||||
// 设置所有平台离线
|
// 设置所有平台离线
|
||||||
@ -36,6 +41,9 @@ public class SipPlatformRunner implements CommandLineRunner {
|
|||||||
// 清理所有平台注册缓存
|
// 清理所有平台注册缓存
|
||||||
redisCatchStorage.cleanPlatformRegisterInfos();
|
redisCatchStorage.cleanPlatformRegisterInfos();
|
||||||
|
|
||||||
|
// 停止所有推流
|
||||||
|
// zlmrtpServerFactory.closeAllSendRtpStream();
|
||||||
|
|
||||||
List<ParentPlatform> parentPlatforms = storager.queryEnableParentPlatformList(true);
|
List<ParentPlatform> parentPlatforms = storager.queryEnableParentPlatformList(true);
|
||||||
|
|
||||||
for (ParentPlatform parentPlatform : parentPlatforms) {
|
for (ParentPlatform parentPlatform : parentPlatforms) {
|
||||||
|
@ -111,7 +111,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
http.headers().contentTypeOptions().disable();
|
http.headers().contentTypeOptions().disable();
|
||||||
http.authorizeRequests()
|
http.authorizeRequests()
|
||||||
// 放行接口
|
// 放行接口
|
||||||
.antMatchers("/api/user/login","/index/hook/**").permitAll()
|
.antMatchers("/#/**", "/api/user/login","/index/hook/**").permitAll()
|
||||||
// 除上面外的所有请求全部需要鉴权认证
|
// 除上面外的所有请求全部需要鉴权认证
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
// 异常处理(权限拒绝、登录失效等)
|
// 异常处理(权限拒绝、登录失效等)
|
||||||
|
@ -39,8 +39,8 @@ public class KeepaliveTimeoutListenerForPlatform extends KeyExpirationEventMessa
|
|||||||
// 获取失效的key
|
// 获取失效的key
|
||||||
String expiredKey = message.toString();
|
String expiredKey = message.toString();
|
||||||
logger.info(expiredKey);
|
logger.info(expiredKey);
|
||||||
if(!expiredKey.startsWith(VideoManagerConstants.PLATFORM_PREFIX)){
|
if(!expiredKey.startsWith(VideoManagerConstants.PLATFORM_KEEPLIVEKEY_PREFIX)){
|
||||||
logger.info("收到redis过期监听,但开头不是"+VideoManagerConstants.PLATFORM_PREFIX+",忽略");
|
logger.debug("收到redis过期监听,但开头不是"+VideoManagerConstants.PLATFORM_KEEPLIVEKEY_PREFIX+",忽略");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 平台心跳到期,需要重发, 判断是否已经多次未收到心跳回复, 多次未收到,则重新发起注册, 注册尝试多次未得到回复,则认为平台离线
|
// 平台心跳到期,需要重发, 判断是否已经多次未收到心跳回复, 多次未收到,则重新发起注册, 注册尝试多次未得到回复,则认为平台离线
|
||||||
@ -49,7 +49,6 @@ public class KeepaliveTimeoutListenerForPlatform extends KeyExpirationEventMessa
|
|||||||
|
|
||||||
publisher.platformKeepaliveExpireEventPublish(platformGBId);
|
publisher.platformKeepaliveExpireEventPublish(platformGBId);
|
||||||
}else if (expiredKey.startsWith(VideoManagerConstants.PLATFORM_REGISTER_PREFIX)) {
|
}else if (expiredKey.startsWith(VideoManagerConstants.PLATFORM_REGISTER_PREFIX)) {
|
||||||
logger.info("11111111111111");
|
|
||||||
String platformGBId = expiredKey.substring(VideoManagerConstants.PLATFORM_REGISTER_PREFIX.length(),expiredKey.length());
|
String platformGBId = expiredKey.substring(VideoManagerConstants.PLATFORM_REGISTER_PREFIX.length(),expiredKey.length());
|
||||||
|
|
||||||
publisher.platformNotRegisterEventPublish(platformGBId);
|
publisher.platformNotRegisterEventPublish(platformGBId);
|
||||||
|
@ -38,7 +38,7 @@ public class KeepliveTimeoutListener extends KeyExpirationEventMessageListener {
|
|||||||
// 获取失效的key
|
// 获取失效的key
|
||||||
String expiredKey = message.toString();
|
String expiredKey = message.toString();
|
||||||
if(!expiredKey.startsWith(VideoManagerConstants.KEEPLIVEKEY_PREFIX)){
|
if(!expiredKey.startsWith(VideoManagerConstants.KEEPLIVEKEY_PREFIX)){
|
||||||
logger.info("收到redis过期监听,但开头不是"+VideoManagerConstants.KEEPLIVEKEY_PREFIX+",忽略");
|
logger.debug("收到redis过期监听,但开头不是"+VideoManagerConstants.KEEPLIVEKEY_PREFIX+",忽略");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@ public class PlatformKeepaliveExpireEventLister implements ApplicationListener<P
|
|||||||
if (parentPlatformCatch.getKeepAliveReply() >= 3) {
|
if (parentPlatformCatch.getKeepAliveReply() >= 3) {
|
||||||
// 有3次未收到心跳回复, 设置平台状态为离线, 开始重新注册
|
// 有3次未收到心跳回复, 设置平台状态为离线, 开始重新注册
|
||||||
logger.warn("有3次未收到心跳回复,标记设置平台状态为离线, 并重新注册 平台国标ID:" + event.getPlatformGbID());
|
logger.warn("有3次未收到心跳回复,标记设置平台状态为离线, 并重新注册 平台国标ID:" + event.getPlatformGbID());
|
||||||
|
storager.updateParentPlatformStatus(event.getPlatformGbID(), false);
|
||||||
publisher.platformNotRegisterEventPublish(event.getPlatformGbID());
|
publisher.platformNotRegisterEventPublish(event.getPlatformGbID());
|
||||||
parentPlatformCatch.setKeepAliveReply(0);
|
parentPlatformCatch.setKeepAliveReply(0);
|
||||||
}else {
|
}else {
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.event.platformNotRegister;
|
package com.genersoft.iot.vmp.gb28181.event.platformNotRegister;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
|
||||||
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -9,6 +12,10 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 平台未注册事件,来源有二:
|
* @Description: 平台未注册事件,来源有二:
|
||||||
* 1、平台新添加
|
* 1、平台新添加
|
||||||
@ -23,23 +30,53 @@ public class PlatformNotRegisterEventLister implements ApplicationListener<Platf
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IVideoManagerStorager storager;
|
private IVideoManagerStorager storager;
|
||||||
|
@Autowired
|
||||||
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SIPCommanderFroPlatform sipCommanderFroPlatform;
|
private SIPCommanderFroPlatform sipCommanderFroPlatform;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ZLMRTPServerFactory zlmrtpServerFactory;
|
||||||
|
|
||||||
// @Autowired
|
// @Autowired
|
||||||
// private RedisUtil redis;
|
// private RedisUtil redis;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onApplicationEvent(PlatformNotRegisterEvent event) {
|
public void onApplicationEvent(PlatformNotRegisterEvent event) {
|
||||||
|
|
||||||
logger.debug("平台未注册事件触发,平台国标ID:" + event.getPlatformGbID());
|
logger.info("平台未注册事件触发,平台国标ID:" + event.getPlatformGbID());
|
||||||
|
|
||||||
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(event.getPlatformGbID());
|
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(event.getPlatformGbID());
|
||||||
if (parentPlatform == null) {
|
if (parentPlatform == null) {
|
||||||
logger.debug("平台未注册事件触发,但平台已经删除!!! 平台国标ID:" + event.getPlatformGbID());
|
logger.info("平台未注册事件触发,但平台已经删除!!! 平台国标ID:" + event.getPlatformGbID());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// 查询是否有推流, 如果有则都停止
|
||||||
|
List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServer(event.getPlatformGbID());
|
||||||
|
logger.info("停止[ {} ]的所有推流size", sendRtpItems.size());
|
||||||
|
if (sendRtpItems != null && sendRtpItems.size() > 0) {
|
||||||
|
logger.info("停止[ {} ]的所有推流", event.getPlatformGbID());
|
||||||
|
StringBuilder app = new StringBuilder();
|
||||||
|
StringBuilder stream = new StringBuilder();
|
||||||
|
for (int i = 0; i < sendRtpItems.size(); i++) {
|
||||||
|
if (app.length() != 0) {
|
||||||
|
app.append(",");
|
||||||
|
}
|
||||||
|
app.append(sendRtpItems.get(i).getApp());
|
||||||
|
if (stream.length() != 0) {
|
||||||
|
stream.append(",");
|
||||||
|
}
|
||||||
|
stream.append(sendRtpItems.get(i).getStreamId());
|
||||||
|
redisCatchStorage.deleteSendRTPServer(event.getPlatformGbID(), sendRtpItems.get(i).getChannelId());
|
||||||
|
}
|
||||||
|
Map<String, Object> param = new HashMap<>();
|
||||||
|
param.put("vhost","__defaultVhost__");
|
||||||
|
param.put("app", app.toString());
|
||||||
|
param.put("stream", stream.toString());
|
||||||
|
zlmrtpServerFactory.stopSendRtpStream(param);
|
||||||
|
|
||||||
|
}
|
||||||
sipCommanderFroPlatform.register(parentPlatform);
|
sipCommanderFroPlatform.register(parentPlatform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ public class CheckForAllRecordsThread extends Thread {
|
|||||||
if (totalRecordList.size() < this.recordInfo.getSumNum()) {
|
if (totalRecordList.size() < this.recordInfo.getSumNum()) {
|
||||||
logger.info("已获取" + totalRecordList.size() + "项录像数据,共" + this.recordInfo.getSumNum() + "项");
|
logger.info("已获取" + totalRecordList.size() + "项录像数据,共" + this.recordInfo.getSumNum() + "项");
|
||||||
} else {
|
} else {
|
||||||
logger.info("录像数据已全部获取,共" + this.recordInfo.getSumNum() + "项");
|
logger.info("录像数据已全部获取,共 {} 项", this.recordInfo.getSumNum());
|
||||||
this.recordInfo.setRecordList(totalRecordList);
|
this.recordInfo.setRecordList(totalRecordList);
|
||||||
for (int i = 0; i < cacheKeys.size(); i++) {
|
for (int i = 0; i < cacheKeys.size(); i++) {
|
||||||
redis.del(cacheKeys.get(i).toString());
|
redis.del(cacheKeys.get(i).toString());
|
||||||
|
@ -58,6 +58,7 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
param.put("vhost","__defaultVhost__");
|
param.put("vhost","__defaultVhost__");
|
||||||
param.put("app",sendRtpItem.getApp());
|
param.put("app",sendRtpItem.getApp());
|
||||||
param.put("stream",streamId);
|
param.put("stream",streamId);
|
||||||
|
param.put("ssrc",sendRtpItem.getSsrc());
|
||||||
logger.info("停止向上级推流:" + streamId);
|
logger.info("停止向上级推流:" + streamId);
|
||||||
zlmrtpServerFactory.stopSendRtpStream(param);
|
zlmrtpServerFactory.stopSendRtpStream(param);
|
||||||
redisCatchStorage.deleteSendRTPServer(platformGbId, channelId);
|
redisCatchStorage.deleteSendRTPServer(platformGbId, channelId);
|
||||||
|
@ -93,6 +93,11 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId);
|
GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId);
|
||||||
// 不是通道可能是直播流
|
// 不是通道可能是直播流
|
||||||
if (channel != null || gbStream != null ) {
|
if (channel != null || gbStream != null ) {
|
||||||
|
if (channel.getStatus() == 0) {
|
||||||
|
logger.info("通道离线,返回400");
|
||||||
|
responseAck(evt, Response.BAD_REQUEST, "channel [" + channel.getChannelId() + "] offline");
|
||||||
|
return;
|
||||||
|
}
|
||||||
responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
|
responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
|
||||||
}else {
|
}else {
|
||||||
logger.info("通道不存在,返回404");
|
logger.info("通道不存在,返回404");
|
||||||
@ -367,6 +372,12 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
getServerTransaction(evt).sendResponse(response);
|
getServerTransaction(evt).sendResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void responseAck(RequestEvent evt, int statusCode, String msg) throws SipException, InvalidArgumentException, ParseException {
|
||||||
|
Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
|
||||||
|
response.setReasonPhrase(msg);
|
||||||
|
getServerTransaction(evt).sendResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回复带sdp的200
|
* 回复带sdp的200
|
||||||
* @param evt
|
* @param evt
|
||||||
|
@ -770,14 +770,17 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
try {
|
try {
|
||||||
Element rootElement = getRootElement(evt);
|
Element rootElement = getRootElement(evt);
|
||||||
String deviceId = XmlUtil.getText(rootElement, "DeviceID");
|
String deviceId = XmlUtil.getText(rootElement, "DeviceID");
|
||||||
// 检查设备是否存在, 不存在则不回复
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
if (storager.exists(deviceId)) {
|
// 检查设备是否存在并在线, 不存在则不回复
|
||||||
|
if (device != null && device.getOnline() == 1) {
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt);
|
||||||
if (offLineDetector.isOnline(deviceId)) {
|
if (offLineDetector.isOnline(deviceId)) {
|
||||||
publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
|
publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
|
}else {
|
||||||
|
logger.warn("收到[ "+deviceId+" ]心跳信息, 但是设备" + (device == null? "不存在":"离线") + ", 心跳信息不予以回复");
|
||||||
}
|
}
|
||||||
} catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
|
} catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -146,7 +146,7 @@ public class RegisterRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
// 注册成功
|
// 注册成功
|
||||||
// 保存到redis
|
// 保存到redis
|
||||||
// 下发catelog查询目录
|
// 下发catelog查询目录
|
||||||
if (registerFlag == 1 && device != null) {
|
if (registerFlag == 1 ) {
|
||||||
logger.info("注册成功! deviceId:" + device.getDeviceId());
|
logger.info("注册成功! deviceId:" + device.getDeviceId());
|
||||||
// boolean exists = storager.exists(device.getDeviceId());
|
// boolean exists = storager.exists(device.getDeviceId());
|
||||||
device.setRegisterTimeMillis(System.currentTimeMillis());
|
device.setRegisterTimeMillis(System.currentTimeMillis());
|
||||||
|
@ -80,12 +80,13 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor {
|
|||||||
// 注册/注销成功
|
// 注册/注销成功
|
||||||
logger.info(String.format("%s %s成功", platformGBId, action));
|
logger.info(String.format("%s %s成功", platformGBId, action));
|
||||||
redisCatchStorage.delPlatformRegisterInfo(callId);
|
redisCatchStorage.delPlatformRegisterInfo(callId);
|
||||||
parentPlatform.setStatus(true);
|
parentPlatform.setStatus("注册".equals(action));
|
||||||
// 取回Expires设置,避免注销过程中被置为0
|
// 取回Expires设置,避免注销过程中被置为0
|
||||||
ParentPlatform parentPlatformTmp = storager.queryParentPlatByServerGBId(platformGBId);
|
ParentPlatform parentPlatformTmp = storager.queryParentPlatByServerGBId(platformGBId);
|
||||||
String expires = parentPlatformTmp.getExpires();
|
String expires = parentPlatformTmp.getExpires();
|
||||||
parentPlatform.setExpires(expires);
|
parentPlatform.setExpires(expires);
|
||||||
storager.updateParentPlatform(parentPlatform);
|
parentPlatform.setId(parentPlatformTmp.getId());
|
||||||
|
storager.updateParentPlatformStatus(platformGBId, "注册".equals(action));
|
||||||
|
|
||||||
redisCatchStorage.updatePlatformRegister(parentPlatform);
|
redisCatchStorage.updatePlatformRegister(parentPlatform);
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package com.genersoft.iot.vmp.media.zlm;
|
package com.genersoft.iot.vmp.media.zlm;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.genersoft.iot.vmp.conf.MediaServerConfig;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
|
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
|
||||||
@ -119,4 +122,33 @@ public class ZLMMediaListManager {
|
|||||||
storager.mediaOutline(app, streamId);
|
storager.mediaOutline(app, streamId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearAllSessions() {
|
||||||
|
logger.info("清空所有国标相关的session");
|
||||||
|
JSONObject allSessionJSON = zlmresTfulUtils.getAllSession();
|
||||||
|
MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
|
||||||
|
HashSet<String> allLocalPorts = new HashSet();
|
||||||
|
if (allSessionJSON.getInteger("code") == 0) {
|
||||||
|
JSONArray data = allSessionJSON.getJSONArray("data");
|
||||||
|
if (data.size() > 0) {
|
||||||
|
for (int i = 0; i < data.size(); i++) {
|
||||||
|
JSONObject sessionJOSN = data.getJSONObject(i);
|
||||||
|
Integer local_port = sessionJOSN.getInteger("local_port");
|
||||||
|
if (!local_port.equals(Integer.valueOf(mediaInfo.getHttpPort())) &&
|
||||||
|
!local_port.equals(Integer.valueOf(mediaInfo.getHttpSSLport())) &&
|
||||||
|
!local_port.equals(Integer.valueOf(mediaInfo.getRtmpPort())) &&
|
||||||
|
!local_port.equals(Integer.valueOf(mediaInfo.getRtspPort())) &&
|
||||||
|
!local_port.equals(Integer.valueOf(mediaInfo.getRtspSSlport())) &&
|
||||||
|
!local_port.equals(Integer.valueOf(mediaInfo.getHookOnFlowReport()))){
|
||||||
|
allLocalPorts.add(sessionJOSN.getInteger("local_port") + "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (allLocalPorts.size() > 0) {
|
||||||
|
List<String> result = new ArrayList<>(allLocalPorts);
|
||||||
|
String localPortSStr = String.join(",", result);
|
||||||
|
zlmresTfulUtils.kickSessions(localPortSStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,4 +194,14 @@ public class ZLMRESTfulUtils {
|
|||||||
param.put("force", 1);
|
param.put("force", 1);
|
||||||
return sendPost("close_streams",param, null);
|
return sendPost("close_streams",param, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JSONObject getAllSession() {
|
||||||
|
return sendPost("getAllSession",null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void kickSessions(String localPortSStr) {
|
||||||
|
Map<String, Object> param = new HashMap<>();
|
||||||
|
param.put("local_port", localPortSStr);
|
||||||
|
sendPost("kick_sessions",param, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,13 +18,13 @@ public class ZLMRTPServerFactory {
|
|||||||
|
|
||||||
private Logger logger = LoggerFactory.getLogger("ZLMRTPServerFactory");
|
private Logger logger = LoggerFactory.getLogger("ZLMRTPServerFactory");
|
||||||
|
|
||||||
@Value("${media.rtp.udpPortRange}")
|
@Value("${media.rtp.portRange}")
|
||||||
private String udpPortRange;
|
private String portRange;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ZLMRESTfulUtils zlmresTfulUtils;
|
private ZLMRESTfulUtils zlmresTfulUtils;
|
||||||
|
|
||||||
private int[] udpPortRangeArray = new int[2];
|
private int[] portRangeArray = new int[2];
|
||||||
|
|
||||||
private int currentPort = 0;
|
private int currentPort = 0;
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ public class ZLMRTPServerFactory {
|
|||||||
|
|
||||||
Map<String, Object> param = new HashMap<>();
|
Map<String, Object> param = new HashMap<>();
|
||||||
int result = -1;
|
int result = -1;
|
||||||
int newPort = getPortFromUdpPortRange();
|
int newPort = getPortFromportRange();
|
||||||
param.put("port", newPort);
|
param.put("port", newPort);
|
||||||
param.put("enable_tcp", 1);
|
param.put("enable_tcp", 1);
|
||||||
param.put("stream_id", streamId);
|
param.put("stream_id", streamId);
|
||||||
@ -101,16 +101,16 @@ public class ZLMRTPServerFactory {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getPortFromUdpPortRange() {
|
private int getPortFromportRange() {
|
||||||
if (currentPort == 0) {
|
if (currentPort == 0) {
|
||||||
String[] udpPortRangeStrArray = udpPortRange.split(",");
|
String[] portRangeStrArray = portRange.split(",");
|
||||||
udpPortRangeArray[0] = Integer.parseInt(udpPortRangeStrArray[0]);
|
portRangeArray[0] = Integer.parseInt(portRangeStrArray[0]);
|
||||||
udpPortRangeArray[1] = Integer.parseInt(udpPortRangeStrArray[1]);
|
portRangeArray[1] = Integer.parseInt(portRangeStrArray[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentPort == 0 || currentPort++ > udpPortRangeArray[1]) {
|
if (currentPort == 0 || currentPort++ > portRangeArray[1]) {
|
||||||
currentPort = udpPortRangeArray[0];
|
currentPort = portRangeArray[0];
|
||||||
return udpPortRangeArray[0];
|
return portRangeArray[0];
|
||||||
} else {
|
} else {
|
||||||
if (currentPort % 2 == 1) {
|
if (currentPort % 2 == 1) {
|
||||||
currentPort++;
|
currentPort++;
|
||||||
@ -244,4 +244,8 @@ public class ZLMRTPServerFactory {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void closeAllSendRtpStream() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,6 +164,10 @@ public class ZLMRunner implements CommandLineRunner {
|
|||||||
mediaServerConfig.setLocalIP(mediaIp);
|
mediaServerConfig.setLocalIP(mediaIp);
|
||||||
mediaServerConfig.setWanIp(StringUtils.isEmpty(mediaWanIp)? mediaIp: mediaWanIp);
|
mediaServerConfig.setWanIp(StringUtils.isEmpty(mediaWanIp)? mediaIp: mediaWanIp);
|
||||||
redisCatchStorage.updateMediaInfo(mediaServerConfig);
|
redisCatchStorage.updateMediaInfo(mediaServerConfig);
|
||||||
|
|
||||||
|
// 清空所有session
|
||||||
|
// zlmMediaListManager.clearAllSessions();
|
||||||
|
|
||||||
// 更新流列表
|
// 更新流列表
|
||||||
zlmMediaListManager.updateMediaList();
|
zlmMediaListManager.updateMediaList();
|
||||||
// 恢复流代理
|
// 恢复流代理
|
||||||
|
@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
|||||||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
|
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public interface IRedisCatchStorage {
|
public interface IRedisCatchStorage {
|
||||||
@ -91,6 +92,8 @@ public interface IRedisCatchStorage {
|
|||||||
*/
|
*/
|
||||||
SendRtpItem querySendRTPServer(String platformGbId, String channelId);
|
SendRtpItem querySendRTPServer(String platformGbId, String channelId);
|
||||||
|
|
||||||
|
List<SendRtpItem> querySendRTPServer(String platformGbId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除RTP推送信息缓存
|
* 删除RTP推送信息缓存
|
||||||
* @param platformGbId
|
* @param platformGbId
|
||||||
|
@ -135,6 +135,13 @@ public interface IVideoManagerStorager {
|
|||||||
*/
|
*/
|
||||||
public boolean outline(String deviceId);
|
public boolean outline(String deviceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新所有设备离线
|
||||||
|
*
|
||||||
|
* @return true:更新成功 false:更新失败
|
||||||
|
*/
|
||||||
|
public boolean outlineForAll();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询子设备
|
* 查询子设备
|
||||||
@ -352,4 +359,10 @@ public interface IVideoManagerStorager {
|
|||||||
* @param streamId
|
* @param streamId
|
||||||
*/
|
*/
|
||||||
void mediaOutline(String app, String streamId);
|
void mediaOutline(String app, String streamId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置平台在线/离线
|
||||||
|
* @param online
|
||||||
|
*/
|
||||||
|
void updateParentPlatformStatus(String platformGbID, boolean online);
|
||||||
}
|
}
|
||||||
|
@ -65,4 +65,7 @@ public interface DeviceMapper {
|
|||||||
|
|
||||||
@Delete("DELETE FROM device WHERE deviceId=#{deviceId}")
|
@Delete("DELETE FROM device WHERE deviceId=#{deviceId}")
|
||||||
int del(String deviceId);
|
int del(String deviceId);
|
||||||
|
|
||||||
|
@Update("UPDATE device SET online=0")
|
||||||
|
int outlineForAll();
|
||||||
}
|
}
|
||||||
|
@ -66,5 +66,8 @@ public interface ParentPlatformMapper {
|
|||||||
ParentPlatform getParentPlatById(int id);
|
ParentPlatform getParentPlatById(int id);
|
||||||
|
|
||||||
@Update("UPDATE parent_platform SET status=false" )
|
@Update("UPDATE parent_platform SET status=false" )
|
||||||
void outlineForAllParentPlatform();
|
int outlineForAllParentPlatform();
|
||||||
|
|
||||||
|
@Update("UPDATE parent_platform SET status=#{online} WHERE serverGBId=#{platformGbID}" )
|
||||||
|
int updateParentPlatformStatus(String platformGbID, boolean online);
|
||||||
}
|
}
|
||||||
|
@ -233,6 +233,20 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
|||||||
return (SendRtpItem)redis.get(key);
|
return (SendRtpItem)redis.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SendRtpItem> querySendRTPServer(String platformGbId) {
|
||||||
|
String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + platformGbId + "_*";
|
||||||
|
List<Object> queryResult = redis.scan(key);
|
||||||
|
List<SendRtpItem> result= new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < queryResult.size(); i++) {
|
||||||
|
String keyItem = (String) queryResult.get(i);
|
||||||
|
result.add((SendRtpItem)redis.get(keyItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除RTP推送信息缓存
|
* 删除RTP推送信息缓存
|
||||||
* @param platformGbId
|
* @param platformGbId
|
||||||
|
@ -256,6 +256,18 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
|
|||||||
return deviceMapper.update(device) > 0;
|
return deviceMapper.update(device) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新所有设备离线
|
||||||
|
*
|
||||||
|
* @return true:更新成功 false:更新失败
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized boolean outlineForAll() {
|
||||||
|
logger.info("更新所有设备离线");
|
||||||
|
int result = deviceMapper.outlineForAll();
|
||||||
|
return result > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清空通道
|
* 清空通道
|
||||||
* @param deviceId
|
* @param deviceId
|
||||||
@ -575,5 +587,8 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
|
|||||||
gbStreamMapper.setStatus(app, streamId, false);
|
gbStreamMapper.setStatus(app, streamId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateParentPlatformStatus(String platformGbID, boolean online) {
|
||||||
|
platformMapper.updateParentPlatformStatus(platformGbID, online);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,12 +78,12 @@ media:
|
|||||||
autoApplyPlay: false
|
autoApplyPlay: false
|
||||||
# [可选] 部分设备需要扩展SDP,需要打开此设置
|
# [可选] 部分设备需要扩展SDP,需要打开此设置
|
||||||
seniorSdp: false
|
seniorSdp: false
|
||||||
# 启用udp多端口模式
|
# 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
|
||||||
rtp:
|
rtp:
|
||||||
# [可选] 是否启用udp多端口模式, 开启后会在udpPortRange范围内选择端口用于媒体流传输
|
# [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
|
||||||
enable: true
|
enable: true
|
||||||
# [可选] 在此范围内选择端口用于媒体流传输, 不只是udp, 使用TCP被动传输模式时,也是从这个范围内选择端口
|
# [可选] 在此范围内选择端口用于媒体流传输,
|
||||||
udpPortRange: 30000,30500 # 端口范围
|
portRange: 30000,30500 # 端口范围
|
||||||
|
|
||||||
# [可选] 日志配置, 一般不需要改
|
# [可选] 日志配置, 一般不需要改
|
||||||
logging:
|
logging:
|
||||||
|
Loading…
Reference in New Issue
Block a user