From f06ac3402687f19065bd5ae738f9a8e95dad7eaa Mon Sep 17 00:00:00 2001
From: WXL <1785969728@qq.com>
Date: 星期四, 10 七月 2025 17:09:14 +0800
Subject: [PATCH] 测试完成

---
 src/utils/sipService.js |  176 ++++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 115 insertions(+), 61 deletions(-)

diff --git a/src/utils/sipService.js b/src/utils/sipService.js
index e6cca92..4b12914 100644
--- a/src/utils/sipService.js
+++ b/src/utils/sipService.js
@@ -1,118 +1,172 @@
-import JsSIP from 'jssip'
+import JsSIP from "jssip";
 
 class SipService {
   constructor() {
-    this.ua = null
-    this.currentSession = null
-    this.onStatusChange = null // 鐘舵�佸彉鍖栧洖璋�
+    this.ua = null;
+    this.currentSession = null;
+    this.onStatusChange = null; // 鐘舵�佸彉鍖栧洖璋�
   }
 
   // 鍒濆鍖朣IP瀹㈡埛绔�
   init(config) {
     try {
-      this.updateStatus('connecting', '杩炴帴涓�...')
+      this.updateStatus("connecting", "杩炴帴涓�...");
 
       this.ua = new JsSIP.UA({
         sockets: [new JsSIP.WebSocketInterface(config.wsUrl)],
         uri: config.sipUri,
         password: config.password,
         display_name: config.displayName,
+        iceservers:[],
         // realm: config.realm,
         register: true,
-        session_expires:180,
+        session_expires: 180,
+        sessionTimersExpires: 300, // 璁剧疆 Session-Expires=120锛堝繀椤� >= Min-SE锛�
+        extraHeaders: [
+          "Min-SE: 120", // 鍙�夛細鏄惧紡鍛婅瘔鏈嶅姟鍣ㄤ綘鏀寔鐨勬渶灏忓��
+        ],
         register_expires: 300, // 娉ㄥ唽鏈夋晥鏈�(绉�)
         connection_recovery_min_interval: 2, // 鏈�灏忛噸杩為棿闅�
-        connection_recovery_max_interval: 30 // 鏈�澶ч噸杩為棿闅�
-      })
+        connection_recovery_max_interval: 30, // 鏈�澶ч噸杩為棿闅�
+      });
 
-      this.ua.start()
+      this.ua.start();
 
       // 娉ㄥ唽浜嬩欢鐩戝惉
-      this.ua.on('registered', () => {
-        this.updateStatus('registered', '宸叉敞鍐�')
-      })
+      this.ua.on("registered", () => {
+        this.updateStatus("registered", "宸叉敞鍐�");
+      });
 
-      this.ua.on('registrationFailed', (e) => {
-        this.updateStatus('failed', `娉ㄥ唽澶辫触: ${e.cause}`)
-      })
+      this.ua.on("registrationFailed", (e) => {
+        this.updateStatus("failed", `娉ㄥ唽澶辫触: ${e.cause}`);
+      });
 
-      this.ua.on('disconnected', () => {
-        this.updateStatus('disconnected', '杩炴帴鏂紑')
-      })
+      this.ua.on("disconnected", () => {
+        this.updateStatus("disconnected", "杩炴帴鏂紑");
+      });
 
-      this.ua.on('connected', () => {
-        this.updateStatus('connecting', '閲嶆柊杩炴帴涓�...')
-      })
+      this.ua.on("connected", () => {
+        this.updateStatus("connecting", "閲嶆柊杩炴帴涓�...");
+      });
 
       // 鐩戝惉鏉ョ數
-      this.ua.on('newRTCSession', (data) => {
-        this.handleIncomingCall(data.session)
-      })
-
+      this.ua.on("newRTCSession", (data) => {
+        this.handleIncomingCall(data.session);
+      });
     } catch (error) {
-      this.updateStatus('failed', `鍒濆鍖栧け璐�: ${error.message}`)
-      console.error('SIP鍒濆鍖栧け璐�:', error)
+      this.updateStatus("failed", `鍒濆鍖栧け璐�: ${error.message}`);
+      console.error("SIP鍒濆鍖栧け璐�:", error);
+    }
+  }
+  handleIncomingCall(session) {
+    if (session.direction === "incoming") {
+      console.log("鏉ョ數:", session.remote_identity.uri.toString());
+      // 鍙互鍦ㄨ繖閲岃Е鍙� UI 閫氱煡
+      if (this.onIncomingCall) {
+        this.onIncomingCall(session);
+      }
     }
   }
 
   // 鏇存柊鐘舵�佸苟閫氱煡UI
   updateStatus(type, text) {
-    console.log(`SIP鐘舵�佹洿鏂�: ${type} - ${text}`)
+    console.log(`SIP鐘舵�佹洿鏂�: ${type} - ${text}`);
     if (this.onStatusChange) {
-      this.onStatusChange({ type, text })
+      this.onStatusChange({ type, text });
     }
   }
 
   // 涓�閿嫧鍙� - 澧炲姞娉ㄥ唽鐘舵�佹鏌�
   makeCall(targetNumber) {
     if (!this.ua) {
-      throw new Error('SIP瀹㈡埛绔湭鍒濆鍖�')
+      throw new Error("SIP瀹㈡埛绔湭鍒濆鍖�");
     }
 
     if (!this.ua.isRegistered()) {
-      throw new Error('SIP鏈敞鍐岋紝鏃犳硶鍛煎彨')
+      throw new Error("SIP鏈敞鍐岋紝鏃犳硶鍛煎彨");
     }
 
     const options = {
+      sessionTimers: true,
+      sessionTimersExpires: 300,
+      extraHeaders: [
+        "Min-SE: 120",
+        "Route: <sip:@192.168.100.6>",
+        "Accept: application/sdp",
+        "Supported: replaces, timer",
+        "Allow: INVITE, ACK, BYE, CANCEL, OPTIONS",
+      ],
       eventHandlers: {
-        progress: (e) => console.log('鍛煎彨涓�...'),
-        failed: (e) => console.error('鍛煎彨澶辫触:', e),
-        ended: (e) => console.log('閫氳瘽缁撴潫'),
-        confirmed: (e) => console.log('閫氳瘽宸叉帴閫�')
+        progress: (e) => console.log("鍛煎彨涓�..."),
+        failed: (e) => console.error("鍛煎彨澶辫触:", e),
+        ended: (e) => console.log("閫氳瘽缁撴潫"),
+        confirmed: (e) => console.log("閫氳瘽宸叉帴閫�"),
       },
-      mediaConstraints: { audio: true, video: false },
-      rtcOfferConstraints: { offerToReceiveAudio: 1 }
-    }
+      mediaConstraints: {
+        audio: true,
+        video: false,
+      },
+      rtcOfferConstraints: {
+        offerToReceiveAudio: 1,
+        offerToReceiveVideo: 0,
+        mandatory: {
+          OfferToReceiveAudio: true,
+          OfferToReceiveVideo: false,
+        },
+      },
+      pcConfig: {
+        iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
+        iceTransportPolicy: "all",
+        bundlePolicy: "balanced",
+        rtcpMuxPolicy: "require",
+        codecs: {
+          audio: [
+            { name: "PCMU", clockRate: 8000, payloadType: 0 },
+            { name: "PCMA", clockRate: 8000, payloadType: 8 },
+          ],
+          video: [],
+        },
+      },
+    };
 
-    this.currentSession = this.ua.call(`sip:${targetNumber}@192.168.100.6`, options)
-    this.setupAudio(this.currentSession)
+    this.currentSession = this.ua.call(
+      `sip:${targetNumber}@192.168.100.6`,
+      options
+    );
+    // 鍦ㄤ細璇濆垱寤哄悗淇敼 SDP
+    this.currentSession.on("peerconnection", (pc) => {
+      pc.createOffer = (offerOptions) => {
+        return RTCPeerConnection.prototype.createOffer
+          .call(pc, offerOptions)
+          .then((offer) => {
+            const modifiedSdp = offer.sdp
+              .replace(/c=IN IP4 192\.168\.100\.10/g, "c=IN IP4 192.168.100.6")
+              .replace(/m=audio \d+ RTP\/AVP.*/, "m=audio 7078 RTP/AVP 0 8");
+            return new RTCSessionDescription({
+              type: "offer",
+              sdp: modifiedSdp,
+            });
+          });
+      };
+    });
+    this.setupAudio(this.currentSession);
   }
-
+  setupAudio(session) {
+    session.connection.addEventListener("addstream", (e) => {
+      const audioElement = document.getElementById("remoteAudio");
+      if (audioElement) {
+        audioElement.srcObject = e.stream;
+      }
+    });
+  }
   // 鎸傛柇褰撳墠閫氳瘽
   endCall() {
     if (this.currentSession) {
-      this.currentSession.terminate()
-      this.currentSession = null
+      this.currentSession.terminate();
+      this.currentSession = null;
     }
   }
 
-  // 澶勭悊闊抽娴�
-  setupAudio(session) {
-    session.connection.addEventListener('addstream', (e) => {
-      const audioElement = document.getElementById('remoteAudio')
-      if (audioElement) {
-        audioElement.srcObject = e.stream
-      }
-    })
-  }
-
-  // 澶勭悊鏉ョ數
-  handleIncomingCall(session) {
-    if (session.direction === 'incoming') {
-      console.log('鏉ョ數:', session.remote_identity.uri.toString())
-      // 杩欓噷鍙互瑙﹀彂UI閫氱煡
-    }
-  }
 }
 
-export default new SipService()
+export default new SipService();

--
Gitblit v1.9.3