Merge branch '648540858:wvp-28181-2.0' into wvp-28181-2.0

This commit is contained in:
mk1990 2022-05-23 13:02:50 +08:00 committed by GitHub
commit 46c77302a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 62 additions and 43 deletions

View File

@ -6,6 +6,10 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Pattern;
@Configuration("mediaConfig") @Configuration("mediaConfig")
public class MediaConfig{ public class MediaConfig{
@ -161,7 +165,18 @@ public class MediaConfig{
if (StringUtils.isEmpty(sdpIp)){ if (StringUtils.isEmpty(sdpIp)){
return ip; return ip;
}else { }else {
return sdpIp; if (isValidIPAddress(sdpIp)) {
return sdpIp;
}else {
// 按照域名解析
String hostAddress = null;
try {
hostAddress = InetAddress.getByName(sdpIp).getHostAddress();
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
return hostAddress;
}
} }
} }
@ -211,4 +226,11 @@ public class MediaConfig{
return mediaServerItem; return mediaServerItem;
} }
private boolean isValidIPAddress(String ipAddress) {
if ((ipAddress != null) && (!ipAddress.isEmpty())) {
return Pattern.matches("^([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}$", ipAddress);
}
return false;
}
} }

View File

@ -11,6 +11,9 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
/**
* @author lin
*/
@Component @Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler { public class LoginSuccessHandler implements AuthenticationSuccessHandler {

View File

@ -20,6 +20,7 @@ import java.util.List;
/** /**
* 配置Spring Security * 配置Spring Security
* @author lin
*/ */
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@ -132,15 +133,19 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.anyRequest().authenticated() .anyRequest().authenticated()
// 异常处理(权限拒绝登录失效等) // 异常处理(权限拒绝登录失效等)
.and().exceptionHandling() .and().exceptionHandling()
.authenticationEntryPoint(anonymousAuthenticationEntryPoint)//匿名用户访问无权限资源时的异常处理 //匿名用户访问无权限资源时的异常处理
.authenticationEntryPoint(anonymousAuthenticationEntryPoint)
// .accessDeniedHandler(accessDeniedHandler)//登录用户没有权限访问资源 // .accessDeniedHandler(accessDeniedHandler)//登录用户没有权限访问资源
// 登入 // 登入 允许所有用户
.and().formLogin().permitAll()//允许所有用户 .and().formLogin().permitAll()
.successHandler(loginSuccessHandler)//登录成功处理逻辑 //登录成功处理逻辑
.failureHandler(loginFailureHandler)//登录失败处理逻辑 .successHandler(loginSuccessHandler)
//登录失败处理逻辑
.failureHandler(loginFailureHandler)
// 登出 // 登出
.and().logout().logoutUrl("/api/user/logout").permitAll()//允许所有用户 .and().logout().logoutUrl("/api/user/logout").permitAll()
.logoutSuccessHandler(logoutHandler)//登出成功处理逻辑 //登出成功处理逻辑
.logoutSuccessHandler(logoutHandler)
.deleteCookies("JSESSIONID") .deleteCookies("JSESSIONID")
// 会话管理 // 会话管理
// .and().sessionManagement().invalidSessionStrategy(invalidSessionHandler) // 超时处理 // .and().sessionManagement().invalidSessionStrategy(invalidSessionHandler) // 超时处理

View File

@ -1,17 +1,13 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate; import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate;
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.service.IDeviceService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.DateUtil;
import gov.nist.javax.sip.RequestEventExt; import gov.nist.javax.sip.RequestEventExt;
import gov.nist.javax.sip.address.AddressImpl; import gov.nist.javax.sip.address.AddressImpl;
@ -50,15 +46,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
@Autowired @Autowired
private SipConfig sipConfig; private SipConfig sipConfig;
@Autowired
private IRedisCatchStorage redisCatchStorage;
@Autowired
private IVideoManagerStorage storager;
@Autowired
private EventPublisher publisher;
@Autowired @Autowired
private SIPProcessorObserver sipProcessorObserver; private SIPProcessorObserver sipProcessorObserver;
@ -86,7 +73,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
ExpiresHeader expiresHeader = (ExpiresHeader) request.getHeader(Expires.NAME); ExpiresHeader expiresHeader = (ExpiresHeader) request.getHeader(Expires.NAME);
Response response = null; Response response = null;
boolean passwordCorrect = false; boolean passwordCorrect = false;
// 注册标志 0未携带授权头或者密码错误 1注册成功 2注销成功 // 注册标志
boolean registerFlag = false; boolean registerFlag = false;
FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME);
AddressImpl address = (AddressImpl) fromHeader.getAddress(); AddressImpl address = (AddressImpl) fromHeader.getAddress();
@ -105,7 +92,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
// 校验密码是否正确 // 校验密码是否正确
passwordCorrect = StringUtils.isEmpty(sipConfig.getPassword()) || passwordCorrect = StringUtils.isEmpty(sipConfig.getPassword()) ||
new DigestServerAuthenticationHelper().doAuthenticatePlainTextPassword(request, sipConfig.getPassword()); new DigestServerAuthenticationHelper().doAuthenticatePlainTextPassword(request, sipConfig.getPassword());
// 未携带授权头或者密码错误 回复401
if (!passwordCorrect) { if (!passwordCorrect) {
// 注册失败 // 注册失败

View File

@ -64,16 +64,14 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
device.setHostAddress(received.concat(":").concat(String.valueOf(rPort))); device.setHostAddress(received.concat(":").concat(String.valueOf(rPort)));
} }
device.setKeepaliveTime(DateUtil.getNow()); device.setKeepaliveTime(DateUtil.getNow());
// 回复200 OK
responseAck(evt, Response.OK);
if (device.getOnline() == 1) { if (device.getOnline() == 1) {
// 回复200 OK
responseAck(evt, Response.OK);
deviceService.updateDevice(device); deviceService.updateDevice(device);
}else { }else {
// 对于已经离线的设备判断他的注册是否已经过期 // 对于已经离线的设备判断他的注册是否已经过期
if (!deviceService.expire(device)){ if (!deviceService.expire(device)){
deviceService.online(device); deviceService.online(device);
// 回复200 OK
responseAck(evt, Response.OK);
} }
} }
} catch (SipException e) { } catch (SipException e) {

View File

@ -70,15 +70,20 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
rootElement = getRootElement(evt, device.getCharset()); rootElement = getRootElement(evt, device.getCharset());
String sn = getText(rootElement, "SN"); String sn = getText(rootElement, "SN");
RecordInfo recordInfo = new RecordInfo();
recordInfo.setDeviceId(device.getDeviceId());
recordInfo.setSn(sn);
recordInfo.setName(getText(rootElement, "Name"));
String sumNumStr = getText(rootElement, "SumNum"); String sumNumStr = getText(rootElement, "SumNum");
int sumNum = 0; int sumNum = 0;
if (!StringUtils.isEmpty(sumNumStr)) { if (!StringUtils.isEmpty(sumNumStr)) {
sumNum = Integer.parseInt(sumNumStr); sumNum = Integer.parseInt(sumNumStr);
} }
recordInfo.setSumNum(sumNum);
Element recordListElement = rootElement.element("RecordList"); Element recordListElement = rootElement.element("RecordList");
if (recordListElement == null || sumNum == 0) { if (recordListElement == null || sumNum == 0) {
logger.info("无录像数据"); logger.info("无录像数据");
eventPublisher.recordEndEventPush(recordInfo);
recordDataCatch.put(device.getDeviceId(), sn, sumNum, new ArrayList<>()); recordDataCatch.put(device.getDeviceId(), sn, sumNum, new ArrayList<>());
releaseRequest(device.getDeviceId(), sn); releaseRequest(device.getDeviceId(), sn);
} else { } else {
@ -112,6 +117,9 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
record.setRecorderId(getText(itemRecord, "RecorderID")); record.setRecorderId(getText(itemRecord, "RecorderID"));
recordList.add(record); recordList.add(record);
} }
recordInfo.setRecordList(recordList);
// 发送消息如果是上级查询此录像则会通过这里通知给上级
eventPublisher.recordEndEventPush(recordInfo);
int count = recordDataCatch.put(device.getDeviceId(), sn, sumNum, recordList); int count = recordDataCatch.put(device.getDeviceId(), sn, sumNum, recordList);
logger.info("[国标录像] {}->{}: {}/{}", device.getDeviceId(), sn, count, sumNum); logger.info("[国标录像] {}->{}: {}/{}", device.getDeviceId(), sn, count, sumNum);
} }

View File

@ -19,17 +19,16 @@ import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.service.IMediaService;
import com.genersoft.iot.vmp.service.IPlayService;
import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback;
import com.genersoft.iot.vmp.service.bean.PlayBackCallback; import com.genersoft.iot.vmp.service.bean.PlayBackCallback;
import com.genersoft.iot.vmp.service.bean.PlayBackResult; import com.genersoft.iot.vmp.service.bean.PlayBackResult;
import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.service.bean.SSRCInfo;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
import com.genersoft.iot.vmp.service.IMediaService;
import com.genersoft.iot.vmp.service.IPlayService;
import gov.nist.javax.sip.stack.SIPDialog; import gov.nist.javax.sip.stack.SIPDialog;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -43,6 +42,7 @@ import org.springframework.web.context.request.async.DeferredResult;
import javax.sip.ResponseEvent; import javax.sip.ResponseEvent;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*; import java.util.*;
@SuppressWarnings(value = {"rawtypes", "unchecked"}) @SuppressWarnings(value = {"rawtypes", "unchecked"})
@ -63,9 +63,6 @@ public class PlayServiceImpl implements IPlayService {
@Autowired @Autowired
private IRedisCatchStorage redisCatchStorage; private IRedisCatchStorage redisCatchStorage;
@Autowired
private RedisUtil redis;
@Autowired @Autowired
private DeferredResultHolder resultHolder; private DeferredResultHolder resultHolder;
@ -591,7 +588,7 @@ public class PlayServiceImpl implements IPlayService {
BigDecimal currentCount = new BigDecimal(duration/1000); BigDecimal currentCount = new BigDecimal(duration/1000);
BigDecimal totalCount = new BigDecimal(end-start); BigDecimal totalCount = new BigDecimal(end-start);
BigDecimal divide = currentCount.divide(totalCount,2, BigDecimal.ROUND_HALF_UP); BigDecimal divide = currentCount.divide(totalCount,2, RoundingMode.HALF_UP);
double process = divide.doubleValue(); double process = divide.doubleValue();
streamInfo.setProgress(process); streamInfo.setProgress(process);
} }

View File

@ -52,7 +52,7 @@
"postcss-url": "^7.2.1", "postcss-url": "^7.2.1",
"rimraf": "^2.6.0", "rimraf": "^2.6.0",
"semver": "^5.3.0", "semver": "^5.3.0",
"shelljs": "^0.7.6", "shelljs": "^0.8.5",
"uglifyjs-webpack-plugin": "^1.1.1", "uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.8", "url-loader": "^0.5.8",
"vue-loader": "^13.3.0", "vue-loader": "^13.3.0",

View File

@ -605,12 +605,12 @@ export default {
url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' + url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
row.endTime row.endTime
}).then(function (res) { }).then(function (res) {
var streamInfo = res.data; that.streamInfo = res.data;
that.app = streamInfo.app; that.app = that.streamInfo.app;
that.streamId = streamInfo.stream; that.streamId = that.streamInfo.stream;
that.mediaServerId = streamInfo.mediaServerId; that.mediaServerId = that.streamInfo.mediaServerId;
that.ssrc = streamInfo.ssrc; that.ssrc = that.streamInfo.ssrc;
that.videoUrl = that.getUrlByStreamInfo(streamInfo); that.videoUrl = that.getUrlByStreamInfo();
that.recordPlay = true; that.recordPlay = true;
}); });
} }