Bangun aplikasi web multipemain instan, tidak memerlukan server
COBA DEMOnya ?
trystero mengelola jaringan kurir rahasia yang memungkinkan pengguna aplikasi Anda berbicara langsung satu sama lain, terenkripsi dan tanpa perantara server.
Internet penuh dengan saluran komunikasi terbuka dan terdesentralisasi: pelacak torrent, broker perangkat IoT, protokol file butik, dan jejaring sosial khusus.
trystero mendukung jaringan ini untuk secara otomatis membuat koneksi p2p yang aman dan pribadi antara pengguna aplikasi Anda tanpa perlu usaha apa pun dari Anda.
Rekan dapat terhubung melalui ? BitTorrent, ? Sekarang, ? MQTT, ⚡️ Supabase, Firebase, atau ? IPFS – semuanya menggunakan API yang sama.
Selain membuat pencocokan rekan otomatis, trystero menawarkan beberapa abstraksi bagus di atas WebRTC:
Anda dapat melihat apa yang dibuat orang-orang dengan trystero di sini.
Jika Anda hanya ingin mencoba trystero , Anda dapat melewati penjelasan ini dan langsung menggunakannya.
Untuk membuat koneksi peer-to-peer langsung dengan WebRTC, diperlukan saluran sinyal untuk bertukar informasi peer (SDP). Biasanya hal ini melibatkan menjalankan server perjodohan Anda sendiri, tetapi trystero mengabstraksikannya untuk Anda dan menawarkan beberapa strategi "tanpa server" untuk menghubungkan rekan (saat ini BitTorrent, Nostr, MQTT, Supabase, Firebase, dan IPFS).
Hal penting yang perlu diingat adalah ini:
Selain penemuan rekan, data aplikasi Anda tidak pernah menyentuh media strategi dan dikirim langsung secara peer-to-peer dan dienkripsi secara end-to-end antar pengguna.
?
Anda dapat membandingkan strategi di sini.
Anda dapat menginstal dengan npm ( npm i trystero
) dan mengimpor seperti:
import { joinRoom } from ' trystero '
Atau mungkin Anda lebih suka tag skrip sederhana? Unduh file JS bawaan dari rilis terbaru dan impor secara lokal:
< script type =" module " >
import { joinRoom } from './ trystero -torrent.min.js'
</ script >
Secara default, strategi Nostr digunakan. Untuk menggunakan yang berbeda, cukup impor dalam seperti ini (bundel Anda harus menangani penyertaan hanya kode yang relevan):
import { joinRoom } from ' trystero /mqtt' // ( trystero -mqtt.min.js with a local file)
// or
import { joinRoom } from ' trystero /torrent' // ( trystero -torrent.min.js)
// or
import { joinRoom } from ' trystero /supabase' // ( trystero -supabase.min.js)
// or
import { joinRoom } from ' trystero /firebase' // ( trystero -firebase.min.js)
// or
import { joinRoom } from ' trystero /ipfs' // ( trystero -ipfs.min.js)
Selanjutnya, gabungkan pengguna ke ruangan dengan ID:
const config = { appId : 'san_narciso_3d' }
const room = joinRoom ( config , 'yoyodyne' )
Argumen pertama adalah objek konfigurasi yang memerlukan appId
. Ini harus menjadi pengenal yang benar-benar unik untuk aplikasi Anda¹. Argumen kedua adalah ID ruangan.
Mengapa kamar? Browser hanya dapat menangani koneksi WebRTC dalam jumlah terbatas pada satu waktu, jadi disarankan untuk merancang aplikasi Anda sedemikian rupa sehingga pengguna dibagi menjadi beberapa grup (atau ruang, atau ruang nama, atau saluran... apa pun sebutan Anda).
¹ Saat menggunakan Firebase, appId
harus menjadi databaseURL
Anda dan saat menggunakan Supabase, itu harus menjadi URL proyek Anda.
Dengarkan rekan-rekan yang bergabung dalam ruangan:
room . onPeerJoin ( peerId => console . log ( ` ${ peerId } joined` ) )
Dengarkan teman-teman yang meninggalkan ruangan:
room . onPeerLeave ( peerId => console . log ( ` ${ peerId } left` ) )
Dengarkan rekan-rekan yang mengirimkan aliran audio/video mereka:
room . onPeerStream (
( stream , peerId ) => ( peerElements [ peerId ] . video . srcObject = stream )
)
Untuk berhenti berlangganan acara, tinggalkan ruangan:
room . leave ( )
Anda dapat mengakses ID rekan pengguna lokal dengan mengimpor selfId
seperti:
import { selfId } from ' trystero '
console . log ( `my peer ID is ${ selfId } ` )
Kirimkan aliran video Anda kepada rekan-rekan:
room . addStream (
await navigator . mediaDevices . getUserMedia ( { audio : true , video : true } )
)
Kirim dan berlangganan tindakan P2P khusus:
const [ sendDrink , getDrink ] = room . makeAction ( 'drink' )
// buy drink for a friend
sendDrink ( { drink : 'negroni' , withIce : true } , friendId )
// buy round for the house (second argument omitted)
sendDrink ( { drink : 'mezcal' , withIce : false } )
// listen for drinks sent to you
getDrink ( ( data , peerId ) =>
console . log (
`got a ${ data . drink } with ${ data . withIce ? '' : 'out' } ice from ${ peerId } `
)
)
Anda juga dapat menggunakan tindakan untuk mengirim data biner, seperti gambar:
const [ sendPic , getPic ] = room . makeAction ( 'pic' )
// blobs are automatically handled, as are any form of TypedArray
canvas . toBlob ( blob => sendPic ( blob ) )
// binary data is received as raw ArrayBuffers so your handling code should
// interpret it in a way that makes sense
getPic (
( data , peerId ) => ( imgs [ peerId ] . src = URL . createObjectURL ( new Blob ( [ data ] ) ) )
)
Katakanlah kita ingin pengguna dapat memberi nama pada dirinya sendiri:
const idsToNames = { }
const [ sendName , getName ] = room . makeAction ( 'name' )
// tell other peers currently in the room our name
sendName ( 'Oedipa' )
// tell newcomers
room . onPeerJoin ( peerId => sendName ( 'Oedipa' , peerId ) )
// listen for peers naming themselves
getName ( ( name , peerId ) => ( idsToNames [ peerId ] = name ) )
room . onPeerLeave ( peerId =>
console . log ( ` ${ idsToNames [ peerId ] || 'a weird stranger' } left` )
)
Tindakannya cerdas dan menangani serialisasi dan pengelompokan untuk Anda di belakang layar. Ini berarti Anda dapat mengirim file yang sangat besar dan data apa pun yang Anda kirim akan diterima di sisi lain dengan tipe yang sama (angka sebagai angka, string sebagai string, objek sebagai objek, biner sebagai biner, dll.) .
Berikut ini contoh sederhana bagaimana Anda dapat membuat ruang obrolan audio:
// this object can store audio instances for later
const peerAudios = { }
// get a local audio stream from the microphone
const selfStream = await navigator . mediaDevices . getUserMedia ( {
audio : true ,
video : false
} )
// send stream to peers currently in the room
room . addStream ( selfStream )
// send stream to peers who join later
room . onPeerJoin ( peerId => room . addStream ( selfStream , peerId ) )
// handle streams from other peers
room . onPeerStream ( ( stream , peerId ) => {
// create an audio instance and set the incoming stream
const audio = new Audio ( )
audio . srcObject = stream
audio . autoplay = true
// add the audio to peerAudio object if you want to address it for something
// later (volume, etc.)
peerAudios [ peerId ] = audio
} )
Melakukan hal yang sama dengan video juga serupa, pastikan untuk menambahkan aliran masuk ke elemen video di DOM:
const peerVideos = { }
const videoContainer = document . getElementById ( 'videos' )
room . onPeerStream ( ( stream , peerId ) => {
let video = peerVideos [ peerId ]
// if this peer hasn't sent a stream before, create a video element
if ( ! video ) {
video = document . createElement ( 'video' )
video . autoplay = true
// add video element to the DOM
videoContainer . appendChild ( video )
}
video . srcObject = stream
peerVideos [ peerId ] = video
} )
Katakanlah aplikasi Anda mendukung pengiriman berbagai jenis file dan Anda ingin memberi anotasi pada byte mentah yang dikirim dengan metadata tentang cara menafsirkannya. Daripada menambahkan byte metadata ke buffer secara manual, Anda cukup meneruskan argumen metadata dalam tindakan pengirim untuk payload biner Anda:
const [ sendFile , getFile ] = makeAction ( 'file' )
getFile ( ( data , peerId , metadata ) =>
console . log (
`got a file ( ${ metadata . name } ) from ${ peerId } with type ${ metadata . type } ` ,
data
)
)
// to send metadata, pass a third argument
// to broadcast to the whole room, set the second peer ID argument to null
sendFile ( buffer , null , { name : 'The Courierʼs Tragedy' , type : 'application/pdf' } )
Fungsi pengirim tindakan mengembalikan janji yang terselesaikan setelah selesai mengirim. Secara opsional, Anda dapat menggunakan ini untuk menunjukkan kepada pengguna saat transfer dalam jumlah besar telah dilakukan.
await sendFile ( amplePayload )
console . log ( 'done sending to all peers' )
Fungsi pengirim tindakan juga menggunakan fungsi panggilan balik opsional yang akan terus dipanggil seiring kemajuan transmisi. Ini dapat digunakan untuk menunjukkan bilah kemajuan kepada pengirim untuk transfer dalam jumlah besar. Callback dipanggil dengan nilai persentase antara 0 dan 1 dan ID rekan penerima:
sendFile (
payload ,
// notice the peer target argument for any action sender can be a single peer
// ID, an array of IDs, or null (meaning send to all peers in the room)
[ peerIdA , peerIdB , peerIdC ] ,
// metadata, which can also be null if you're only interested in the
// progress handler
{ filename : 'paranoids.flac' } ,
// assuming each peer has a loading bar added to the DOM, its value is
// updated here
( percent , peerId ) => ( loadingBars [ peerId ] . value = percent )
)
Demikian pula, Anda dapat mendengarkan peristiwa kemajuan sebagai penerima seperti ini:
const [ sendFile , getFile , onFileProgress ] = room . makeAction ( 'file' )
onFileProgress ( ( percent , peerId , metadata ) =>
console . log (
` ${ percent * 100 } % done receiving ${ metadata . filename } from ${ peerId } `
)
)
Perhatikan bahwa metadata apa pun dikirim dengan peristiwa kemajuan sehingga Anda dapat menunjukkan kepada pengguna penerima bahwa ada transfer yang sedang berlangsung dengan mungkin nama file yang masuk.
Karena rekan dapat mengirimkan beberapa transmisi secara paralel, Anda juga dapat menggunakan metadata untuk membedakannya, misalnya dengan mengirimkan ID unik.
Setelah rekan-rekan terhubung satu sama lain, semua komunikasi mereka dienkripsi secara end-to-end. Selama proses koneksi/penemuan awal, SDP peer dikirim melalui media strategi peering yang dipilih. Secara default, SDP dienkripsi menggunakan kunci yang berasal dari ID aplikasi dan ID ruangan Anda untuk mencegah data sesi teks biasa muncul di log. Hal ini tidak masalah untuk sebagian besar kasus penggunaan, namun operator strategi relai dapat merekayasa balik kunci menggunakan ID ruangan dan aplikasi. Opsi yang lebih aman adalah dengan meneruskan parameter password
di objek konfigurasi aplikasi yang akan digunakan untuk mendapatkan kunci enkripsi:
joinRoom ( { appId : 'kinneret' , password : 'MuchoMaa$' } , 'w_a_s_t_e__v_i_p' )
Ini adalah rahasia bersama yang harus diketahui sebelumnya dan kata sandi harus cocok untuk semua rekan di ruangan agar mereka dapat terhubung. Contoh kasus penggunaan mungkin adalah ruang obrolan pribadi tempat pengguna mempelajari kata sandi melalui cara eksternal.
fungsi trystero bersifat idempoten sehingga sudah berfungsi langsung sebagai React hooks.
Berikut adalah contoh komponen sederhana di mana setiap rekan menyinkronkan warna favoritnya ke orang lain:
import { joinRoom } from ' trystero '
import { useState } from 'react'
const trystero Config = { appId : 'thurn-und-taxis' }
export default function App ( { roomId } ) {
const room = joinRoom ( trystero Config , roomId )
const [ sendColor , getColor ] = room . makeAction ( 'color' )
const [ myColor , setMyColor ] = useState ( '#c0ffee' )
const [ peerColors , setPeerColors ] = useState ( { } )
// whenever new peers join the room, send my color to them:
room . onPeerJoin ( peer => sendColor ( myColor , peer ) )
// listen for peers sending their colors and update the state accordingly:
getColor ( ( color , peer ) =>
setPeerColors ( peerColors => ( { ... peerColors , [ peer ] : color } ) )
)
const updateColor = e => {
const { value } = e . target
// when updating my own color, broadcast it to all peers:
sendColor ( value )
setMyColor ( value )
}
return (
< >
< h1 > trystero + React </ h1 >
< h2 > My color: </ h2 >
< input type = "color" value = { myColor } onChange = { updateColor } />
< h2 > Peer colors: </ h2 >
< ul >
{ Object . entries ( peerColors ) . map ( ( [ peerId , color ] ) => (
< li key = { peerId } style = { { backgroundColor : color } } >
{ peerId } : { color }
</ li >
) ) }
</ ul >
</ >
)
}
Pembaca yang cerdik mungkin menyadari bahwa contoh di atas sederhana dan tidak mempertimbangkan apakah kita ingin mengubah ID ruangan komponen atau melepasnya. Untuk skenario tersebut, Anda dapat menggunakan kait useRoom()
sederhana ini yang membatalkan langganan acara ruangan:
import { joinRoom } from ' trystero '
import { useEffect , useRef } from 'react'
export const useRoom = ( roomConfig , roomId ) => {
const roomRef = useRef ( joinRoom ( roomConfig , roomId ) )
const lastRoomIdRef = useRef ( roomId )
useEffect ( ( ) => {
if ( roomId !== lastRoomIdRef . current ) {
roomRef . current . leave ( )
roomRef . current = joinRoom ( roomConfig , roomId )
lastRoomIdRef . current = roomId
}
return ( ) => roomRef . current . leave ( )
} , [ roomConfig , roomId ] )
return roomRef . current
}
Untuk menggunakan strategi Supabase:
appId
di konfigurasi trystero , salin kunci API anon public
dan atur sebagai supabaseKey
di konfigurasi trysteroJika Anda ingin menggunakan strategi Firebase dan belum memiliki proyek:
databaseURL
dan gunakan sebagai appId
di konfigurasi trystero Anda{
"rules" : {
".read" : false ,
".write" : false ,
"__ trystero __" : {
".read" : false ,
".write" : false ,
"$room_id" : {
".read" : true ,
".write" : true
}
}
}
}
Aturan ini memastikan kehadiran rekan ruangan hanya dapat dibaca jika namespace ruangan diketahui sebelumnya.
joinRoom(config, roomId, [onError])
Menambahkan pengguna lokal ke ruang tempat rekan lain di namespace yang sama akan membuka saluran komunikasi dan mengirim acara. Memanggil joinRoom()
beberapa kali dengan namespace yang sama akan mengembalikan instance ruangan yang sama.
config
- Objek konfigurasi yang berisi kunci berikut:
appId
- (wajib) String unik yang mengidentifikasi aplikasi Anda. Saat menggunakan Supabase, ini harus disetel ke URL proyek Anda (lihat petunjuk penyiapan Supabase). Jika menggunakan Firebase, ini harus berupa databaseURL
dari konfigurasi Firebase Anda (lihat juga firebaseApp
di bawah untuk cara alternatif mengonfigurasi strategi Firebase).
password
- (opsional) Sebuah string untuk mengenkripsi deskripsi sesi melalui AES-GCM saat melewati media peering. Jika tidak disetel, deskripsi sesi akan dienkripsi dengan kunci yang berasal dari ID aplikasi dan nama ruangan. Kata sandi khusus harus cocok dengan semua rekan di ruangan agar mereka dapat terhubung. Lihat enkripsi untuk lebih jelasnya.
rtcConfig
- (opsional) Menentukan RTCConfiguration
khusus untuk semua koneksi rekan.
relayUrls
- (opsional, ? BitTorrent, ? Nostr, ? MQTT saja) Daftar URL khusus untuk strategi yang digunakan untuk mem-bootstrap koneksi P2P. Ini masing-masing adalah pelacak BitTorrent, relai Nostr, dan broker MQTT. Mereka harus mendukung koneksi WebSocket yang aman.
relayRedundancy
- (opsional, ? BitTorrent, ? Nostr, ? MQTT saja) Integer yang menentukan berapa banyak pelacak torrent yang akan dihubungkan secara bersamaan jika ada yang gagal. Meneruskan opsi relayUrls
akan menyebabkan opsi ini diabaikan karena seluruh daftar akan digunakan.
supabaseKey
- (wajib, ⚡️ Khusus Supabase) Kunci API anon public
proyek Supabase Anda.
firebaseApp
- (opsional, khusus Firebase) Anda dapat meneruskan instance aplikasi Firebase yang sudah diinisialisasi, bukan appId
. Biasanya trystero akan menginisialisasi aplikasi Firebase berdasarkan appId
tetapi ini akan gagal jika Anda sudah menginisialisasinya untuk digunakan di tempat lain.
rootPath
- (opsional, khusus Firebase) String yang menentukan jalur tempat trystero menulis data perjodohannya di database Anda ( '__ trystero __'
secara default). Mengubah ini berguna jika Anda ingin menjalankan beberapa aplikasi menggunakan database yang sama dan tidak ingin khawatir tentang tabrakan namespace.
libp2pConfig
- (opsional, ? IPFS saja) Libp2pOptions
tempat Anda dapat menentukan daftar rekan statis untuk bootstrapping.
roomId
- String untuk rekan namespace dan acara di dalam ruangan.
onError(details)
- (opsional) Fungsi panggilan balik yang akan dipanggil jika ruangan tidak dapat digabungkan karena kata sandi salah. details
adalah objek yang berisi appId
, roomId
, peerId
, dan error
yang menjelaskan kesalahan tersebut.
Mengembalikan objek dengan metode berikut:
leave()
Hapus pengguna lokal dari ruang dan berhenti berlangganan acara ruang.
getPeers()
Mengembalikan peta RTCPeerConnection
untuk rekan-rekan yang ada di ruangan (tidak termasuk pengguna lokal). Kunci dari objek ini adalah ID masing-masing rekan.
addStream(stream, [targetPeers], [metadata])
Menyiarkan aliran media ke rekan lain.
stream
- MediaStream
dengan audio dan/atau video untuk dikirim ke rekan-rekan di ruangan.
targetPeers
- (opsional) Jika ditentukan, aliran dikirim hanya ke ID rekan target (string) atau daftar ID rekan (array).
metadata
- (opsional) Metadata tambahan (jenis apa pun yang dapat diserialkan) untuk dikirim bersama aliran. Hal ini berguna saat mengirimkan beberapa aliran sehingga penerima mengetahui yang mana (misalnya webcam versus tangkapan layar). Jika Anda ingin menyiarkan streaming ke semua rekan di ruangan dengan argumen metadata, teruskan null
sebagai argumen kedua.
removeStream(stream, [targetPeers])
Berhenti mengirimkan aliran media yang dikirim sebelumnya ke rekan lain.
stream
- MediaStream
yang dikirim sebelumnya untuk berhenti mengirim.
targetPeers
- (opsional) Jika ditentukan, aliran hanya dihapus dari ID rekan target (string) atau daftar ID rekan (array).
addTrack(track, stream, [targetPeers], [metadata])
Menambahkan trek media baru ke aliran.
track
- MediaStreamTrack
untuk ditambahkan ke aliran yang ada.
stream
- MediaStream
target untuk melampirkan trek baru.
targetPeers
- (opsional) Jika ditentukan, trek hanya dikirim ke ID rekan target (string) atau daftar ID rekan (array).
metadata
- (opsional) Metadata tambahan (jenis serial apa pun) untuk dikirim bersama trek. Lihat catatan metadata
untuk addStream()
di atas untuk detail selengkapnya.
removeTrack(track, stream, [targetPeers])
Menghapus trek media dari aliran.
track
- MediaStreamTrack
yang akan dihapus.
stream
- MediaStream
tempat trek dilampirkan.
targetPeers
- (opsional) Jika ditentukan, trek hanya dihapus dari ID rekan target (string) atau daftar ID rekan (array).
replaceTrack(oldTrack, newTrack, stream, [targetPeers])
Mengganti trek media dengan yang baru.
oldTrack
- MediaStreamTrack
yang akan dihapus.
newTrack
- MediaStreamTrack
untuk dilampirkan.
stream
- MediaStream
yang dilampirkan oldTrack
.
targetPeers
- (opsional) Jika ditentukan, track diganti hanya untuk ID rekan target (string) atau daftar ID rekan (array).
onPeerJoin(callback)
Mendaftarkan fungsi panggilan balik yang akan dipanggil saat rekan bergabung ke ruangan. Jika dipanggil lebih dari sekali, hanya panggilan balik terakhir yang terdaftar yang akan dipanggil.
callback(peerId)
- Berfungsi untuk dijalankan setiap kali ada rekan yang bergabung, dipanggil dengan ID rekan tersebut.Contoh:
onPeerJoin ( peerId => console . log ( ` ${ peerId } joined` ) )
onPeerLeave(callback)
Mendaftarkan fungsi panggilan balik yang akan dipanggil ketika rekan meninggalkan ruangan. Jika dipanggil lebih dari sekali, hanya panggilan balik terakhir yang terdaftar yang akan dipanggil.
callback(peerId)
- Fungsi untuk dijalankan setiap kali rekan keluar, dipanggil dengan ID rekan.Contoh:
onPeerLeave ( peerId => console . log ( ` ${ peerId } left` ) )
onPeerStream(callback)
Mendaftarkan fungsi panggilan balik yang akan dipanggil ketika rekan mengirimkan aliran media. Jika dipanggil lebih dari sekali, hanya panggilan balik terakhir yang terdaftar yang akan dipanggil.
callback(stream, peerId, metadata)
- Berfungsi untuk dijalankan setiap kali rekan mengirimkan aliran media, yang dipanggil dengan aliran rekan, ID, dan metadata opsional (lihat addStream()
di atas untuk detailnya).Contoh:
onPeerStream ( ( stream , peerId ) =>
console . log ( `got stream from ${ peerId } ` , stream )
)
onPeerTrack(callback)
Mendaftarkan fungsi panggilan balik yang akan dipanggil ketika rekan mengirimkan trek media. Jika dipanggil lebih dari sekali, hanya panggilan balik terakhir yang terdaftar yang akan dipanggil.
callback(track, stream, peerId, metadata)
- Berfungsi untuk dijalankan setiap kali rekan mengirimkan trek media, dipanggil dengan trek rekan tersebut, aliran terlampir, ID, dan metadata opsional (lihat addTrack()
di atas untuk detailnya).Contoh:
onPeerTrack ( ( track , stream , peerId ) =>
console . log ( `got track from ${ peerId } ` , track )
)
makeAction(actionId)
Dengarkan dan kirim tindakan data khusus.
actionId
- Sebuah string untuk mendaftarkan tindakan ini secara konsisten di antara semua rekan.Mengembalikan array dengan tiga fungsi:
Mengirim data ke rekan-rekan dan mengembalikan janji yang diselesaikan ketika semua rekan target selesai menerima data.
(data, [targetPeers], [metadata], [onProgress])
data
- Nilai apa pun yang akan dikirim (primitif, objek, biner). Serialisasi dan chunking ditangani secara otomatis. Data biner (misalnya Blob
, TypedArray
) diterima oleh rekan lain sebagai ArrayBuffer
agnostik.
targetPeers
- (opsional) ID rekan (string), array ID rekan, atau null
(menunjukkan untuk mengirim ke semua rekan di ruangan).
metadata
- (opsional) Jika datanya biner, Anda dapat mengirimkan objek metadata opsional yang menjelaskannya (lihat Metadata biner).
onProgress
- (opsional) Fungsi panggilan balik yang akan dipanggil saat setiap potongan untuk setiap rekan dikirimkan. Fungsi tersebut akan dipanggil dengan nilai antara 0 dan 1 dan ID rekan. Lihat Pembaruan kemajuan sebagai contoh.
Mendaftarkan fungsi panggilan balik yang berjalan ketika data untuk tindakan ini diterima dari rekan lain.
(data, peerId, metadata)
data
- Nilai yang dikirimkan oleh rekan pengirim. Deserialisasi ditangani secara otomatis, yaitu suatu bilangan akan diterima sebagai suatu bilangan, suatu obyek sebagai suatu obyek, dan seterusnya.
peerId
- String ID dari rekan pengirim.
metadata
- (opsional) Objek metadata opsional disediakan oleh pengirim jika data
biner, misalnya nama file.
Mendaftarkan fungsi panggilan balik yang berjalan ketika sebagian data diterima dari rekan-rekan. Anda dapat menggunakan ini untuk melacak transfer biner besar. Lihat Pembaruan kemajuan sebagai contoh.
(percent, peerId, metadata)
percent
- Angka antara 0 dan 1 yang menunjukkan persentase selesainya transfer.
peerId
- String ID dari rekan pengirim.
metadata
- (opsional) Objek metadata opsional yang disediakan oleh pengirim.
Contoh:
const [ sendCursor , getCursor ] = room . makeAction ( 'cursormove' )
window . addEventListener ( 'mousemove' , e => sendCursor ( [ e . clientX , e . clientY ] ) )
getCursor ( ( [ x , y ] , peerId ) => {
const peerCursor = cursorMap [ peerId ]
peerCursor . style . left = x + 'px'
peerCursor . style . top = y + 'px'
} )
ping(peerId)
Mengambil ID rekan dan mengembalikan janji yang menyelesaikan hingga milidetik yang diperlukan untuk perjalanan pulang pergi ke rekan tersebut. Gunakan ini untuk mengukur latensi.
peerId
- String ID rekan dari rekan target.Contoh:
// log round-trip time every 2 seconds
room . onPeerJoin ( peerId =>
setInterval (
async ( ) => console . log ( `took ${ await room . ping ( peerId ) } ms` ) ,
2000
)
)
selfId
String ID unik yang akan diketahui rekan lain sebagai pengguna lokal secara global di seluruh ruangan.
getRelaySockets()
(? BitTorrent, ? Nostr, ? MQTT saja) Mengembalikan objek kunci URL relai yang dipetakan ke koneksi WebSocketnya. Hal ini berguna untuk menentukan status koneksi pengguna ke relay dan menangani kegagalan koneksi.
Contoh:
console . log ( trystero . getRelaySockets ( ) )
// => Object {
// "wss://tracker.webtorrent.dev": WebSocket,
// "wss://tracker.openwebtorrent.com": WebSocket
// }
getOccupants(config, roomId)
(Khusus Firebase) Mengembalikan janji yang menyelesaikan daftar ID pengguna yang ada di namespace yang diberikan. Ini berguna untuk memeriksa berapa banyak pengguna di suatu ruangan tanpa bergabung ke dalamnya.
config
- Objek konfigurasiroomId
- String namespace yang akan Anda teruskan ke joinRoom()
.Contoh:
console . log ( ( await trystero . getOccupants ( config , 'the_scope' ) ) . length )
// => 3
pengaturan satu kali¹ | ukuran bundel² | waktu untuk terhubung³ | |
---|---|---|---|
? hidung | tidak ada ? | 54K | ⏱️⏱️ |
? MQTT | tidak ada ? | 332K | ⏱️⏱️ |
? BitTorrent | tidak ada ? | 25K? | ⏱️⏱️ |
⚡️ Supabase | ~5 menit | 150K | ⏱️ ? |
basis api | ~5 menit | 177K | ⏱️ ? |
? IPFS | tidak ada ? | 945K | ⏱️⏱️ |
¹ Semua strategi kecuali Firebase tidak memerlukan penyiapan apa pun. Firebase adalah strategi terkelola yang memerlukan penyiapan akun.
² Dihitung melalui bundling Rollup + kompresi Terser.
³ Kecepatan relatif rekan-rekan yang terhubung satu sama lain saat bergabung dalam sebuah ruangan. Firebase hampir terjadi secara instan sementara strategi lainnya sedikit lebih lambat dalam bertukar informasi peering.
Keuntungan unik trystero adalah tidak memerlukan pengaturan backend dan menggunakan infrastruktur terdesentralisasi dalam banyak kasus. Hal ini memungkinkan eksperimen tanpa hambatan dan tidak ada satu titik kegagalan pun. Salah satu kelemahan potensial adalah sulitnya menjamin bahwa infrastruktur publik yang digunakan akan selalu tersedia, bahkan dengan teknik redundansi yang digunakan trystero . Meskipun strategi lainnya bersifat terdesentralisasi, strategi Supabase dan Firebase merupakan pendekatan yang lebih terkelola dengan kontrol lebih besar dan SLA, yang mungkin lebih sesuai untuk aplikasi “produksi”.
trystero mempermudah peralihan antar strategi — cukup ubah satu baris impor dan lakukan eksperimen dengan cepat:
import { joinRoom } from ' trystero /[torrent|nostr|mqtt|supabase|firebase|ipfs]'
trystero oleh Dan Motzenbecker