浏览代码

测试2 合并测试

kindring 2 年之前
父节点
当前提交
5fe1a4f727

+ 33 - 33
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java

@@ -4,79 +4,79 @@ import io.swagger.v3.oas.annotations.media.Schema;
 
 import java.io.Serializable;
 
-@Schema(description = "流信息")
+@Schema(description = "娴佷俊鎭�")
 public class StreamInfo implements Serializable, Cloneable{
 
-    @Schema(description = "应用名")
+    @Schema(description = "搴旂敤鍚�")
     private String app;
-    @Schema(description = "流ID")
+    @Schema(description = "娴両D")
     private String stream;
-    @Schema(description = "设备编号")
+    @Schema(description = "璁惧�缂栧彿")
     private String deviceID;
-    @Schema(description = "通道编号")
+    @Schema(description = "閫氶亾缂栧彿")
     private String channelId;
 
     @Schema(description = "IP")
     private String ip;
 
-    @Schema(description = "HTTP-FLV流地址")
+    @Schema(description = "HTTP-FLV娴佸湴鍧€")
     private StreamURL flv;
 
-    @Schema(description = "HTTPS-FLV流地址")
+    @Schema(description = "HTTPS-FLV娴佸湴鍧€")
     private StreamURL https_flv;
-    @Schema(description = "Websocket-FLV流地址")
+    @Schema(description = "Websocket-FLV娴佸湴鍧€")
     private StreamURL ws_flv;
-    @Schema(description = "Websockets-FLV流地址")
+    @Schema(description = "Websockets-FLV娴佸湴鍧€")
     private StreamURL wss_flv;
-    @Schema(description = "HTTP-FMP4流地址")
+    @Schema(description = "HTTP-FMP4娴佸湴鍧€")
     private StreamURL fmp4;
-    @Schema(description = "HTTPS-FMP4流地址")
+    @Schema(description = "HTTPS-FMP4娴佸湴鍧€")
     private StreamURL https_fmp4;
-    @Schema(description = "Websocket-FMP4流地址")
+    @Schema(description = "Websocket-FMP4娴佸湴鍧€")
     private StreamURL ws_fmp4;
-    @Schema(description = "Websockets-FMP4流地址")
+    @Schema(description = "Websockets-FMP4娴佸湴鍧€")
     private StreamURL wss_fmp4;
-    @Schema(description = "HLS流地址")
+    @Schema(description = "HLS娴佸湴鍧€")
     private StreamURL hls;
-    @Schema(description = "HTTPS-HLS流地址")
+    @Schema(description = "HTTPS-HLS娴佸湴鍧€")
     private StreamURL https_hls;
-    @Schema(description = "Websocket-HLS流地址")
+    @Schema(description = "Websocket-HLS娴佸湴鍧€")
     private StreamURL ws_hls;
-    @Schema(description = "Websockets-HLS流地址")
+    @Schema(description = "Websockets-HLS娴佸湴鍧€")
     private StreamURL wss_hls;
-    @Schema(description = "HTTP-TS流地址")
+    @Schema(description = "HTTP-TS娴佸湴鍧€")
     private StreamURL ts;
-    @Schema(description = "HTTPS-TS流地址")
+    @Schema(description = "HTTPS-TS娴佸湴鍧€")
     private StreamURL https_ts;
-    @Schema(description = "Websocket-TS流地址")
+    @Schema(description = "Websocket-TS娴佸湴鍧€")
     private StreamURL ws_ts;
-    @Schema(description = "Websockets-TS流地址")
+    @Schema(description = "Websockets-TS娴佸湴鍧€")
     private StreamURL wss_ts;
-    @Schema(description = "RTMP流地址")
+    @Schema(description = "RTMP娴佸湴鍧€")
     private StreamURL rtmp;
-    @Schema(description = "RTMPS流地址")
+    @Schema(description = "RTMPS娴佸湴鍧€")
     private StreamURL rtmps;
-    @Schema(description = "RTSP流地址")
+    @Schema(description = "RTSP娴佸湴鍧€")
     private StreamURL rtsp;
-    @Schema(description = "RTSPS流地址")
+    @Schema(description = "RTSPS娴佸湴鍧€")
     private StreamURL rtsps;
-    @Schema(description = "RTC流地址")
+    @Schema(description = "RTC娴佸湴鍧€")
     private StreamURL rtc;
 
-    @Schema(description = "RTCS流地址")
+    @Schema(description = "RTCS娴佸湴鍧€")
     private StreamURL rtcs;
-    @Schema(description = "流媒体ID")
+    @Schema(description = "娴佸獟浣揑D")
     private String mediaServerId;
-    @Schema(description = "流编码信息")
+    @Schema(description = "娴佺紪鐮佷俊鎭�")
     private Object tracks;
-    @Schema(description = "开始时间")
+    @Schema(description = "寮€濮嬫椂闂�")
     private String startTime;
-    @Schema(description = "结束时间")
+    @Schema(description = "缁撴潫鏃堕棿")
     private String endTime;
-    @Schema(description = "进度(录像下载使用)")
+    @Schema(description = "杩涘害锛堝綍鍍忎笅杞戒娇鐢�級")
     private double progress;
 
-    @Schema(description = "是否暂停(录像回放使用)")
+    @Schema(description = "鏄�惁鏆傚仠锛堝綍鍍忓洖鏀句娇鐢�級")
     private boolean pause;
 
     public void setFlv(StreamURL flv) {

+ 9 - 6
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java

@@ -547,11 +547,11 @@ public class SIPCommander implements ISIPCommander {
 //                // 释放 zlm 的推流端口
 //                mediaServerService.releaseSsrc(mediaServerItem.getId(), _ssrc );
 //                // todo 等待 broadcast invite的 200 sdp 超时  回复bye
-////                try {
-////                    cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());
-////                } catch (SipException | InvalidArgumentException | ParseException e) {
-////                    logger.error("[命令发送失败] 语音广播 发送BYE: {}", e.getMessage());
-////                }
+//                try {
+//                    cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());
+//                } catch (SipException | InvalidArgumentException | ParseException e) {
+//                    logger.error("[命令发送失败] 语音广播 发送BYE: {}", e.getMessage());
+//                }
 //            }, 60 * 1000);
 //            testInviteRequestProcessor.responseBroadcastSdpACK(serverTransaction,
 //                    sdpContent,
@@ -566,7 +566,10 @@ public class SIPCommander implements ISIPCommander {
                     sipConfig.getPort()
             );
         }catch(SipException e){
-            logger.warn("下发audio invite 失败");
+            logger.warn("返回audio invite 失败");
+            if(errorEvent != null){
+//                errorEvent(e);
+            }
         }
 
 

+ 6 - 2
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java

@@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.service;
 import com.alibaba.fastjson2.JSONObject;
 import com.genersoft.iot.vmp.common.StreamInfo;
 import com.genersoft.iot.vmp.conf.exception.ServiceException;
+import com.genersoft.iot.vmp.gb28181.HookSubscribeForKey;
 import com.genersoft.iot.vmp.gb28181.bean.Device;
 import com.genersoft.iot.vmp.gb28181.bean.InviteStreamCallback;
 import com.genersoft.iot.vmp.gb28181.bean.InviteStreamInfo;
@@ -10,6 +11,7 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
 import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback;
+import com.genersoft.iot.vmp.service.bean.NodeCallBack;
 import com.genersoft.iot.vmp.service.bean.PlayBackCallback;
 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
 
@@ -29,8 +31,10 @@ public interface IPlayService {
               InviteTimeOutCallback timeoutCallback);
     void play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent, Runnable timeoutCallback);
 
-    void openBroadcast(MediaServerItem mediaServerItem,String deviceId,String audioStreamId,ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent,
-                              Runnable timeoutCallback);
+    void openBroadcast(MediaServerItem mediaServerItem, String deviceId, String audioStreamId,
+                       HookSubscribeForKey broadcastForInviteHook,
+                       NodeCallBack nodeCallBack,
+                       Runnable timeoutCallback);
     MediaServerItem getNewMediaServerItem(Device device);
 
     /**

+ 20 - 169
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java

@@ -364,133 +364,24 @@ public class PlayServiceImpl implements IPlayService {
     }
 
 
-    public void openBroadcast(MediaServerItem mediaServerItem,String deviceId,String audioStreamId,ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent,
+    public void openBroadcast(MediaServerItem mediaServerItem,
+                              String deviceId,
+                              String audioStreamId,
+                              HookSubscribeForKey broadcastForInviteHook,
+                              NodeCallBack nodeCallBack,
                               Runnable timeoutCallback){
         logger.warn("[语音广播] 开语音广播");
 //        PlayResult playResult = new PlayResult();
-        RequestMessage msg = new RequestMessage();
-        String key  = DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId;
-        // 使用invite 来进行延迟
-        msg.setKey(key);
-        String uuid = UUID.randomUUID().toString();
-        msg.setId(uuid);
-//        playResult.setUuid(uuid);
-        DeferredResult<WVPResult<String>> result = new DeferredResult<>(13*1000l);
-//        playResult.setResult(result);
-        resultHolder.put(key, uuid, result);
-        // 检查zlm
-        if (mediaServerItem == null) {
-            logger.warn("[语音广播] 无法连接至ZLM服务器");
-            WVPResult wvpResult = new WVPResult();
-            wvpResult.setCode(ErrorCode.ERROR100.getCode());
-            wvpResult.setMsg("无法连接至流媒体服务器");
-            msg.setData(wvpResult);
-            resultHolder.invokeAllResult(msg);
-            return;
-        }
 
-        // 此段为录像查询...
         Device device = redisCatchStorage.getDevice(deviceId);
-//        StreamInfo streamInfo = redisCatchStorage.queryRecordByDevice(deviceId);
-//        playResult.setDevice(device);
-
-
-        HookSubscribeForKey broadcastForInviteHook = GBHookSubscribeFactory.on_broadcast_invite(deviceId);
-
-
-
-
-        // 检查无法连接zlm的情况
-//        if (streamInfo != null && false) {
-//            GBHookSubscribe.removeSubscribe(broadcastForInviteHook);
-//            String streamId = streamInfo.getStream();
-//            if (streamId == null){
-//                logger.warn("[语音广播] zlm 缓存的 streamId等于null");
-//                WVPResult wvpResult = new WVPResult();
-//                wvpResult.setCode(ErrorCode.ERROR100.getCode());
-//                wvpResult.setMsg("zlm 缓存的 streamId等于null");
-//                msg.setData(wvpResult);
-//                resultHolder.invokeAllResult(msg);
-//                return ;
-//            }
-//            String mediaServerId = streamInfo.getMediaServerId();
-//            MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
-//            JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId);
-//            if(rtpInfo.getInteger("code") == 0){
-//                if (rtpInfo.getBoolean("exist")) {
-//                    int localPort = rtpInfo.getInteger("local_port");
-//                    if (localPort == 0) {
-//                        logger.warn("[语音广播],点播时发现rtpServerC存在,但是尚未开始推流");
-//                        // 此时说明rtpServer已经创建但是流还没有推上来
-//                        WVPResult wvpResult = new WVPResult();
-//                        wvpResult.setCode(ErrorCode.ERROR100.getCode());
-//                        wvpResult.setMsg("语音广播已经开始");
-//                        msg.setData(wvpResult);
-//
-//                        resultHolder.invokeAllResult(msg);
-//                        return ;
-//                    }else{
-//                        // 语音点播已经开始,返回推流信息给前端
-//                        WVPResult wvpResult = new WVPResult();
-//                        wvpResult.setCode(ErrorCode.SUCCESS.getCode());
-//                        wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());
-//                        wvpResult.setData(streamInfo);
-//                        msg.setData(wvpResult);
-//                        resultHolder.invokeAllResult(msg);
-//                        if (hookEvent != null) {
-//                            hookEvent.response(mediaServerItem, JSONObject.parseObject(JSON.toJSONString(streamInfo)));
-//                        }
-//                    }
-//                }else{
-//                    logger.warn("[语音广播] 停止语音广播推流转发端口");
-//                    redisCatchStorage.stopBroadcast(streamInfo);
-//                    storager.stopBroadcast(streamInfo.getDeviceID());
-//                    streamInfo = null;
-//                }
-//            }else{
-//                logger.warn("[语音广播] 无法连接至zlm服务器");
-//                redisCatchStorage.stopPlay(streamInfo);
-//                storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
-//                streamInfo = null;
-//            }
-//        }
-
-        result.onTimeout(()->{
-            logger.warn("[广播超时] 与设备交互broadcast流程超时,未收到设备invite信息");
-            WVPResult wvpResult = new WVPResult();
-            wvpResult.setCode(ErrorCode.ERROR100.getCode());
-            wvpResult.setMsg("[广播超时] 与设备交互broadcast流程超时,未收到设备invite信息");
-            msg.setData(wvpResult);
-            resultHolder.invokeAllResult(msg);
-            // 超时移除
-            GBHookSubscribe.removeSubscribe(broadcastForInviteHook);
-        });
-
-        result.onCompletion(()->{
-            // 通道结束
-            logger.info("[语音广播] broadcast流程结束....");
-        });
-
-
-        // rtp语音通道创建完成,开始发送broadcast
-        broadcastEventHandle(
-                device,
-                audioStreamId,
-            (int code,String tipMsg)->{
-                if(code == 1){
-                    WVPResult wvpResult = new WVPResult();
-                    wvpResult.setCode(ErrorCode.ERROR100.getCode());
-                    wvpResult.setMsg(tipMsg);
-                    msg.setData(wvpResult);
-                    // 回复之前所有的点播请求
-                    resultHolder.invokeAllResult(msg);
-                }
-            }
-        );
-
-        // 开始创建 rtp/tcp 推流通道
-
 
+        // rtp语音通道创建完成,开始发送broadcast,
+        try {
+            cmder.audioBroadcastCmd(device, audioStreamId);
+        }catch (InvalidArgumentException | SipException | ParseException e) {
+            logger.error("[命令发送失败] 发送broadcast中 errorMsg: {}", e.getMessage());
+            nodeCallBack.run(1,"[命令发送失败] 无法发送broadcast消息");
+        }
         // 注册subScript事件
         GBHookSubscribe.addInviteSubscribe(broadcastForInviteHook,(int code, JSONObject json, SIPRequest request)->{
             logger.info("[语音广播] 接收到设备invite信息___订阅事件触发 JSONDATA: {}",json.toJSONString());
@@ -502,46 +393,23 @@ public class PlayServiceImpl implements IPlayService {
                 streamId = String.format("broadcast_%s", device.getDeviceId());
             }
             logger.info("[语音广播] 尝试创建rtp语音推流通道");
-//                ssrcInfo = mediaServerService.startSendRtpServer(mediaServerItem, streamId, audioStreamId,
-//                        json.getString("addr"),
-//                        json.getString("port"),
-//                        json.getString("ssrc")
-//                );
-//                logger.info(JSONObject.toJSONString(ssrcInfo));
-//                TimeDescriptionImpl timeDescription = (TimeDescriptionImpl) (sdp.getTimeDescriptions(false).get(0));
-//                TimeField startTimeFiled = (TimeField) timeDescription.getTime();
-//                startTime = startTimeFiled.getStartTime();
-//                stopTime = startTimeFiled.getStopTime();
-//
-//                start = Instant.ofEpochSecond(startTime);
-//                end = Instant.ofEpochSecond(stopTime);
 
             // TODO: 2023/3/7 开始下发invite信息给设备
             try {
-//                String sdpContent = cmder.createBroadcastInviteSdp(mediaServerItem, ssrcInfo);
-//                String _ssrc = ssrcInfo.getSsrc();
-
-
-                cmder.sendBoradcastInviteCmd(request,mediaServerItem, ssrcInfo, device, null, null,
-                null,
-                (_event) -> {
-                },
-                (_errorEvent) -> {
-
-                });
+                // 向流媒体服务器申请创建 rtpServer 服务端口
                 ssrcInfo = mediaServerService.startSendRtpServer(mediaServerItem, streamId, audioStreamId,
                         json.getString("addr"),
                         json.getString("port"),
                         ssrcStr
                 );
-                resultHolder.invokeAllResult(msg);
-                WVPResult wvpResult = new WVPResult();
-                wvpResult.setCode(ErrorCode.SUCCESS.getCode());
-                wvpResult.setMsg("okokokokooo");
-                wvpResult.setData(ssrcInfo);
+                // 回复invite 200 信息至设备
+                cmder.sendBoradcastInviteCmd(request,mediaServerItem, ssrcInfo, device, null, null,
+                null,
+                null,
+                null);
+                //
+                nodeCallBack.run(0,"ok");
 
-                msg.setData(wvpResult);
-                resultHolder.invokeAllResult(msg);
             }catch(InvalidArgumentException |  SipException | ParseException e){
                 logger.error("[下发audio拉流invite失败]",e);
 //                    SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new CmdSendFailEvent(null));
@@ -549,26 +417,9 @@ public class PlayServiceImpl implements IPlayService {
 //                    errorEvent.response(eventResult);
             }
         });
-
-
-
         return ;
     }
 
-    public void broadcastEventHandle(
-            Device device,
-            String webrtcStreamId,
-            NodeCallBack nodeCallBack){
-        logger.info("[语音广播] 开始broadcast交互");
-        try {
-            cmder.audioBroadcastCmd(device,webrtcStreamId);
-            nodeCallBack.run(0,"ok");
-        } catch (InvalidArgumentException | SipException | ParseException e) {
-            logger.error("[命令发送失败] 发送broadcast中 errorMsg: {}", e.getMessage());
-            nodeCallBack.run(1,"[命令发送失败] 无法发送broadcast消息");
-        }
-  }
-
     @Override
     public void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId) {
         StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);

+ 63 - 1
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java

@@ -6,6 +6,9 @@ import com.genersoft.iot.vmp.common.StreamInfo;
 import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.conf.exception.ControllerException;
 import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
+import com.genersoft.iot.vmp.gb28181.GBEventSubscribe;
+import com.genersoft.iot.vmp.gb28181.GBHookSubscribeFactory;
+import com.genersoft.iot.vmp.gb28181.HookSubscribeForKey;
 import com.genersoft.iot.vmp.gb28181.bean.Device;
 import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
@@ -77,6 +80,9 @@ public class PlayController {
 	@Autowired
 	private UserSetting userSetting;
 
+	@Autowired
+	private GBEventSubscribe GBHookSubscribe;
+
 	@Operation(summary = "开始点播")
 	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
 	@Parameter(name = "channelId", description = "通道国标编号", required = true)
@@ -258,9 +264,65 @@ public class PlayController {
         if (logger.isDebugEnabled()) {
             logger.debug("语音广播API调用");
         }
+		// 添加计时器,待事件结束则自动触发超时回复
+		RequestMessage msg = new RequestMessage();
+		String key  = DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId;
+		boolean exist = resultHolder.exist(key, null);
+		msg.setKey(key);
+		String uuid = UUID.randomUUID().toString();
+		msg.setId(uuid);
+		DeferredResult<WVPResult<String>> result = new DeferredResult<>(13*1000l);
+		DeferredResultEx<WVPResult<String>> deferredResultEx = new DeferredResultEx<>(result);
+		HookSubscribeForKey broadcastForInviteHook =  GBHookSubscribeFactory.on_broadcast_invite(deviceId);
+
+
+		result.onTimeout(()->{
+			logger.warn("[广播超时] 与设备交互broadcast流程超时,未收到设备invite信息");
+			WVPResult wvpResult = new WVPResult();
+			wvpResult.setCode(ErrorCode.ERROR100.getCode());
+			wvpResult.setMsg("[广播超时] 与设备交互broadcast流程超时,未收到设备invite信息");
+			msg.setData(wvpResult);
+			resultHolder.invokeAllResult(msg);
+			// 超时移除
+			GBHookSubscribe.removeSubscribe(broadcastForInviteHook);
+		});
+		resultHolder.put(key, uuid, result);
 		Device device = storager.queryVideoDevice(deviceId);
 		MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
-		playService.openBroadcast(newMediaServerItem, deviceId,stream, null, null, null);
+
+		if (newMediaServerItem == null) {
+			logger.warn("[语音广播] 无法连接至ZLM服务器");
+			WVPResult wvpResult = new WVPResult();
+			wvpResult.setCode(ErrorCode.ERROR100.getCode());
+			wvpResult.setMsg("无法连接至流媒体服务器");
+			msg.setData(wvpResult);
+			resultHolder.invokeAllResult(msg);
+		}else{
+			playService.openBroadcast(
+					newMediaServerItem,
+					deviceId,
+					stream,
+					broadcastForInviteHook,
+					(int code,String tipMsg)->{
+						if(code == 1){
+							WVPResult wvpResult = new WVPResult();
+							wvpResult.setCode(ErrorCode.ERROR100.getCode());
+							wvpResult.setMsg(tipMsg);
+							msg.setData(wvpResult);
+							// 回复之前所有的点播请求
+							resultHolder.invokeAllResult(msg);
+						} else if (code == 0) {
+							resultHolder.invokeAllResult(msg);
+							WVPResult wvpResult = new WVPResult();
+							wvpResult.setCode(ErrorCode.SUCCESS.getCode());
+							wvpResult.setMsg("okokokokooo");
+//							wvpResult.setData(ssrcInfo);
+							msg.setData(wvpResult);
+							resultHolder.invokeAllResult(msg);
+						}
+					}, null);
+		}
+
 		return result;
 
 	}

+ 2 - 2
src/main/resources/application.yml

@@ -97,7 +97,7 @@ sip:
     # [必须修改] 本机的IP, 必须是网卡上的IP,用于sip下协议栈监听ip,如果监听所有设置为0.0.0.0
     monitor-ip: 0.0.0.0
     # [必须修改] 本机的IP
-    ip: 192.168.1.26
+    ip: 0.0.0.0
     # [可选] 28181服务监听的端口
     port: 29000
     # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
@@ -133,7 +133,7 @@ media:
     #stream-ip: 192.168.1.203
     #stream-ip: 113.88.194.58
     # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip
-    sdp-ip: 192.168.1.60
+    sdp-ip: 192.168.31.60
     #sdp-ip: 192.168.1.203
     #sdp-ip: 113.88.194.58
     # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip