Giới thiệu về kết nối P2P trong trình duyệt
Để thiết lập kết nối trực tiếp giữa hai trình duyệt (peer-to-peer) trong HTML, chúng ta sử dụng WebRTC thông qua thư viện PeerJS - một wrapper đơn giản hóa API WebRTC phức tạp.
Các bước thực hiện
1. Nhúng thư viện PeerJS
Thêm script sau vào trang HTML của bạn (khuyên dùng phiên bản mới nhất từ CDN):
<script src="https://cdn.peerjs.com/1.5.2/peer.min.js"></script>
2. Tạo Peer instance
Mỗi trình duyệt cần một ID duy nhất và API key (có thể lấy miễn phí từ PeerJS Server hoặc tự host server):
// Cú pháp: new Peer(id, options)
var peer = new Peer('user-unique-id', {
host: 'peerjs-server.herokuapp.com', // hoặc server tự host
port: 443,
path: '/',
secure: true,
key: 'your-api-key' // API key từ PeerJS Cloud
});
3. Xử lý kết nối
Phía người khởi tạo kết nối (caller):
// Kết nối đến peer khác
var conn = peer.connect('another-peer-id');
conn.on('open', function() {
console.log('Đã kết nối thành công!');
conn.send('Xin chào từ peer A!');
});
// Nhận tin nhắn
conn.on('data', function(data) {
console.log('Nhận được:', data);
});
Phía người nhận kết nối (callee):
peer.on('connection', function(conn) {
conn.on('data', function(data) {
console.log('Nhận được:', data);
conn.send('Xin chào từ peer B!');
});
});
4. Xử lý sự kiện quan trọng
peer.on('open', function(id) {
console.log('My peer ID is: ' + id);
});
peer.on('error', function(err) {
console.error('Lỗi:', err);
});
peer.on('disconnected', function() {
console.log('Mất kết nối với server');
});
peer.on('close', function() {
console.log('Kết nối peer đã đóng');
});
Lưu ý quan trọng
- Cần server signaling (PeerJS Server) để trao đổi metadata ban đầu
- Đối với production, nên tự host PeerJS Server để kiểm soát hoàn toàn
- WebRTC yêu cầu HTTPS (trừ localhost) để truy cập camera/microphone
- NAT traversal được xử lý tự động qua STUN/TURN servers
Mở rộng: Video/Audio Call
PeerJS cũng hỗ trợ gọi video/đ thoại:
// Người gọi
var call = peer.call('another-peer-id', localStream);
call.on('stream', function(remoteStream) {
// Hiển thị video remote
document.getElementById('remote-video').srcObject = remoteStream;
});
// Người nhận
peer.on('call', function(call) {
call.answer(localStream);
call.on('stream', function(remoteStream) {
document.getElementById('remote-video').srcObject = remoteStream;
});
});