Führen Sie Webserver in Webbrowsern über WebRTC aus
Smoke ermöglicht Browsern die Ausführung von Mikro-Webservern über WebRTC
import { Network } from '@sinclair/smoke'
// ------------------------------------------------------------------
//
// Create a Virtual Network
//
// ------------------------------------------------------------------
const { Http } = new Network ( )
// ------------------------------------------------------------------
//
// Create a Http Listener on a Virtual Port
//
// ------------------------------------------------------------------
Http . listen ( { port : 5000 } , request => new Response ( 'hello webrtc' ) )
// ------------------------------------------------------------------
//
// Fetch data over WebRTC
//
// ------------------------------------------------------------------
const text = Http . fetch ( 'http://localhost:5000' ) . then ( r => r . text ( ) )
$ npm install @sinclair/smoke
Smoke ist ein experimentelles Browser-Netzwerk- und Speicher-Framework, das HTTP-, TCP- und WebSocket-Emulation über WebRTC und die Speicherung großer Dateien über IndexedDB ermöglicht. Es dient als Grundlage für die Entwicklung von Peer-to-Peer-Webdiensten im Browser, wobei jeder Browser über ein anwendungsgesteuertes virtuelles Netzwerk zugänglich ist.
Smoke formt WebRTC in WinterCG-kompatible Schnittstellen um und ermöglicht so die Portabilität herkömmlicher Webserveranwendungen zwischen Server- und Browserumgebungen. Es wurde zur Unterstützung alternativer Softwarearchitekturen entwickelt, bei denen benutzerzentrierte Dienste aus der Cloud verlagert und Peer-to-Peer im Browser ausgeführt werden können.
Lizenz MIT
Smoke-Netzwerk-APIs werden über Netzwerkobjekte bereitgestellt. Ein Netzwerkobjekt stellt eine aktive Verbindung zu einem gemeinsam genutzten Signalisierungs-Hub dar und stellt die HTTP-, Netz- und Medienfunktionen bereit, die zur Kommunikation mit anderen Netzwerkobjekten verwendet werden, die mit demselben Hub verbunden sind.
import { Network , Hubs } from '@sinclair/smoke'
const { Http , Net , Media , Hub } = new Network ( { hub : new Hubs . Private ( ) } )
const address = await Hub . address ( ) // The address of this Network object.
Ein privater Hub ist ein In-Memory-Relay, das WebRTC-ICE-Nachrichten über die BroadcastChannel-API des Browsers weiterleitet. Ein privater Hub kann Nachrichten nur an die Seite und andere Registerkarten weiterleiten, die innerhalb desselben Browserprozesses ausgeführt werden. Da private Hubs keine Verbindungen ermöglichen, die außerhalb der aktuellen Seite hergestellt werden, gelten sie als privat. Dieser Hub ist der Standard.
import { Network , Hubs } from '@sinclair/smoke'
const { Http } = new Network ( { hub : new Hubs . Private ( ) } )
Die Implementierung dieses Hubs steht derzeit noch aus.
import { Network , Hubs } from '@sinclair/smoke'
const { Http } = new Network ( { hub : new Hubs . Public ( 'ws://server/hub' ) } )
Die HTTP-API unterstützt HTTP-Listen und -Abruf über WebRTC. Es bietet auch eine WebSocket-Emulation.
const { Http } = new Network ( )
Verwenden Sie die Listen-Funktion, um HTTP-Anfragen von Remote-Peers zu empfangen.
Http . listen ( { port : 5000 } , request => new Response ( 'hello' ) )
Verwenden Sie die Abruffunktion, um eine HTTP-Anfrage an Remote-Peers zu stellen.
const response = await Http . fetch ( 'http://localhost:5000' )
const message = await response . text ( )
Verwenden Sie die Upgrade-Funktion, um eine HTTP-Anfrage in einen WebSocket umzuwandeln
Http . listen ( { port : 5000 } , request => Http . upgrade ( request , ( socket ) => socket . send ( 'hello' ) ) )
Verwenden Sie die Verbindungsfunktion, um eine Verbindung zu einem Remote-WebSocket-Server herzustellen.
const socket = await Http . connect ( 'ws://localhost:5000' )
socket . on ( 'message' , ( event ) => console . log ( event . data ) )
socket . on ( 'error' , ( event ) => console . log ( event ) )
socket . on ( 'close' , ( event ) => console . log ( event ) )
Die Net-API bietet TCP-Emulation über RTCDataChannel
const { Net } = new Network ( )
Verwenden Sie die Listen-Funktion, um einen eingehenden Socket zu akzeptieren.
Net . listen ( { port : 5000 } , async socket => {
const data = await socket . read ( )
await socket . write ( data )
await socket . close ( )
} )
Verwenden Sie die Verbindungsfunktion, um eine Netzverbindung zu einem Remote-Listener herzustellen.
const socket = await Net . connect ( { hostname : 'localhost' , port : 5000 } )
await socket . write ( new Uint8Array ( 1000 ) )
const data = await socket . read ( ) // Uint8Array()
const end = await socket . read ( ) // null
Die Medien-API bietet Funktionen zum Senden und Empfangen von MediaStream-Objekten über WebRTC.
const { Media } = new Network ( )
Verwenden Sie die Listen-Funktion, um auf eingehende MediaStream-Objekte zu warten
Media . listen ( { port : 6000 } , ( receiver ) => {
const video = document . createElement ( 'video' )
video . srcObject = receiver . mediastream
video . play ( )
document . body . appendChild ( video )
receiver . on ( 'close' , ( ) => document . removeChild ( video ) )
} )
Verwenden Sie die Sendefunktion, um einen MediaStream an einen Listener zu senden
const sender = await Media . send ( { hostname : 'localhost' , port : 6000 } , new MediaStream ( [ ... ] ) )
sender . close ( ) // stop sending live media
Verwenden Sie die Audiofunktion, um eine streambare AudioSource zu erstellen.
const audio = Media . audio ( { src : './audio.mp3' } )
const sender = Media . send ( { hostname : 'localhost' , port : 6000 } , audio . mediastream )
Verwenden Sie die Videofunktion, um eine streambare VideoSource zu erstellen.
const video = Media . video ( { src : './video.mp4' } )
const sender = Media . send ( { hostname : 'localhost' , port : 6000 } , video . mediastream )
Verwenden Sie die Musterfunktion, um ein MediaStream-Testmuster zu generieren. Diese Funktion kann nützlich sein, um Live-Medien-Streaming ohne Webcams oder andere Medienquellen zu testen.
const pattern = Media . pattern ( )
const sender = Media . send ( { port : 5000 } , pattern . mediastream )
Smoke bietet ein hierarchisches Dateisystem, mit dem große Dateien im Browser gespeichert werden können. Das Dateisystem wird von IndexedDB unterstützt und unterstützt Streaming-Lesen und -Schreiben, Verzeichnisaufzählung, Kopieren, Verschieben, Umbenennen sowie Datei- und Verzeichnisüberwachungsereignisse. Es dient als statischer Dateispeicher für Netzwerkdienste, kann aber auch als allgemeines Dateisystem für Anwendungen verwendet werden, die große Dateien im Browser speichern müssen.
Verwenden Sie die Funktion open, um ein Dateisystem mit dem angegebenen Datenbanknamen zu öffnen. Wenn die Datenbank nicht existiert, wird sie erstellt.
import { FileSystem } from '@sinclair/smoke'
const Fs = await FileSystem . open ( '<database-name>' )
Verwenden Sie die Stat-Funktion, um Informationen zu einer Datei oder einem Verzeichnis zurückzugeben.
const stat = await Fs . write ( '/path/file.txt' )
Verwenden Sie die Funktion „exists“, um zu überprüfen, ob ein Pfad vorhanden ist.
const exists = await Fs . exists ( '/path/file.txt' )
Verwenden Sie die Funktion mkdir, um ein Verzeichnis zu erstellen.
await Fs . mkdir ( '/media/videos' )
Verwenden Sie die Funktion readdir, um Statistikobjekte für den angegebenen Verzeichnispfad zurückzugeben.
const stats = await Fs . readdir ( '/media/videos' )
Verwenden Sie die Blob-Funktion, um ein Blob-Objekt an einen Dateipfad zurückzugeben.
const blob = await Fs . readdir ( '/video.mp4' )
const url = URL . createObjectUrl ( blob )
Verwenden Sie die Funktionen write und writeText, um Dateiinhalte zu schreiben.
await Fs . write ( '/path/file.dat' , new Uint8Array ( [ 1 , 2 , 3 , 4 ] ) )
await Fs . writeText ( '/path/file.txt' , 'hello world' )
Verwenden Sie die Funktionen read und readText, um Inhalte aus einer Datei zu lesen.
const buffer = await fs . read ( '/path/file.dat' )
const content = await Fs . readText ( '/path/file.txt' )
Verwenden Sie die Löschfunktion, um eine Datei oder ein Verzeichnis zu löschen.
await Fs . delete ( '/path/file.txt' )
Verwenden Sie die Umbenennungsfunktion, um eine Datei oder ein Verzeichnis umzubenennen.
await Fs . writeText ( '/path/fileA.txt' , '...' )
await Fs . rename ( '/path/fileA.txt' , 'fileB.txt' )
Mit der Kopierfunktion können Sie eine Datei oder ein Verzeichnis in ein Zielverzeichnis kopieren.
await Fs . writeText ( '/path/fileA.txt' , '...' )
await Fs . copy ( '/path/fileA.txt' , '/backup' )
Mit der Move-Funktion können Sie eine Datei oder ein Verzeichnis in ein Zielverzeichnis verschieben.
await Fs . writeText ( '/path/fileA.txt' , '...' )
await Fs . move ( '/path/fileA.txt' , '/backup' )
Verwenden Sie die Überwachungsfunktion, um auf Datei- und Verzeichnisereignisse zu achten.
Fs . watch ( '/dir' , event => console . log ( event ) )
Smoke ist offen für Gemeinschaftsbeiträge. Bitte stellen Sie sicher, dass Sie ein offenes Problem einreichen, bevor Sie Ihre Pull-Anfrage einreichen. Das Smoke-Projekt bevorzugt eine offene Community-Diskussion, bevor es neue Funktionen akzeptiert.