精华内容
下载资源
问答
  • Java实现GB2312标准的sip下级平台 ...下级平台与上级平台进行保活Java实现GB2312标准的sip下级平台一、sip保活流程二、代码1.引入库2.代码 一、sip保活流程 说明:每个60秒左右,下级平台需要向上级平台进

    Java实现GB28181标准的sip下级平台

    第一章 向上级平台注册

    第二章 下级平台与上级平台进行保活

    第三章 下级平台响应上级平台的资源查询

    第四章 下级平台响应上级平台的实时视频流请求

    第五章 响应上级平台的订阅请求并及进行目录订阅推送

    附:优雅的改变Javax-sip包进行sip通信的编码


    提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


    一、sip保活流程

    说明:每个60秒左右,下级平台需要向上级平台进行保活来确保下级平台在线

    二、代码

    1.引入库

    代码如下(示例):

            <dependency>
                <groupId>javax.sip</groupId>
                <artifactId>jain-sip-ri</artifactId>
                <version>1.3.0-91</version>
            </dependency>
    

    2.代码

    (1)保活请求:

        /**
         * sip平台保活请求信息
         */
        @Override
        public void keepAliveRequest(SipServerInfo sipServerInfo) {
            StringBuffer ptzXml = new StringBuffer(200);
            ptzXml.append("<?xml version=\"1.0\" ?>");
            ptzXml.append("<Notify>");
            ptzXml.append("<CmdType>Keepalive</CmdType>");
            ptzXml.append("<SN>" + 19952 + "</SN>");
            ptzXml.append("<DeviceID>" + sipServerInfo.getSipNoLocal() + "</DeviceID>");
            ptzXml.append("<Status>OK</Status>");
            ptzXml.append("</Notify>");
            try {
                /**
                 * 获取平台请求保活头信息
                 */
                Request request = sipRequestHeaderProvider.createMessageRequest(SequenceNumber.keepAlive,ptzXml.toString(),
                        MessageRequest.keepAliveContentType,MessageRequest.keepAliveContentSubType,sipServerInfo,false,false);
    
                /**
                 * 添加头信息
                 */
                SipFactory sipFactory = SipFactory.getInstance();
                /**
                 * Contact
                 *  在INVITE请求和200 OK响应里面必须存在
                 *  当UA处于防火墙后,该字段内容为防火墙URI,From字段为UA的URI地址
                 *  允许有一个显示用的姓名,由< >封装
                 *
                 * 示例:Contact: <sip:62010201002000000001@10.129.4.21:5080>
                 */
                SipURI contactURI = sipFactory.createAddressFactory().createSipURI(sipServerInfo.getSipNoLocal(), sipConfig.getSipIp() + ":" + sipConfig.getSipPort());
                contactURI.setPort(sipConfig.getSipPort());
                Address contactAddress =  sipFactory.createAddressFactory().createAddress(contactURI);
                ContactHeader contactHeader = sipFactory.createHeaderFactory().createContactHeader(contactAddress);
                request.addHeader(contactHeader);
    
                /**
                 * Expires
                 *  Expires头域给定了消息(或者内容)过期的相关时间
                 *  出现在INVITE消息中,表示UAC的请求有效时间
                 *  出现在REGISTER消息中,表示Contact中URI地址的注册有效时间
                 *示例:Expires: 3600
                 */
                ExpiresHeader expiresHeader = sipFactory.createHeaderFactory().createExpiresHeader(90);
                request.addHeader(expiresHeader);
    
                Header header = sipFactory.createHeaderFactory().createHeader("OutUserInfo","DomainId="+sipServerInfo.getSipNoLocal()+"u;UserName="+sipServerInfo.getSipUserName()+";UserPri=10");
                request.addHeader(header);
                Header header2 = sipFactory.createHeaderFactory().createHeader("User-Agent","IMOS/V3");
                request.addHeader(header2);
    
                /**
                 * 提交请求
                 */
    
                transmitRequest(request,sipServerInfo.getSipNo(), BusinessFlag.keepAlive);
    
            } catch (ParseException e) {
                e.printStackTrace();
            } catch (InvalidArgumentException e) {
                e.printStackTrace();
            } catch (PeerUnavailableException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 提交请求
         * @param request
         * @return
         * @throws SipException
         */
        @Override
        public ClientTransaction transmitRequest(Request request,String tarSipNo,String businessFlag) {
            ClientTransaction clientTransaction = null;
            try{
                if("TCP".equals(sipConfig.getTransMethod().toUpperCase())) {
                    clientTransaction = tcpSipProvider.getNewClientTransaction(request);
                } else if("UDP".equals(sipConfig.getTransMethod().toUpperCase())) {
                    clientTransaction = udpSipProvider.getNewClientTransaction(request);
                }
    
                clientTransaction.sendRequest();
            }catch (SipException e) {
                e.printStackTrace();
            }
            /**
             * 添加发送记录
             */
            CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
            SipSendLog sipSendLog = new SipSendLog();
            sipSendLog.setCallId(callIdHeader.getCallId());
            sipSendLog.setCreateTime(new Date());
            sipSendLog.setBusinessFlag(businessFlag);
            sipSendLog.setSipNo(tarSipNo);
            sipSendLog.setRequestContent(request.toString());
            sipSendLogMapper.insertSipSendLog(sipSendLog);
            System.out.println("请求信息发送: ---------------------------------------------------");
            System.out.println(request.toString());
            System.out.println("---------------------------------------------------------------");
            return clientTransaction;
        }
    

    (2)组装sip通信请求头:

    public Request createMessageRequest(long sequenceNumber, String content, String contentType, String contentSubType, SipServerInfo sipServerInfo,
    										boolean fromHeaderHostIsHasPort,boolean toHeaderHostIsHasPort)
    			throws ParseException, InvalidArgumentException, PeerUnavailableException {
    		/**
    		 * 创建请求头
    		 */
    		String fromHeaderUserName = sipServerInfo.getSipNoLocal();
    		String toHeaderUserName = sipServerInfo.getSipNo();
    		String fromHeaderHost = fromHeaderHostIsHasPort ? (sipConfig.getSipIp() + ":" + sipConfig.getSipPort()+";transport="+sipConfig.getTransMethod().toLowerCase()) :  sipConfig.getSipIp();
    		String toHeaderHost = toHeaderHostIsHasPort ? (sipServerInfo.getSipIp() + ":" + sipServerInfo.getSipPort()+";transport="+sipConfig.getTransMethod().toLowerCase()) : sipServerInfo.getSipIp()+";transport="+sipConfig.getTransMethod().toLowerCase();
    		Request request = createRequestHeader(sequenceNumber,Request.MESSAGE, BusinessFlag.shareDeviceInfoNotify,sipServerInfo,
    				fromHeaderUserName,fromHeaderHost,
    				toHeaderUserName,toHeaderHost
    				);
    
    		/**
    		 * Expires
    		 *  Expires头域给定了消息(或者内容)过期的相关时间
    		 *  出现在INVITE消息中,表示UAC的请求有效时间
    		 *  出现在REGISTER消息中,表示Contact中URI地址的注册有效时间
    		 *示例:Expires: 3600
    		 */
    		ExpiresHeader expiresHeader = sipFactory.createHeaderFactory().createExpiresHeader(90);
    		request.addHeader(expiresHeader);
    		Header header2 = sipFactory.createHeaderFactory().createHeader("User-Agent","IMOS/V3");
    		request.addHeader(header2);
    		ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader(contentType, contentSubType);
    		request.setContent(content, contentTypeHeader);
    		return request;
    	}
    
    
    	/**
    	 * 创建sip通信的请求头
    	 * @param sequenceNumber sip的序列号
    	 * @param method sip请求方法
    	 * @param businessFlag 业务标志
    	 * @return
    	 * @throws PeerUnavailableException
    	 * @throws ParseException
    	 * @throws InvalidArgumentException
    	 */
    	public  Request createRequestHeader(long sequenceNumber, String method,String businessFlag,SipServerInfo sipServerInfo,String fromHeaderUserName,String fromHeaderHost,String toHeaderUserName,String toHeaderHost) throws PeerUnavailableException, ParseException, InvalidArgumentException {
    		/**
    		 * 示例 REGISTER sip: SIP 服务器编码 @ 目的域名或 IP 地址端口 SIP/2.0
    		 */
    		SipURI requestSipURI = sipFactory.createAddressFactory().createSipURI(sipServerInfo.getSipNo(),sipServerInfo.getSipIp()+":"+sipServerInfo.getSipPort());
    		requestSipURI.setTransportParam(sipConfig.getTransMethod());
    
    		/**
    		 * From头域表示了请求的来源地
    		 *  允许有一个显示用的姓名,由< >封装
    		 *  UAC发起的请求必须包含Tag字段,用于标识一个特定的呼叫
    		 * 示例:From: <sip: SIP 设备编码 @ 源域名 >;tag=185326220
    		 */
    		/*sipConfig.getSipNo(),sipConfig.getSipIp() + ":" + sipConfig.getSipPort()*/
    		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(fromHeaderUserName,fromHeaderHost);
    		Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
    		FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, DateUtil.getDateFormat(new Date(),DateUtil.DATETIME_DEFAULT_FORMAT2));
    
    		/**
    		 * TO
    		 *  To头域定义了逻辑上请求的接收者
    		 *  允许有一个显示用的姓名,由< >封装
    		 * tag 可无
    		 * 示例:To: <sip: SIP 设备编码 @ 源域名 >
    		 */
    		/**
    		 * sipConfig.getSipNo(), sipConfig.getSipIp() + ":" + sipConfig.getSipPort()
    		 */
    		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(toHeaderUserName,toHeaderHost);
    		Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
    		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress,null);
    
    		/**
    		 *  Via头域是用来描述请求当前经历的路径,并且标志了应答所应当经过的路径;
    		 *  当UAC创建一个请求,它必须在头域中添加一个Via域;转发请求报文的Proxy在Via头域顶端添加自己的地址,并携带branch ID参数(提供了事务的标志,是Request-URI、To-Tag、From-Tag、Call-ID和CSeq的哈希值)
    		 *  包含协议名、版本号、以及传输层协议(SIP/2.0/UDP, SIP/2.0/TCP, etc.)
    		 *  Via头域必须包含一个分支(branch)参数,用于区分请求创建的事务。根据RFC3261产生的branch ID必须用”z9hG4bK”开头
    		 *
    		 * 示例:Via: SIP/2.0/UDP 源域名或 IP 地址端口
    		 */
    		ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(),
    				sipConfig.getTransMethod(), ViaTagUtil.provideViaTag(businessFlag));
    		List<ViaHeader> viaHeaderList = new ArrayList<>();
    		viaHeaderList.add(viaHeader);
    		//callid,cseq,maxforwards
    		CallIdHeader callIdHeader = sipConfig.getTransMethod().toLowerCase().equals("tcp") ? tcpSipProvider.getNewCallId()
    				: udpSipProvider.getNewCallId();
    		CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(sequenceNumber, method);
    		MaxForwardsHeader maxForwardsHeader = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
    		/**
    		 * 下面我们通过传递先前创建的所有元素来实例化实际的 SIP 消息本身。
    		 */
    
    		/**
    		 * sip工具包中默认字符集为utf-8
    		 * 这里通过调用对象的set方法来设置默认字符集为我们想要的字符集
    		 */
    		gov.nist.javax.sip.message.MessageFactoryImpl messageFactory = (gov.nist.javax.sip.message.MessageFactoryImpl)sipFactory.createMessageFactory();
    		messageFactory.setDefaultContentEncodingCharset(sipConfig.getCharset());
    
    		Request request = sipFactory.createMessageFactory().createRequest(requestSipURI, method, callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaderList, maxForwardsHeader);
    		return request;
    	}
    

    (3)sip监听SipLayer:

    package com.vxdata.sip.siplistener;
    
    import com.vxdata.sip.config.SipConfig;
    import com.vxdata.sip.domain.SipSendLog;
    import com.vxdata.sip.factory.SIPProcessorFactory;
    import com.vxdata.sip.mapper.SipSendLogMapper;
    import gov.nist.javax.sip.SipStackImpl;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.DependsOn;
    import org.springframework.stereotype.Component;
    
    import javax.sip.*;
    import javax.sip.header.CallIdHeader;
    import javax.sip.message.Response;
    import java.util.Date;
    import java.util.Properties;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    @Component
    public class SipLayer implements SipListener {
    
    	private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
    
    	@Autowired
    	private SipConfig sipConfig;
    
    	@Autowired
    	private SIPProcessorFactory processorFactory;
    
    	@Autowired
    	private SipSendLogMapper sipSendLogMapper;
    
    	private SipStack sipStack;
    
    	private SipFactory sipFactory;
    
    	/**   
    	 * 消息处理器线程池
    	 */
    	private ThreadPoolExecutor processThreadPool;
    
    
    	/**
    	 * 创建消息处理线程池
    	 * @return
    	 */
    	@Bean("initSipServer")
    	private ThreadPoolExecutor initSipServer() {
    		int processThreadNum = Runtime.getRuntime().availableProcessors() * 10;
    		/**
    		 * LinkedBlockingQueue是一个单向链表实现的阻塞队列。
    		 * 该队列按 FIFO(先进先出)排序元素,新元素插入到队列的尾部,
    		 * 并且队列获取操作会获得位于队列头部的元素。
    		 * 链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。
    		 */
    		LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<Runnable>(10000);
    		processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum,
    				0L,TimeUnit.MILLISECONDS,processQueue,
    				new ThreadPoolExecutor.CallerRunsPolicy());
    		return processThreadPool;
    	}
    
    	/**
    	 * 获取sip实例并配置sip域名id
    	 * @return
    	 */
    	@Bean("sipFactory")
    	@DependsOn("initSipServer")
    	private SipFactory createSipFactory() {
    		sipFactory = SipFactory.getInstance();
    		/**
    		 * 配置sip域名id
    		 */
    		sipFactory.setPathName("gov.nist");
    		return sipFactory;
    	}
    
    	/**
    	 * 配置sip代理服务器相关参数
    	 * @return
    	 * @throws PeerUnavailableException
    	 */
    	@Bean("sipStack")
    	@DependsOn({"initSipServer", "sipFactory"})
    	private SipStack createSipStack() throws PeerUnavailableException {
    		Properties properties = new Properties();
    		properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
    		properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getSipIp());
    		properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false");
    		properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32");
    		properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_client_log.txt");
    		properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_debug_log.txt");
    		sipStack = (SipStackImpl) sipFactory.createSipStack(properties);
    		return sipStack;
    	}
    
    	@Bean("tcpSipProvider")
    	@DependsOn("sipStack")
    	private SipProvider startTcpListener() throws Exception {
    		ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "TCP");
    		SipProvider tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint);
    		tcpSipProvider.addSipListener(this);
    		logger.info("Sip Client TCP 启动成功 port {" + sipConfig.getSipPort() + "}");
    		return tcpSipProvider;
    	}
    	
    	@Bean("udpSipProvider")
    	@DependsOn("sipStack")
    	private SipProvider startUdpListener() throws Exception {
    		ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "UDP");
    		SipProvider udpSipProvider = sipStack.createSipProvider(udpListeningPoint);
    		udpSipProvider.addSipListener(this);
    		logger.info("Sip Client UDP 启动成功 port {" + sipConfig.getSipPort() + "}");
    		return udpSipProvider;
    	}
    
    	/**
    	 * SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a
    	 * new request arrives.
    	 */
    	@Override
    	public void processRequest(RequestEvent requestEvent) {
    		// 由于jainsip是单线程程序,为提高性能并发处理
    		processThreadPool.execute(() -> {
    			processorFactory.createRequestProcessor(requestEvent).process();
    		});
    	}
    
    	@Override
    	public void processResponse(ResponseEvent responseEvent) {
    		Response response = responseEvent.getResponse();
    		int status = response.getStatusCode();
    		/**
    		 * 修改发送记录状态
    		 */
    		CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME);
    		//获取callId
    		String callId = callIdHeader.getCallId();
    		SipSendLog sipSendLog = new SipSendLog();
    		sipSendLog.setResponseStatus(status);
    		sipSendLog.setResponseContent(response.toString());
    		sipSendLog.setCallId(callId);
    		sipSendLog.setStatus(1);
    		sipSendLog.setUpdateTime(new Date());
    		sipSendLogMapper.updateSipSendLog(sipSendLog);
    
    		System.out.println("-----------------------------------------------");
    		System.out.println("响应信息:");
    		System.out.println(response);
    		System.out.println("-----------------------------------------------");
    
    		if ((status >= 200) && (status < 300)) { // Success!
    			processorFactory.createResponseProcessor(responseEvent);
    		} else if ((status >= 100) && (status < 200)) {
    			// 增加其它无需回复的响应,如101、180等
    		} else {
    			logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase());
    		}
    	}
    
    	/**
    	 * <p>
    	 * Title: processTimeout
    	 * </p>
    	 * <p>
    	 * Description:
    	 * </p>
    	 * 
    	 * @param timeoutEvent
    	 */
    	@Override
    	public void processTimeout(TimeoutEvent timeoutEvent) {
    		// TODO Auto-generated method stub
    
    	}
    
    	/**
    	 * <p>
    	 * Title: processIOException
    	 * </p>
    	 * <p>
    	 * Description:
    	 * </p>
    	 * 
    	 * @param exceptionEvent
    	 */
    	@Override
    	public void processIOException(IOExceptionEvent exceptionEvent) {
    		// TODO Auto-generated method stub
    
    	}
    
    	/**
    	 * <p>
    	 * Title: processTransactionTerminated
    	 * </p>
    	 * <p>
    	 * Description:
    	 * </p>
    	 * 
    	 * @param transactionTerminatedEvent
    	 */
    	@Override
    	public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
    		// TODO Auto-generated method stub
    
    	}
    
    	/**
    	 * <p>
    	 * Title: processDialogTerminated
    	 * </p>
    	 * <p>
    	 * Description:
    	 * </p>
    	 * 
    	 * @param dialogTerminatedEvent
    	 */
    	@Override
    	public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
    		// TODO Auto-generated method stub
    
    	}
    
    }
    
    

    (4)处理响应:

    package com.vxdata.sip.factory;
    
    import com.vxdata.sip.cmd.SipCommand;
    import com.vxdata.sip.request.ISIPRequestProcessor;
    import com.vxdata.sip.request.impl.*;
    import com.vxdata.sip.response.impl.MessageResponseProcessor;
    import com.vxdata.sip.response.impl.RegisterResponseProcessor;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import javax.sip.RequestEvent;
    import javax.sip.ResponseEvent;
    import javax.sip.SipProvider;
    import javax.sip.header.CSeqHeader;
    import javax.sip.message.Request;
    import javax.sip.message.Response;
    import java.text.ParseException;
    
    /**    
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: swwheihei
     * @date:   2020年5月3日 下午4:24:37     
     */
    @Component
    public class SIPProcessorFactory {
    	
    	private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class);
    
    	private RegisterResponseProcessor registerResponseProcessor;
    
    	private MessageResponseProcessor messageResponseProcessor;
    
    	// 注:这里使用注解会导致循环依赖注入,暂用springBean
    	private SipProvider tcpSipProvider;
    		
    	// 注:这里使用注解会导致循环依赖注入,暂用springBean
    	private SipProvider udpSipProvider;
    	
    	public ISIPRequestProcessor createRequestProcessor(RequestEvent evt) {
    		Request request = evt.getRequest();
    		String method = request.getMethod();
    		if (Request.INVITE.equals(method)) {
    			InviteRequestProcessor processor = new InviteRequestProcessor();
    			processor.setRequestEvent(evt);
    			processor.setTcpSipProvider(getTcpSipProvider());
    			processor.setUdpSipProvider(getUdpSipProvider());
    			return processor;
    		} else if (Request.SUBSCRIBE.equals(method)) {
    			SubscribeRequestProcessor processor = new SubscribeRequestProcessor();
    			processor.setTcpSipProvider(getTcpSipProvider());
    			processor.setUdpSipProvider(getUdpSipProvider());
    			processor.setCmd((SipCommand) SpringBeanFactory.getBean("sipCommandImpl"));
    			processor.setRequestEvent(evt);
    			return processor;
    		} else if (Request.ACK.equals(method)) {
    			AckRequestProcessor processor = new AckRequestProcessor();
    			processor.setRequestEvent(evt);
    			return processor;
    		} else if (Request.BYE.equals(method)) {
    			ByeRequestProcessor processor = new ByeRequestProcessor();
    			processor.setRequestEvent(evt);
    			return processor;
    		} else if (Request.MESSAGE.equals(method)) {
    			MessageRequestProcessor processor = new MessageRequestProcessor();
    			processor.setRequestEvent(evt);
    			processor.setTcpSipProvider(getTcpSipProvider());
    			processor.setUdpSipProvider(getUdpSipProvider());
    			processor.setCmd((SipCommand) SpringBeanFactory.getBean("sipCommandImpl"));
    			return processor;
    		} else {
    			OtherRequestProcessor processor = new OtherRequestProcessor();
    			processor.setRequestEvent(evt);
    			return processor;
    		}
    	}
    	
    	public void createResponseProcessor(ResponseEvent responseEvent) {
    
    		registerResponseProcessor  = (RegisterResponseProcessor) SpringBeanFactory.getBean("registerResponseProcessor");
    		messageResponseProcessor 	= (MessageResponseProcessor) SpringBeanFactory.getBean("messageResponseProcessor");
    
    		Response response = responseEvent.getResponse();
    		CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
    		String method = cseqHeader.getMethod();
    		if (Request.REGISTER.equals(method)){
    			try {
    				registerResponseProcessor.process(responseEvent);
    			} catch (ParseException e) {
    				e.printStackTrace();
    			}
    			return ;
    		}else if (Request.MESSAGE.equals(method)){
    			try {
    				messageResponseProcessor.process(responseEvent);
    			} catch (ParseException e) {
    				e.printStackTrace();
    			}
    			return;
    		}
    		return ;
    	}
    	
    	private SipProvider getTcpSipProvider() {
    		if (tcpSipProvider == null) {
    			tcpSipProvider = (SipProvider) SpringBeanFactory.getBean("tcpSipProvider");
    		}
    		return tcpSipProvider;
    	}
    	
    	private SipProvider getUdpSipProvider() {
    		if (udpSipProvider == null) {
    			udpSipProvider = (SipProvider) SpringBeanFactory.getBean("udpSipProvider");
    		}
    		return udpSipProvider;
    	}
    	
    }
    
    
    package com.vxdata.sip.response.impl;
    
    import com.vxdata.sip.domain.SipSendLog;
    import com.vxdata.sip.mapper.SipSendLogMapper;
    import com.vxdata.sip.response.ISIPResponseProcessor;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import javax.sip.ResponseEvent;
    import javax.sip.header.CallIdHeader;
    import javax.sip.message.Response;
    import java.text.ParseException;
    
    @Component
    public class MessageResponseProcessor implements ISIPResponseProcessor {
    
        @Autowired
        private SipSendLogMapper sipSendLogMapper;
    
        @Override
        public void process(ResponseEvent responseEvent) throws ParseException {
            /**
             * 获取消息的内容
             */
            Response response =  responseEvent.getResponse();
            CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME);
            //获取callId
            String callId = callIdHeader.getCallId();
            /**
             * 更新响应
             */
            SipSendLog sipSendLog = new SipSendLog();
            /*sipSendLog.setCallId();*/
    
    
        }
    
    }
    
    
    展开全文
  • Java实现GB2312标准的sip...下级平台响应上级平台的资源查询Java实现GB2312标准的sip下级平台一、下级平台响应上级平台的资源查询流程二、代码1.引入库2.代码 一、下级平台响应上级平台的资源查询流程 说明:上级

    Java实现GB28181标准的sip下级平台

    第一章 向上级平台注册

    第二章 下级平台与上级平台进行保活

    第三章 下级平台响应上级平台的资源查询

    第四章 下级平台响应上级平台的实时视频流请求

    第五章 响应上级平台的订阅请求并及进行目录订阅推送

    附:优雅的改变Javax-sip包进行sip通信的编码


    提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


    一、下级平台响应上级平台的资源查询流程

    说明:上级平台首先会发送目录查询请求,然后下级平台先响应200,响应后进行目录组装进行发送请求。

    二、代码

    1.引入库

    代码如下(示例):

            <dependency>
                <groupId>javax.sip</groupId>
                <artifactId>jain-sip-ri</artifactId>
                <version>1.3.0-91</version>
            </dependency>
    

    2.代码

    (1)识别目录查询请求:

        package com.vxdata.sip.request.impl;
    
    import com.vxdata.common.utils.DateUtils;
    import com.vxdata.sip.cmd.SipCommand;
    import com.vxdata.sip.domain.ResourceInfo;
    import com.vxdata.sip.domain.ServerToResource;
    import com.vxdata.sip.domain.SipCatalogRequestLog;
    import com.vxdata.sip.domain.SipServerInfo;
    import com.vxdata.sip.domain.vo.DeviceChannel;
    import com.vxdata.sip.domain.vo.OtherAsk;
    import com.vxdata.sip.domain.vo.SipInfo;
    import com.vxdata.sip.factory.SpringBeanFactory;
    import com.vxdata.sip.mapper.ResourceInfoMapper;
    import com.vxdata.sip.mapper.ServerToResourceMapper;
    import com.vxdata.sip.mapper.SipCatalogRequestLogMapper;
    import com.vxdata.sip.mapper.SipServerInfoMapper;
    import com.vxdata.sip.request.SIPRequestAbstractProcessor;
    import com.vxdata.sip.util.Conversion;
    import com.vxdata.sip.util.XmlUtil;
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    
    import javax.naming.ldap.PagedResultsControl;
    import javax.sip.InvalidArgumentException;
    import javax.sip.RequestEvent;
    import javax.sip.ServerTransaction;
    import javax.sip.SipException;
    import javax.sip.header.CallIdHeader;
    import javax.sip.header.FromHeader;
    import javax.sip.message.Request;
    import javax.sip.message.Response;
    import java.io.ByteArrayInputStream;
    import java.text.ParseException;
    import java.util.*;
    
    /**    
     * @Description:MESSAGE请求处理器
     * @author: swwheihei
     * @date:   2020年5月3日 下午5:32:41     
     */
    @Component
    public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
    
    	private SipCatalogRequestLogMapper sipCatalogRequestLogMapper;
    
    	private SipServerInfoMapper sipServerInfoMapper;
    
    	private ServerToResourceMapper serverToResourceMapper;
    
    	private ResourceInfoMapper resourceInfoMapper;
    	
    	private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class);
    	
    	private SipCommand cmd;
    
    	Map<Integer, ResourceInfo> resourceInfoMap = new HashMap<>();
    	
    	private final static String CACHE_RECORDINFO_KEY = "CACHE_RECORDINFO_";
    	
    	private static final String MESSAGE_KEEP_ALIVE = "Keepalive";
    	private static final String MESSAGE_CONFIG_DOWNLOAD = "ConfigDownload";
    	private static final String MESSAGE_CATALOG = "Catalog";
    	private static final String MESSAGE_DEVICE_INFO = "DeviceInfo";
    	private static final String MESSAGE_ALARM = "Alarm";
    	private static final String MESSAGE_RECORD_INFO = "RecordInfo";
    	
    	/**   
    	 * 处理MESSAGE请求
    	 *  
    	 * @param requestEvent
    	 */  
    	@Override
    	public void process(RequestEvent requestEvent) {
    		sipCatalogRequestLogMapper = (SipCatalogRequestLogMapper) SpringBeanFactory.getBean("sipCatalogRequestLogMapper");
    		sipServerInfoMapper = (SipServerInfoMapper) SpringBeanFactory.getBean("sipServerInfoMapper");
    		serverToResourceMapper = (ServerToResourceMapper) SpringBeanFactory.getBean("serverToResourceMapper");
    		resourceInfoMapper = (ResourceInfoMapper) SpringBeanFactory.getBean("resourceInfoMapper");
    		try {
    			Element rootElement = getRootElement(requestEvent);
    			String cmd = XmlUtil.getText(rootElement,"CmdType");
    
    			if (MESSAGE_CATALOG.equals(cmd)) {
    				System.out.println("接收到Catalog(目录查询)消息");
    				System.out.println("request: " + requestEvent.getRequest() );
    				processMessageCatalogList(requestEvent);
    			}
    		} catch (DocumentException e) {
    			e.printStackTrace();
    		}
    	}
    
    	/**
    	 * 收到查询目录请求的信息
    	 * @param requestEvent
    	 */
    	private void processMessageCatalogList(RequestEvent requestEvent) throws DocumentException {
    		Request request = requestEvent.getRequest();
    
    		CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
    		FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME);
    		String sipFromUrl = fromHeader.getAddress().getURI().toString();
    		String sipNo = sipFromUrl.substring(sipFromUrl.indexOf(":")+1,sipFromUrl.indexOf("@"));
    		Element rootElement = getRootElement(requestEvent);
    		//平台id
    		String deviceId = rootElement.element("DeviceID").getText();
    		String sn = rootElement.element("SN").getText();
    		/**
    		 * 插入请求记录
    		 */
    		SipCatalogRequestLog sipCatalogRequestLog = new SipCatalogRequestLog();
    		sipCatalogRequestLog.setCallId(callIdHeader.getCallId());
    		sipCatalogRequestLog.setSipNo(sipNo);
    		sipCatalogRequestLog.setRequestTime(new Date());
    		sipCatalogRequestLog.setSn(sn);
    		sipCatalogRequestLog.setRequestType(1);//目录查询请求
    		sipCatalogRequestLogMapper.insertSipCatalogRequestLog(sipCatalogRequestLog);
    
    		/**
    		 * 应答目录查询请求
    		 */
    		Response response = null;
    		try {
    			response = getMessageFactory().createResponse(Response.OK, request);
    			ServerTransaction transaction = getServerTransaction(requestEvent);
    			System.out.println("response(目录查询请求响应)" + response.toString());
    			if (transaction != null) {
    				transaction.sendResponse(response);
    				transaction.terminate();
    			} else {
    				System.out.println("processRequest serverTransactionId is null.");
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    			return;
    		}
    
    		/**
    		 * 查询分享目录信息
    		 */
    
    		/**
    		 * 分享目录
    		 */
    		SipServerInfo sipServerInfo = sipServerInfoMapper.selectSipServerInfoBySipNo(sipNo);
    
    		/**
    		 * 根据serverId 查询该sip服务器的共享目录信息
    		 */
    		ServerToResource queryServer = new ServerToResource();
    		queryServer.setServiceId(sipServerInfo.getId());
    		List<ServerToResource> serverToResources = serverToResourceMapper.selectServerToResourceList(queryServer);
    		if (serverToResources != null && serverToResources.size() >0){
    			int sunNum  = serverToResources.size() * 3 ;
    			StringBuilder sqlStr = new StringBuilder();
    			int init = 0;
    			sqlStr.append("r.id in (");
    			for (ServerToResource serverToResource :serverToResources){
    				if (init != 0){
    					sqlStr.append(",");
    				}else {
    					init ++ ;
    				}
    				sqlStr.append(serverToResource.getCatalogId()+","+serverToResource.getCameraIds());
    			}
    			sqlStr.append(")");
    			HashMap<String, Object> params = new HashMap<>();
    			params.put("sqlStr", sqlStr.toString());
    			ResourceInfo queryResourceInfo = new ResourceInfo();
    			queryResourceInfo.setParams(params);
    			List<ResourceInfo> resourceInfoList = resourceInfoMapper.selectResourceInfoList(queryResourceInfo);
    			if (resourceInfoList != null && resourceInfoList.size() > 0) {
    				resourceInfoList.forEach(rs -> {
    					resourceInfoMap.put(rs.getId(),rs);
    				});
    			}
    
    			/**
    			 * 组装目录发送信息
    			 */
    			for (ServerToResource serverToResource : serverToResources)
    			{
    				assemblyResponse(serverToResource.getCatalogId(),serverToResource.getCameraIds().split(","),serverToResources.size()*3,sipServerInfo,sipCatalogRequestLog);
    			}
    		}
    	}
    	
    	private void responseAck(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
    		Response response = getMessageFactory().createResponse(Response.OK,evt.getRequest());
    		getServerTransaction(evt).sendResponse(response);
    	}
    	
    	private Element getRootElement(RequestEvent evt) throws DocumentException {
    		Request request = evt.getRequest();
    		SAXReader reader = new SAXReader();
    		reader.setEncoding("gbk");
    		Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
    		return xml.getRootElement();
    	}
    
    	public void setCmd(SipCommand cmd) {
    		this.cmd = cmd;
    	}
    
    	public void assemblyResponse(int catalogId , String[] cameraIds , int sumNum , SipServerInfo sipServerInfo , SipCatalogRequestLog sipCatalogRequestLog){
    
    		ResourceInfo catalogInfo = resourceInfoMap.get(catalogId);
    		List<ResourceInfo> cameras = new ArrayList<>();
    		/**
    		 * 注意:相机可能存在搜不到的情况
    		 */
    		for (String cameraId : cameraIds){
    			ResourceInfo camera = resourceInfoMap.get(Integer.parseInt(cameraId));
    			if (camera != null){
    				cameras.add(camera);
    			}
    		}
    
    		/**
    		 * 目录1
    		 */
    		List<DeviceChannel> deviceChannelList2 = new ArrayList<>();
    		DeviceChannel deviceChannel2 = new DeviceChannel();
    		deviceChannel2.setChannelId(catalogInfo.getChannelId());
    		deviceChannel2.setParentId(sipServerInfo.getSipNoLocal());
    		deviceChannel2.setName(catalogInfo.getName());
    		deviceChannel2.setCivilCode(catalogInfo.getCivilCode());
    		deviceChannelList2.add(deviceChannel2);
    		OtherAsk otherAsk2 = new OtherAsk();
    		otherAsk2.setAdd(false);
    		otherAsk2.setCsq(5736);
    		otherAsk2.setSn(2);
    		otherAsk2.setProvide(false);
    		cmd.sendCatalogRequest(sipServerInfo,deviceChannelList2,sipCatalogRequestLog,sumNum,otherAsk2);
    
    		/**
    		 * 目录2
    		 */
    		List<DeviceChannel> deviceChannelList1 = new ArrayList<>();
    		DeviceChannel deviceChannel1 = new DeviceChannel();
    		deviceChannel1.setChannelId(catalogInfo.getChannelId());
    		deviceChannel1.setParentId(sipServerInfo.getSipNo());
    		deviceChannel1.setName(catalogInfo.getName());
    		deviceChannel1.setCivilCode(catalogInfo.getCivilCode());
    		deviceChannelList1.add(deviceChannel1);
    		OtherAsk otherAsk1 = new OtherAsk();
    		otherAsk1.setAdd(false);
    		otherAsk1.setCsq(5735);
    		otherAsk1.setSn(2);
    		otherAsk1.setProvide(true);
    		cmd.sendCatalogRequest(sipServerInfo,deviceChannelList1,sipCatalogRequestLog,sumNum,otherAsk1);
    
    		/**
    		 * 相机信息
    		 */
    		List<DeviceChannel> deviceChannelList = new ArrayList<>();
    		for (ResourceInfo camera : cameras){
    			DeviceChannel deviceChannel = new DeviceChannel();
    			deviceChannel.setChannelId(camera.getChannelId());
    			deviceChannel.setName(camera.getName());
    			deviceChannel.setManufacture(camera.getManufacture());
    			deviceChannel.setModel(camera.getModel());
    			deviceChannel.setOwner(camera.getOwner());
    			deviceChannel.setCivilCode(camera.getCivilCode());
    			deviceChannel.setBlock(camera.getBlock());
    			deviceChannel.setAddress(camera.getAddress());
    			deviceChannel.setParental(camera.getParental());
    			deviceChannel.setParentId(camera.getParentId());
    			deviceChannel.setSafetyWay(camera.getSafetyWay());
    			deviceChannel.setRegisterWay(camera.getRegisterWay());
    			deviceChannel.setCertNum(camera.getCertNum());
    			deviceChannel.setCertifiable(camera.getCertifiable());
    			deviceChannel.setErrCode(camera.getErrCode());
    			deviceChannel.setEndTime(DateUtils.parseDateToStr("yyyy-MM-dd'T'HH:mm:ss",camera.getEndTime()));
    			deviceChannel.setSecrecy(camera.getSecrecy());
    			deviceChannel.setIpAddress(camera.getIpAddress());
    			deviceChannel.setPort(camera.getPort());
    			deviceChannel.setPassword(camera.getPassword());
    			deviceChannel.setStatus(camera.getStatus());
    			deviceChannelList.add(deviceChannel);
    		}
    		OtherAsk otherAsk = new OtherAsk();
    		otherAsk.setAdd(true);
    		otherAsk.setCsq(5735);
    		otherAsk.setSn(3);
    		otherAsk.setProvide(true);
    		cmd.sendCatalogRequest(sipServerInfo,deviceChannelList,sipCatalogRequestLog,sumNum,otherAsk);
    	}
    
    }
    
    
    展开全文
  • Java实现GB2312标准的sip...下级平台响应上级平台的实时视频流请求Java实现GB2312标准的sip下级平台一、下级平台响应上级平台的实时视频流请求流程二、代码1.引入库2.代码 一、下级平台响应上级平台的实时视频流请求

    Java实现GB28181标准的sip下级平台

    第一章 向上级平台注册

    第二章 下级平台与上级平台进行保活

    第三章 下级平台响应上级平台的资源查询

    第四章 下级平台响应上级平台的实时视频流请求

    第五章 响应上级平台的订阅请求并及进行目录订阅推送

    附:优雅的改变Javax-sip包进行sip通信的编码


    提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


    一、下级平台响应上级平台的实时视频流请求流程

    说明:上级平台首先会发送invite请求,然后下级平台先响应200,响应后进行目录组装进行发送请求。
    在这里插入图片描述

    二、代码

    1.引入库

    代码如下(示例):

            <dependency>
                <groupId>javax.sip</groupId>
                <artifactId>jain-sip-ri</artifactId>
                <version>1.3.0-91</version>
            </dependency>
    

    2.代码

    (1)识别请求:

      package com.vxdata.sip.factory;
    
    import com.vxdata.sip.cmd.SipCommand;
    import com.vxdata.sip.request.ISIPRequestProcessor;
    import com.vxdata.sip.request.impl.*;
    import com.vxdata.sip.response.impl.MessageResponseProcessor;
    import com.vxdata.sip.response.impl.RegisterResponseProcessor;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import javax.sip.RequestEvent;
    import javax.sip.ResponseEvent;
    import javax.sip.SipProvider;
    import javax.sip.header.CSeqHeader;
    import javax.sip.message.Request;
    import javax.sip.message.Response;
    import java.text.ParseException;
    
    /**    
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: swwheihei
     * @date:   2020年5月3日 下午4:24:37     
     */
    @Component
    public class SIPProcessorFactory {
    	
    	private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class);
    
    	private RegisterResponseProcessor registerResponseProcessor;
    
    	private MessageResponseProcessor messageResponseProcessor;
    
    	// 注:这里使用注解会导致循环依赖注入,暂用springBean
    	private SipProvider tcpSipProvider;
    		
    	// 注:这里使用注解会导致循环依赖注入,暂用springBean
    	private SipProvider udpSipProvider;
    	
    	public ISIPRequestProcessor createRequestProcessor(RequestEvent evt) {
    		Request request = evt.getRequest();
    		String method = request.getMethod();
    		if (Request.INVITE.equals(method)) {
    			InviteRequestProcessor processor = new InviteRequestProcessor();
    			processor.setRequestEvent(evt);
    			processor.setTcpSipProvider(getTcpSipProvider());
    			processor.setUdpSipProvider(getUdpSipProvider());
    			return processor;
    		} else if (Request.SUBSCRIBE.equals(method)) {
    			SubscribeRequestProcessor processor = new SubscribeRequestProcessor();
    			processor.setTcpSipProvider(getTcpSipProvider());
    			processor.setUdpSipProvider(getUdpSipProvider());
    			processor.setCmd((SipCommand) SpringBeanFactory.getBean("sipCommandImpl"));
    			processor.setRequestEvent(evt);
    			return processor;
    		} else if (Request.ACK.equals(method)) {
    			AckRequestProcessor processor = new AckRequestProcessor();
    			processor.setRequestEvent(evt);
    			return processor;
    		} else if (Request.BYE.equals(method)) {
    			ByeRequestProcessor processor = new ByeRequestProcessor();
    			processor.setRequestEvent(evt);
    			return processor;
    		} else if (Request.MESSAGE.equals(method)) {
    			MessageRequestProcessor processor = new MessageRequestProcessor();
    			processor.setRequestEvent(evt);
    			processor.setTcpSipProvider(getTcpSipProvider());
    			processor.setUdpSipProvider(getUdpSipProvider());
    			processor.setCmd((SipCommand) SpringBeanFactory.getBean("sipCommandImpl"));
    			return processor;
    		} else {
    			OtherRequestProcessor processor = new OtherRequestProcessor();
    			processor.setRequestEvent(evt);
    			return processor;
    		}
    	}
    	
    	public void createResponseProcessor(ResponseEvent responseEvent) {
    
    		registerResponseProcessor  = (RegisterResponseProcessor) SpringBeanFactory.getBean("registerResponseProcessor");
    		messageResponseProcessor 	= (MessageResponseProcessor) SpringBeanFactory.getBean("messageResponseProcessor");
    
    		Response response = responseEvent.getResponse();
    		CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
    		String method = cseqHeader.getMethod();
    		if (Request.REGISTER.equals(method)){
    			try {
    				registerResponseProcessor.process(responseEvent);
    			} catch (ParseException e) {
    				e.printStackTrace();
    			}
    			return ;
    		}else if (Request.MESSAGE.equals(method)){
    			try {
    				messageResponseProcessor.process(responseEvent);
    			} catch (ParseException e) {
    				e.printStackTrace();
    			}
    			return;
    		}
    		return ;
    	}
    	
    	private SipProvider getTcpSipProvider() {
    		if (tcpSipProvider == null) {
    			tcpSipProvider = (SipProvider) SpringBeanFactory.getBean("tcpSipProvider");
    		}
    		return tcpSipProvider;
    	}
    	
    	private SipProvider getUdpSipProvider() {
    		if (udpSipProvider == null) {
    			udpSipProvider = (SipProvider) SpringBeanFactory.getBean("udpSipProvider");
    		}
    		return udpSipProvider;
    	}
    	
    }
    
    

    (2)invite请求处理:

    package com.vxdata.sip.request.impl;
    
    
    import com.vxdata.sip.config.SdkConfig;
    import com.vxdata.sip.config.SipConfig;
    import com.vxdata.sip.domain.ResourceInfo;
    import com.vxdata.sip.domain.SipCatalogRequestLog;
    import com.vxdata.sip.domain.SipInviteInfo;
    import com.vxdata.sip.domain.vo.DeviceChannel;
    import com.vxdata.sip.domain.vo.InviteChannel;
    import com.vxdata.sip.factory.SpringBeanFactory;
    import com.vxdata.sip.mapper.ResourceInfoMapper;
    import com.vxdata.sip.mapper.SipCatalogRequestLogMapper;
    import com.vxdata.sip.mapper.SipInviteInfoMapper;
    import com.vxdata.sip.request.SIPRequestAbstractProcessor;
    import com.vxdata.sip.util.NetUtils;
    import com.vxdata.sip.util.RandomTest;
    import com.vxdata.sip.util.SdpUtil;
    
    import javax.sdp.SdpException;
    import javax.sip.*;
    import javax.sip.address.Address;
    import javax.sip.address.SipURI;
    import javax.sip.header.CallIdHeader;
    import javax.sip.header.ContactHeader;
    import javax.sip.header.ContentTypeHeader;
    import javax.sip.message.Request;
    import javax.sip.message.Response;
    import java.io.UnsupportedEncodingException;
    import java.text.ParseException;
    import java.util.Date;
    
    /**    
     * @Description:处理INVITE请求
     * @author: swwheihei
     * @date:   2020年5月3日 下午4:43:52     
     */
    public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
    
    	private SipConfig sipConfig;
    
    
    	private SipCatalogRequestLogMapper sipCatalogRequestLogMapper;
    
    	private SipInviteInfoMapper sipInviteInfoMapper;
    
    	private ResourceInfoMapper resourceInfoMapper;
    
    	/**
    	 * 处理invite请求
    	 * 
    	 * @param requestEvent
    	 * 请求消息
    	 */ 
    	@Override
    	public void process(RequestEvent requestEvent) {
    		System.out.println("--------------------------------------------------------------");
    		System.out.println("Invite请求:" + evt.getRequest().getMethod());
    		System.out.println(evt.getRequest());
    		System.out.println("--------------------------------------------------------------");
    		sipConfig = (SipConfig) SpringBeanFactory.getBean("sipConfig");
    		sipCatalogRequestLogMapper = (SipCatalogRequestLogMapper) SpringBeanFactory.getBean("sipCatalogRequestLogMapper");
    		sipInviteInfoMapper = (SipInviteInfoMapper) SpringBeanFactory.getBean("sipInviteInfoMapper");
    		resourceInfoMapper = (ResourceInfoMapper) SpringBeanFactory.getBean("resourceInfoMapper");
    		Request request = requestEvent.getRequest();
    		CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
    
    
            /**
             * 根据国标编码查询相机信息
    		 */
    		DeviceChannel deviceChannel = new DeviceChannel();
    
    		//相机发送端口
    		String sourcePort =  provideSourcePort();
    
    		InviteChannel inviteChannel = null;
    		try {
    			//获取invite请求中sdp报文信息
    			 inviteChannel = SdpUtil.getSdpInfo(requestEvent.getRequest());
    			//插入invite请求信息
    			SipInviteInfo sipInviteInfo = new SipInviteInfo();
    			sipInviteInfo.setCallId(callIdHeader.getCallId());
    			sipInviteInfo.setCameraNo(inviteChannel.getSendSipNo());
    			sipInviteInfo.setSendIp(inviteChannel.getSuperIp());
    			sipInviteInfo.setSendPort(String.valueOf(inviteChannel.getSuperPort()));
    			sipInviteInfo.setCreateTime(new Date());
    			//相机从哪个端口发送
    			sipInviteInfo.setSourcePort(sourcePort);
    
    			//判断是否已经插入,保证同一个callId 只插入一条
    			SipInviteInfo querySipInviteInfo = sipInviteInfoMapper.selectSipInviteInfoByCallId(callIdHeader.getCallId());
    			if (querySipInviteInfo == null){
    				sipInviteInfoMapper.insertSipInviteInfo(sipInviteInfo);
    			}else {
    				sipInviteInfoMapper.updateSipInviteInfo(sipInviteInfo);
    			}
    
    
    
    			/**
    			 * 根据国标编码查询相机信息
    			 */
    			ResourceInfo resourceInfo =resourceInfoMapper.selectResourceInfoByChannelId(inviteChannel.getSendSipNo());
    			deviceChannel.setChannelId(resourceInfo.getChannelId());
    			deviceChannel.setIpAddress(resourceInfo.getAddress());
    			deviceChannel.setPort(Integer.parseInt(sourcePort));
    
    		} catch (SdpException e) {
    			e.printStackTrace();
    		} catch (UnsupportedEncodingException e) {
    			e.printStackTrace();
    		}
    		/**
    		 * 回应100状态 trying
    		 */
    		Response response = null;
    		try {
    			response = getMessageFactory().createResponse(Response.TRYING, request);
    			ServerTransaction transaction = getServerTransaction(requestEvent);
    			System.out.println("--------------------------------------------------------------");
    			System.out.println("invite请求响应--trying");
    			System.out.println(response.toString());
    			System.out.println("--------------------------------------------------------------");
    			if (transaction != null) {
    				transaction.sendResponse(response);
    				transaction.terminate();
    			} else {
    				System.out.println("processRequest serverTransactionId is null.");
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    			return;
    		}
    
    		/**
    		 *回应200
    		 */
    		try {
    			response = getMessageFactory().createResponse(Response.OK, request);
    			ServerTransaction transaction = getServerTransaction(requestEvent);
    			addHeadersAndContent(response,request,deviceChannel,inviteChannel);
    			System.out.println("--------------------------------------------------------------");
    			System.out.println("invite请求响应--ok");
    			System.out.println(response.toString());
    			System.out.println("--------------------------------------------------------------");
    			if (transaction != null) {
    				transaction.sendResponse(response);
    				transaction.terminate();
    			} else {
    				System.out.println("processRequest serverTransactionId is null.");
    			}
    
    		} catch (Exception e) {
    			e.printStackTrace();
    			return;
    		}
    
    
            /**
             * 更新请求状态
    		 */
    		SipCatalogRequestLog updateSipCatalogRequestLog = new SipCatalogRequestLog();
    		updateSipCatalogRequestLog.setStatus(1);
    		updateSipCatalogRequestLog.setCallId(callIdHeader.getCallId());
    		sipCatalogRequestLogMapper.updateSipCatalogRequestLog(updateSipCatalogRequestLog);
    	}
    
    	public void addHeadersAndContent(Response response,Request request,DeviceChannel deviceChannel,InviteChannel inviteChannel){
    
    		StringBuffer content = new StringBuffer(200);
    		content.append("v=0\r\n");
    		content.append("o="+deviceChannel.getChannelId()+" 0 0 IN IP4 "+deviceChannel.getIpAddress()+"\r\n");
    		content.append("s=Play\r\n");
    		content.append("c=IN IP4 "+deviceChannel.getIpAddress()+"\r\n");
    		content.append("t=0 0\r\n");
    		if("TCP".equals(sipConfig.getTransMethod().toUpperCase())) {
    			content.append("m=video "+deviceChannel.getPort()+" TCP/RTP/AVP 96\r\n");
    		}
    		if("UDP".equals(sipConfig.getTransMethod().toUpperCase())) {
    			content.append("m=video "+deviceChannel.getPort()+" RTP/AVP 96\r\n");
    		}
    		content.append("a=sendonly\r\n");
    		content.append("a=rtpmap:96 PS/90000\r\n");
    		if("TCP".equals(sipConfig.getTransMethod().toUpperCase())){
    			content.append("a=setup:passive\r\n");
    			content.append("a=connection:new\r\n");
    		}
    		content.append("y="+ inviteChannel.getY() +"\r\n");
    		content.append("f=v/2/4/25/1/2000a/1/8/1\r\n");//ssrc
    		try {
    			SipFactory sipFactory = SipFactory.getInstance();
    			ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "SDP");
    			response.setContent(content, contentTypeHeader);
    
    			SipURI contactURI = sipFactory.createAddressFactory().createSipURI(deviceChannel.getChannelId(), sipConfig.getSipIp() + ":" + sipConfig.getSipPort());
    			contactURI.setPort(sipConfig.getSipPort());
    			Address  contactAddress =  sipFactory.createAddressFactory().createAddress(contactURI);
    			ContactHeader contactHeader = sipFactory.createHeaderFactory().createContactHeader(contactAddress);
    			response.addHeader(contactHeader);
    
    		} catch (ParseException e) {
    			e.printStackTrace();
    		} catch (PeerUnavailableException e) {
    			e.printStackTrace();
    		}
    
    	}
    
    	//随机生成相机发送端口号
    	public String provideSourcePort(){
    		boolean flag = true;
    		Integer port = null;
    		while (flag){
    			//在给定的端口范围内随机生成端口号
    			port = RandomTest.createRandomKey(sipConfig.getMinPort(),sipConfig.getMaxPort());
    			//判断是否占用
    			if (!NetUtils.isLocalPortUsing(port)){
    				flag = false;
    			}
    		}
    		return String.valueOf(port);
    	}
    
    }
    
    
    package com.vxdata.sip.util;
    
    import com.vxdata.sip.domain.vo.InviteChannel;
    
    import javax.sdp.*;
    import javax.sip.header.ContentLengthHeader;
    import javax.sip.header.ContentTypeHeader;
    import javax.sip.header.SubjectHeader;
    import javax.sip.message.Request;
    import java.io.UnsupportedEncodingException;
    import java.util.List;
    import java.util.Vector;
    
    public class SdpUtil {
        private SdpFactory sdpFactory;
    
        public static InviteChannel getSdpInfo(Request request) throws SdpException, UnsupportedEncodingException {
            InviteChannel inviteChannel = new InviteChannel();
            SubjectHeader subjectHeader = (SubjectHeader) request.getHeader(SubjectHeader.NAME);
            String subjectHeaderStr = subjectHeader.getSubject();
            String sendSipNo = subjectHeaderStr.split(",")[0].split(":")[0];
            String sendSerial = subjectHeaderStr.split(",")[0].split(":")[1];
    
            ContentTypeHeader contentType = (ContentTypeHeader) request.getHeader(ContentTypeHeader.NAME);
            ContentLengthHeader contentLen = (ContentLengthHeader) request.getHeader(ContentLengthHeader.NAME);
            if ( contentLen.getContentLength() > 0 && contentType.getContentSubType().toLowerCase().equals("sdp") ){
                String charset = null;
    
                if (contentType != null)
                    charset = contentType.getParameter("charset");
                if (charset == null)
                    charset = "UTF-8"; // RFC 3261
    
                //Save the SDP content in a String
                byte[] rawContent = request.getRawContent();
                String sdpContent = new String(rawContent, charset);
                String y =  sdpContent.substring(sdpContent.lastIndexOf('y')+2);
                inviteChannel.setY(y);
                sdpContent = sdpContent.substring(0,sdpContent.lastIndexOf('y'));
    
                //Use the static method of SdpFactory to parse the content
                SdpFactory sdpFactory = SdpFactory.getInstance();
                SessionDescription sessionDescription = sdpFactory.createSessionDescription(sdpContent);
                Origin origin = sessionDescription.getOrigin();
                SessionName sessionName = sessionDescription.getSessionName();
                Connection connection = sessionDescription.getConnection();
                List<MediaDescription> mediaDescription = sessionDescription.getMediaDescriptions(false);
                Vector<Attribute> attributes = mediaDescription.get(0).getAttributes(false);
                for (Attribute attribute : attributes){
                    String value = attribute.getValue();
                    if (value != null && value.contains("PS")){
                        String a = value.substring(value.indexOf(' ')+1,value.indexOf('/'));
                        if ("PS".equals(a)){
                            inviteChannel.setPtValue(Integer.parseInt(value.substring(0,value.indexOf(' '))));
                        }
                    }
                }
                inviteChannel.setSendSipNo(sendSipNo);
                inviteChannel.setSendMediaSerial(sendSerial);
                inviteChannel.setRequestMethod(sessionName.getValue());
                inviteChannel.setSuperIp(connection.getAddress());
                inviteChannel.setSuperPort(mediaDescription.get(0).getMedia().getMediaPort());
                inviteChannel.setTransportMethod(mediaDescription.get(0).getMedia().getProtocol());
                System.out.println("sdp请求信息: " );
                System.out.println(inviteChannel.toString());
            } else {
                System.out.println("It is not a SDP content");
            }
            return  inviteChannel;
        }
    
        public static void main(String[] args) throws SdpException {
            String sdpContent = "v=0\n" +
                    "o=32059400001320999986 0 0 IN IP4 192.168.20.208\n" +
                    "s=Play\n" +
                    "c=IN IP4 192.168.20.208\n" +
                    "t=0 0\n" +
                    "m=video 5158 RTP/AVP 96 97 98\n" +
                    "a=rtpmap:96 PS/90000\n" +
                    "a=rtpmap:97 MPEG4/90000\n" +
                    "a=rtpmap:98 H264/90000\n" +
                    "a=recvonly\n" +
                    "a=streamMode:SUB\n" +
                    "a=filesize:0\n" +
                    "y=0999999999";
            sdpContent = sdpContent.substring(0,sdpContent.indexOf("y="));
            System.out.println(sdpContent.indexOf("y="));
            SdpFactory sdpFactory = SdpFactory.getInstance();
            SessionDescription sessionDescription = sdpFactory.createSessionDescription(sdpContent);
    
            Origin origin = sessionDescription.getOrigin();
            SessionName sessionName = sessionDescription.getSessionName();
            Connection connection = sessionDescription.getConnection();
            String ip = connection.getAddress();
            List<MediaDescription> mediaDescription = sessionDescription.getMediaDescriptions(false);
            System.out.println();
            Vector<Attribute> attributes = mediaDescription.get(0).getAttributes(false);
            for (Attribute attribute : attributes){
                String value = attribute.getValue();
                if (value != null){
                    String a = value.substring(value.indexOf(' ')+1,value.indexOf('/'));
                    if ("PS".equals(a)){
                        System.out.println(a +"  "+ value.substring(0,value.indexOf(' ')));
                    }
                }
            }
    /*        String subjectHeaderStr = "62010201001310000033:0,62010000002000000001:0";
            String targetSip1 = subjectHeaderStr.split(",")[0].split(":")[0];
            String targetSip2 = subjectHeaderStr.split(",")[0].split(":")[1];
            String targetSip3 = subjectHeaderStr.split(",")[1].split(":")[0];
            String targetSip4 = subjectHeaderStr.split(",")[1].split(":")[1];
            System.out.println(targetSip1);
            System.out.println(targetSip2);
            System.out.println(targetSip3);
            System.out.println(targetSip4);*/
        }
     }
    
    

    (3)Ack请求处理:

    package com.vxdata.sip.request.impl;
    
    import com.vxdata.sip.domain.ResourceInfo;
    import com.vxdata.sip.domain.SipInviteInfo;
    import com.vxdata.sip.domain.vo.SdkCameraVo;
    import com.vxdata.sip.factory.SpringBeanFactory;
    import com.vxdata.sip.mapper.ResourceInfoMapper;
    import com.vxdata.sip.mapper.SipInviteInfoMapper;
    import com.vxdata.sip.request.SIPRequestAbstractProcessor;
    import com.vxdata.sip.service.ISdkService;
    
    import javax.sip.RequestEvent;
    import javax.sip.header.CallIdHeader;
    import java.util.Date;
    
    /**    
     * @Description:ACK请求处理器  
     * @author: swwheihei
     * @date:   2020年5月3日 下午5:31:45     
     */
    public class AckRequestProcessor extends SIPRequestAbstractProcessor {
    	
    	/**   
    	 * 处理  ACK请求
    	 * 
    	 * @param evt
    	 */  
    	@Override
    	public void process(RequestEvent evt) {
    		System.out.println("--------------------------------------------------------------");
    		System.out.println("Ack请求:" + evt.getRequest().getMethod());
    		System.out.println(evt.getRequest());
    		System.out.println("--------------------------------------------------------------");
    		CallIdHeader callIdHeader = (CallIdHeader) evt.getRequest().getHeader(CallIdHeader.NAME);
    
    		SipInviteInfoMapper sipInviteInfoMapper = (SipInviteInfoMapper) SpringBeanFactory.getBean("sipInviteInfoMapper");
    		ISdkService sdkService = (ISdkService) SpringBeanFactory.getBean("sdkServiceImpl");
    		ResourceInfoMapper resourceInfoMapper = (ResourceInfoMapper) SpringBeanFactory.getBean("resourceInfoMapper");
    
    		/**
    		 * 根据call_id查询invite请求信息
    		 */
    		SipInviteInfo sipInviteInfo = sipInviteInfoMapper.selectSipInviteInfoByCallId(callIdHeader.getCallId());
    		if (sipInviteInfo !=null ){
    			/**
    			 * 根据相机国标编号查找相机信息
    			 */
    			ResourceInfo resourceInfo = resourceInfoMapper.selectResourceInfoByChannelId(sipInviteInfo.getCameraNo());
    			if (resourceInfo != null){
    				SdkCameraVo sdkCameraVo = new SdkCameraVo();
    				sdkCameraVo.setCamera(resourceInfo.getOtherId());
    				sdkCameraVo.setSourcePort(Integer.parseInt(sipInviteInfo.getSourcePort()));
    				sdkCameraVo.setTargetIp(sipInviteInfo.getSendIp());
    				sdkCameraVo.setTargetPort(Integer.parseInt(sipInviteInfo.getSendPort()));
    				/**
    				 * 调用相机推流接口
    				 */
    				String closeNo = sdkService.pushStream(sdkCameraVo);
    				sipInviteInfo.setCloseNo(closeNo);
    				sipInviteInfo.setUpdateTime(new Date());
    				sipInviteInfoMapper.updateSipInviteInfo(sipInviteInfo);
    			}
    		}
    
    	}
    
    }
    
    

    (4)Bye请求处理:

    package com.vxdata.sip.request.impl;
    
    
    import com.vxdata.sip.domain.ResourceInfo;
    import com.vxdata.sip.domain.SipInviteInfo;
    import com.vxdata.sip.domain.vo.SdkCameraVo;
    import com.vxdata.sip.factory.SpringBeanFactory;
    import com.vxdata.sip.mapper.ResourceInfoMapper;
    import com.vxdata.sip.mapper.SipInviteInfoMapper;
    import com.vxdata.sip.request.SIPRequestAbstractProcessor;
    import com.vxdata.sip.service.ISdkService;
    
    import javax.sip.RequestEvent;
    import javax.sip.ServerTransaction;
    import javax.sip.header.CallIdHeader;
    import javax.sip.message.Response;
    
    /**    
     * @Description: BYE请求处理器
     * @author: swwheihei
     * @date:   2020年5月3日 下午5:32:05     
     */
    public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
    
    	/**   
    	 * 处理BYE请求
    	 * 
    	 * @param requestEvent
    	 */  
    	@Override
    	public void process(RequestEvent requestEvent) {
    		// TODO 优先级99 Bye Request消息实现,此消息一般为级联消息,上级给下级发送视频停止指令
    		/**
    		 * 停止推送
    		 */
    
    		/**
    		 * 响应
    		 */
    		/**
    		 * 应答目录查询请求
    		 */
    		Response response = null;
    		try {
    			response = getMessageFactory().createResponse(Response.OK, requestEvent.getRequest());
    			ServerTransaction transaction = getServerTransaction(requestEvent);
    			System.out.println("--------------------------------------------------------------");
    			System.out.println("Bye请求响应");
    			System.out.println(response.toString());
    			System.out.println("--------------------------------------------------------------");
    			if (transaction != null) {
    				transaction.sendResponse(response);
    				transaction.terminate();
    			} else {
    				System.out.println("processRequest serverTransactionId is null.");
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    			return;
    		}
    		CallIdHeader callIdHeader = (CallIdHeader) requestEvent.getRequest().getHeader(CallIdHeader.NAME);
    
    		SipInviteInfoMapper sipInviteInfoMapper = (SipInviteInfoMapper) SpringBeanFactory.getBean("sipInviteInfoMapper");
    		ISdkService sdkService = (ISdkService) SpringBeanFactory.getBean("sdkServiceImpl");
    		ResourceInfoMapper resourceInfoMapper = (ResourceInfoMapper) SpringBeanFactory.getBean("resourceInfoMapper");
    		/**
    		 * 根据call_id查询invite请求信息
    		 */
    		SipInviteInfo sipInviteInfo = sipInviteInfoMapper.selectSipInviteInfoByCallId(callIdHeader.getCallId());
    		if (sipInviteInfo != null){
    			/**
    			 * 根据相机国标编号查找相机信息
    			 */
    			ResourceInfo resourceInfo = resourceInfoMapper.selectResourceInfoByChannelId(sipInviteInfo.getCameraNo());
    			if (resourceInfo != null){
    				SdkCameraVo sdkCameraVo = new SdkCameraVo();
    				sdkCameraVo.setCamera(resourceInfo.getOtherId());
    				sdkCameraVo.setSourcePort(resourceInfo.getPort());
    				sdkCameraVo.setTargetIp(sipInviteInfo.getSendIp());
    				sdkCameraVo.setTargetPort(Integer.parseInt(sipInviteInfo.getSendPort()));
    				/**
    				 * 调相机停止推流接口
    				 *
    				 */
    				sdkService.stopPushStream(resourceInfo.getOtherId(),sipInviteInfo.getCloseNo());
    				sipInviteInfo.setOpenStatus(1);
    				sipInviteInfoMapper.updateSipInviteInfo(sipInviteInfo);
    			}
    		}
    
    	}
    
    }
    
    
    展开全文
  • 如何表示上级目录 ../表示源文件所在目录的上一级目录,../../表示源文件所在目录的上上级目录,以此类推。 假设info.html路径是:c:/Inetpub/wwwroot/sites/blabla/info.html假设index.html路径是:c:/Inetpub/...

    如何表示上级目录

    ../表示源文件所在目录的上一级目录,../../表示源文件所在目录的上上级目录,以此类推。

    假设info.html路径是:c:/Inetpub/wwwroot/sites/blabla/info.html
    假设index.html路径是:c:/Inetpub/wwwroot/sites/index.html
    在info.html加入index.html超链接的代码应该这样写:

    <a href = "../index.html">index.html</a>

     

    假设info.html路径是:c:/Inetpub/wwwroot/sites/blabla/info.html
    假设index.html路径是:c:/Inetpub/wwwroot/index.html
    在info.html加入index.html超链接的代码应该这样写:

    <a href = "../../index.html">index.html</a>

     

    假设info.html路径是:c:/Inetpub/wwwroot/sites/blabla/info.html
    假设index.html路径是:c:/Inetpub/wwwroot/sites/wowstory/index.html
    在info.html加入index.html超链接的代码应该这样写:

    <a href = "../wowstory/index.html">index.html</a>
     
     

    如何表示下级目录

    引用下级目录的文件,直接写下级目录文件的路径即可。

    假设info.html路径是:c:/Inetpub/wwwroot/sites/blabla/info.html
    假设index.html路径是:c:/Inetpub/wwwroot/sites/blabla/html/index.html
    在info.html加入index.html超链接的代码应该这样写:

    <a href = "html/index.html">index.html</a>

     

    假设info.html路径是:c:/Inetpub/wwwroot/sites/blabla/info.html
    假设index.html路径是:c:/Inetpub/wwwroot/sites/blabla/html/tutorials/index.html
    在info.html加入index.html超链接的代码应该这样写:

    <a href = "html/tutorials/index.html">index.html</a>

     

    如何联系我:【万里虎】www.bravetiger.cn 【QQ】3396726884 (咨询问题100元起,帮助解决问题500元起) 【博客】http://www.cnblogs.com/kenshinobiy/
    展开全文
  • HTML相对路径上级目录及下级目录的写法_HTML/Xhtml_网页制作HTML相对路径上级目录及下级目录的写法_HTML/Xhtml_网页制作时间:2021-07-01 10:21:17 帮助过:160人阅读如何表示上级目录../表示源文件所在目录的上一...
  • word下级标题与上级标题不关联

    万次阅读 2016-11-16 20:34:38
    分享一下前面一段时间使用word时碰到的一个问题(本人使用office2013): 一级标题二级标题之间没有关联,出现如下情况: ...可以看到在一级标题2下的二级标题并没有重新开始编号...希望可以帮到需要帮助的人。
  • PHP递归统计上下级

    千次阅读 2018-09-28 17:01:16
    我们Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客: 全新的界面设计 ,将会带来全新的写作体验; 在创作中心设置你喜爱的代码...
  • 任何一个组织都存在上下级关系,在大家心中,上级管下属天经地义。所以这篇文章的标题《怎样管理你的上级领导》,有点很稀奇,甚至有点匪夷所思。 那为什么还要管理上级呢? 很多粉丝都问过我,“袁总,我已经工作5...
  • 合理做下级

    2010-08-27 09:31:00
    每一个人都不是天生的管理者,每一个人都一定会有做下属的...看了之后颇有一番感慨,随着企业间人才流动的加剧,企业可以选择,领导却不可以选择,所以员工的适应性和职业素养就有了更高的选择。这是该文作者
  • 工程师文化技术企业来说非常重要,但是在很多公司,作为下属并不敢(会)随便在会议或者平时工作中对上级提出质疑和不一样的声音,这公司,项目,团队,甚至上下级的成长都会产生很多的影响,为了解决这个问题,...
  • 讼卦,帮助你处理好和上级的关系

    千次阅读 2011-10-15 18:16:50
    主要是上级对下级的工作提出异议和记录下级缺点的部门。俗称东厂。这样办好吗?值得商榷。 但是宗旨是:以没有争讼为目标。不是法务部门处理的争讼越多,这个部门的业绩就越好。这是严重不对的。难道不知明朝之亡...
  • PHP 递归无限极下级

    2019-04-10 10:21:00
    下面是自己用到的一些递归...本文只是博主自己存储用到的一些方法,如果您有所帮助,是博主最大的满足 再次感谢两位大大的分享 2019年04月10日   转载于:https://www.cnblogs.com/YFYQ/p/10681698.html
  • 在CRM的实体的权限体系分为个人级,部门级,上下级和组织级,一般了解这个体系的人都能分清这四个级别对应的关系,但理解的比较深刻的一般都是读写删,比如个人级的只能读写删记录ower为自己的记录,部门级能读写删...
  • 第二章 下级平台与上级平台进行保活 第三章 下级平台响应上级平台的资源查询 第四章 下级平台响应上级平台的实时视频流请求 第五章 响应上级平台的订阅请求并及进行目录订阅推送 附:优雅的改变Javax-sip包进行sip...
  • 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录Java实现GB2312标准的sip下级平台前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结 前言 提示:这里可以添加本文要记录的...
  • ​任何一个组织都存在上下级关系,在大家心中,上级管下属天经地义。所以这篇文章的标题《怎样管理你的上级领导》,有点很稀奇,甚至有点匪夷所思。 那为什么还要管理上级呢? 很多粉丝都问过我,“袁总,我已经工作...
  • 起源于App推广,当推广App上遇到效率低下,采取这种的形式(不需要邀请码),这种上下级关系一时爆发,用户数量飙升。采用Xinstall来做免邀请码安装的,目前免费试用一个月,涉及三个方面:分享页面的js,AndroidSDK,...
  • 自己感觉先前这个问题没有很重视,相信很多人也和我一样。整理此篇文章期望自己慢慢改进。 一、为什么要进行上级管理? 1、上级的工作与你的工作有直接的关联; 通常,下属的工作是从上级的工作中分离出来的...
  • 偶尔会听到身边的人在私底下吐槽或抱怨“我们组里的很多人的能力都比开发经理...”。这类话的潜台词是:我的能力比他强,这应该听我...② 他是空降下来的,只是刚开始公司业务不熟,或者入职的考察不够(有些能说...
  • 国标GB28181可以说是在流媒体协议中,开发和调试难度较高的协议了,尤其是在国标GB...可以帮助开发者从学习国标GB28181,到项目应用国标GB28181上,解决整个国标设备与国标平台交互理解、协议实现和软件研发的全过程?
  • 如何与上级进行1on1的回顾面谈?

    千次阅读 2018-08-16 00:33:21
    1on1回顾面谈指的是谈话管理者与被管理者就过去一段时间的工作内容进行一一面对面即时的直接沟通交流,有不少公司是把这个面谈作为绩效考评的依据或参考的。经过近两周的时间终于把团队内部的人都进行了1on1的面谈...
  • 如果你用el-tree做菜单和按钮的权限数据选择,那么按钮和...在菜单和按钮权限的大背景之下,我们需要的是按钮和他的上级菜单不遵循强制的父子联动关系,而其余菜单则强制遵循父子联动关系。明白了这一点之后,我们需...
  • element侧边导航栏多层菜单时上级菜单无高亮解决方案解决方案具体实现 解决方案 查阅网上很多解决方案,都是千篇一律,而且都无法有效解决我的问题。其实要使element的侧边导航栏在点击菜单后使父级菜单一起高亮的...
  • 目标管理中的七个经典故事

    千次阅读 2010-06-03 22:12:00
    从这几个故事里我们不仅能看到管理的理念中上级对下级的影响,也可以看到精确记录的数据可以说明很多问题。
  • 所以,上级对我较为放心,我为上级安排什么事情,总是得到上级的同意和认可。由于自己的努力,我成了红人。大家都说我有靠山,此言不假。  我的用人原则是,我是否喜欢你。我作为局长,我手下的人自然由我来提拔。...
  • 在Q12调查系统中,第一、第二个就是问,你是不是知道应该做什么,以及做事的必备资源是否准备好了。管理就是这样,第一步,你得让你的员工知道自己做什么,然后才可能把...但上级下级的想法能够完全一样,那是很难...
  • 有趣的是,BetterWorks 发现,相比于自己工作内容的关注,下级更喜欢监督上级的目标,这个比例要高出 20% 。显然,大家都希望更了解自己的领导,渴望工作环境的透明度更高。 基于大数据分析,机器学习能够将不同...
  • dede帮助手册

    千次阅读 2013-12-09 10:44:37
    '游客' : @me)"/] [field:title/] 的评论: <li class='fbmsg'> [field:aid/]" class='fbmsg'>[field:msg /]</a></li> {/dede:feedback} 标签属性 row:调用评论条数 titlelen:标题长度 infolen:评论长度 ...
  • 我们团队现在负责的一个产品在合同中...在上一次报告发出时,业主的上级部门这个报告进行了分析和评估,反复了近 10 次左右,最终才将这个文件的版本定下来,报告输出的时间定在每个月的 25 日左右。然而本月的会...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,876
精华内容 2,350
关键字:

上级对下级的帮助