新增turn

This commit is contained in:
kura 2026-05-09 18:21:10 +08:00
parent 76879af0c8
commit a8a1fe19ad
6 changed files with 9232 additions and 782 deletions

8502
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -16,14 +16,16 @@
},
"dependencies": {
"@dcloudio/uni-ui": "^1.4.28",
"@types/crypto-js": "^4.2.2",
"ant-design-vue": "4.x",
"crypto-js": "^4.2.0",
"highlight.js": "^11.11.1",
"peerjs": "^1.5.4",
"register-service-worker": "^1.7.2",
"three": "^0.172.0",
"vue": "^3.3.0",
"vue-i18n": "^9.1.9",
"vue-router": "^4.5.0",
"register-service-worker": "^1.7.2"
"vue-router": "^4.5.0"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.6.1",

View File

@ -318,8 +318,8 @@ const handleReceive = async () => {
await localCurrentFile.value.loadLocalDirectory();
};
//
onMounted(() => {
peer.init();
onMounted(async () => {
await peer.init();
peer.on("open", ((event: CustomEvent) => {
myId.value = event.detail;
const sign = getUrlParam("sign");

View File

@ -14,6 +14,7 @@ import {
getPermissionSet,
confirmWin,
} from "./common";
import { fetchTurnServers } from "./turn";
type MediaType = "desktop" | "call" | "camera";
// 发送超时时间(毫秒)
@ -43,10 +44,25 @@ class Peer extends EventTarget {
super();
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), {
config: {
iceServers: [{ urls: "stun:8.134.35.244:3478" }],
iceServers,
},
});
this.peer.on("open", (id) => {

View 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,
}));
}

1407
yarn.lock

File diff suppressed because it is too large Load Diff