我写了一个 Ajax 示例,它将在没有 socket.io 或其他任何东西的情况下共享 ICE 和 SDP。这可能有用
后端源代码发布在此存储库中
<span></span>
<div id="root"></div>
<script src="./peer-to-peer.js"></script>
<script>
(async function(global) {
const root = document.querySelector('#root');
const span = document.querySelector('span');
const peerHub = new Map();
global.peerHub = peerHub;
const sleep = (timeout = 1000) => new Promise((res) => setTimeout(() => res(), timeout));
const createVideo = (stream) => {
const video = document.createElement('video');
video.srcObject = stream;
root.appendChild(video);
video.play();
};
const request = async (url = '', params = {}) => {
const builder = new URL(url, location.origin);
Object.entries(params).forEach(([k, v]) => builder.searchParams.set(k, v));
const data = await fetch(builder.toString());
const json = await data.json();
return json;
};
const currentStream = await navigator.mediaDevices.getUserMedia({
video: {
facingMode: 'user',
width: {
min: 0,
max: window.screen.width,
},
height: {
min: 0,
max: window.screen.height,
},
},
});
const currentUserId = await request('api/join-room');
span.innerText = `Joined as user_${currentUserId}`;
createVideo(currentStream);
const createConnection = (toUserId = -1, initiator = false) => {
const p2p = new PeerToPeer({
mediaStream: currentStream,
fromUserId: currentUserId,
initiator,
toUserId,
});
p2p.on('stream', ({ stream }) => createVideo(stream));
p2p.on('sdp', ({ sdp, toUserId }) => {
console.log(`Outgoing sdp ${toUserId} ${Date.now()}`, { sdp });
request('api/create-sdp', {
currentUserId,
toUserId,
sdp,
});
});
p2p.on('ice', ({ ice, toUserId }) => {
console.log(`Outgoing ice ${toUserId} ${Date.now()}`, { ice });
request('api/create-ice', {
currentUserId,
toUserId,
ice,
});
});
peerHub.set(toUserId, p2p);
return p2p;
};
const userList = await request('api/user-list');
const targetList = userList.filter((id) => id !== currentUserId);
targetList.forEach((toUserId) => createConnection(toUserId, true));
const browseForIncomingSdp = async () => {
const sdpList = await request('api/read-sdp', {
currentUserId,
});
console.log({sdpList});
await Promise.all(sdpList.map(async ({
fromUserId,
sdp,
}) => {
await request('api/mark-sdp', {
currentUserId,
fromUserId,
});
if (peerHub.has(fromUserId)) {
console.log(`Incoming answer sdp ${fromUserId} ${Date.now()}`, { sdp });
const p2p = peerHub.get(fromUserId);
p2p.setRemoteSdp(sdp);
} else {
console.log(`Incoming offer sdp ${fromUserId} ${Date.now()}`, { sdp });
const p2p = createConnection(fromUserId, false);
p2p.setRemoteSdp(sdp);
}
}));
};
const browseForIncomingIce = async () => {
const iceList = await request('api/read-ice', {
currentUserId
});
console.log({iceList});
await Promise.all(iceList.map(async ({
fromUserId,
ice,
}) => {
await request('api/mark-ice', {
currentUserId,
fromUserId,
});
console.log(`Incoming ice ${fromUserId} ${Date.now()}`, { ice });
const p2p = peerHub.get(fromUserId);
p2p.setRemoteIce(ice);
}));
};
const tick = async () => {
await browseForIncomingSdp();
await browseForIncomingIce();
};
do {
await tick();
await sleep(5_000);
} while (true);
// button.addEventListener('click', tick);
})(window);
</script>