新增turn
This commit is contained in:
parent
76879af0c8
commit
a8a1fe19ad
8502
package-lock.json
generated
Normal file
8502
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -16,14 +16,16 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dcloudio/uni-ui": "^1.4.28",
|
"@dcloudio/uni-ui": "^1.4.28",
|
||||||
|
"@types/crypto-js": "^4.2.2",
|
||||||
"ant-design-vue": "4.x",
|
"ant-design-vue": "4.x",
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
"highlight.js": "^11.11.1",
|
"highlight.js": "^11.11.1",
|
||||||
"peerjs": "^1.5.4",
|
"peerjs": "^1.5.4",
|
||||||
|
"register-service-worker": "^1.7.2",
|
||||||
"three": "^0.172.0",
|
"three": "^0.172.0",
|
||||||
"vue": "^3.3.0",
|
"vue": "^3.3.0",
|
||||||
"vue-i18n": "^9.1.9",
|
"vue-i18n": "^9.1.9",
|
||||||
"vue-router": "^4.5.0",
|
"vue-router": "^4.5.0"
|
||||||
"register-service-worker": "^1.7.2"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rushstack/eslint-patch": "^1.6.1",
|
"@rushstack/eslint-patch": "^1.6.1",
|
||||||
|
|||||||
@ -318,8 +318,8 @@ const handleReceive = async () => {
|
|||||||
await localCurrentFile.value.loadLocalDirectory();
|
await localCurrentFile.value.loadLocalDirectory();
|
||||||
};
|
};
|
||||||
// 事件监听
|
// 事件监听
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
peer.init();
|
await peer.init();
|
||||||
peer.on("open", ((event: CustomEvent) => {
|
peer.on("open", ((event: CustomEvent) => {
|
||||||
myId.value = event.detail;
|
myId.value = event.detail;
|
||||||
const sign = getUrlParam("sign");
|
const sign = getUrlParam("sign");
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import {
|
|||||||
getPermissionSet,
|
getPermissionSet,
|
||||||
confirmWin,
|
confirmWin,
|
||||||
} from "./common";
|
} from "./common";
|
||||||
|
import { fetchTurnServers } from "./turn";
|
||||||
|
|
||||||
type MediaType = "desktop" | "call" | "camera";
|
type MediaType = "desktop" | "call" | "camera";
|
||||||
// 发送超时时间(毫秒)
|
// 发送超时时间(毫秒)
|
||||||
@ -43,10 +44,25 @@ class Peer extends EventTarget {
|
|||||||
super();
|
super();
|
||||||
this.sign = sign;
|
this.sign = sign;
|
||||||
}
|
}
|
||||||
public init() {
|
public async init() {
|
||||||
|
let iceServers: {
|
||||||
|
urls: string | string[];
|
||||||
|
username?: string;
|
||||||
|
credential?: string;
|
||||||
|
}[] = [{ urls: "stun:8.134.35.244:3478" }];
|
||||||
|
|
||||||
|
try {
|
||||||
|
const turnServers = await fetchTurnServers(this.sign);
|
||||||
|
if (turnServers.length > 0) {
|
||||||
|
iceServers = iceServers.concat(turnServers);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("获取 TURN 服务器失败,仅使用 STUN:", error);
|
||||||
|
}
|
||||||
|
|
||||||
this.peer = new PeerJs(sign2peerid(this.sign), {
|
this.peer = new PeerJs(sign2peerid(this.sign), {
|
||||||
config: {
|
config: {
|
||||||
iceServers: [{ urls: "stun:8.134.35.244:3478" }],
|
iceServers,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
this.peer.on("open", (id) => {
|
this.peer.on("open", (id) => {
|
||||||
|
|||||||
75
src/pages/file/utils/turn.ts
Normal file
75
src/pages/file/utils/turn.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import CryptoJS from "crypto-js";
|
||||||
|
|
||||||
|
export interface TurnCredentials {
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
expire: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IceServer {
|
||||||
|
urls: string | string[];
|
||||||
|
username?: string;
|
||||||
|
credential?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TURN_URLS: (string | string[])[] = ["turn:8.134.35.244:3478"];
|
||||||
|
|
||||||
|
function decryptTurn(dataBase64: string): TurnCredentials {
|
||||||
|
const secret = "kuraa.cc";
|
||||||
|
|
||||||
|
const raw = CryptoJS.enc.Base64.parse(dataBase64);
|
||||||
|
|
||||||
|
const iv = CryptoJS.lib.WordArray.create(raw.words.slice(0, 4), 16);
|
||||||
|
|
||||||
|
const ciphertext = CryptoJS.lib.WordArray.create(
|
||||||
|
raw.words.slice(4),
|
||||||
|
raw.sigBytes - 16,
|
||||||
|
);
|
||||||
|
|
||||||
|
const key = CryptoJS.MD5(secret);
|
||||||
|
|
||||||
|
const decrypted = CryptoJS.AES.decrypt(
|
||||||
|
{ ciphertext: ciphertext } as CryptoJS.lib.CipherParams,
|
||||||
|
key,
|
||||||
|
{
|
||||||
|
iv: iv,
|
||||||
|
mode: CryptoJS.mode.CBC,
|
||||||
|
padding: CryptoJS.pad.Pkcs7,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = decrypted.toString(CryptoJS.enc.Utf8);
|
||||||
|
|
||||||
|
return JSON.parse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchTurnServers(name: string): Promise<IceServer[]> {
|
||||||
|
const response = await fetch("https://kuraa.cc/api/rtc", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ name }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(
|
||||||
|
`TURN API error: ${response.status} ${response.statusText}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const encryptedData: string = await response.text();
|
||||||
|
|
||||||
|
const credentials: TurnCredentials = decryptTurn(encryptedData);
|
||||||
|
|
||||||
|
if (!TURN_URLS.length) {
|
||||||
|
console.warn("未配置 TURN 地址,请在 turn.ts 中配置 TURN_URLS");
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return TURN_URLS.map((urls) => ({
|
||||||
|
urls,
|
||||||
|
username: credentials.username,
|
||||||
|
credential: credentials.password,
|
||||||
|
}));
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user