透過 WebRTC 在 Web 瀏覽器中執行 Web 伺服器
Smoke 讓瀏覽器能夠透過 WebRTC 運行微型 Web 伺服器
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 是一個實驗性瀏覽器網路和儲存框架,可透過 WebRTC 提供 Http、Tcp 和 WebSocket 模擬,並透過 IndexedDB 提供大型檔案儲存。它是作為在瀏覽器中開發對等 Web 服務的基礎而建構的,每個瀏覽器都可以透過應用程式控制的虛擬網路進行存取。
Smoke 將 WebRTC 重塑為 WinterCG 相容接口,使傳統 Web 伺服器應用程式能夠在伺服器和瀏覽器環境之間移植。它的開發是為了支援替代軟體架構,其中以用戶為中心的服務可以從雲端移出並在瀏覽器中點對點運行。
許可麻省理工學院
煙霧網路 API 透過網路物件提供。網路物件表示與共享訊號集線器的活動連接,並公開用於與連接到相同集線器的其他網路物件進行通訊的 Http、網路和媒體功能。
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.
專用集線器是記憶體中的中繼,它透過瀏覽器的 BroadcastChannel API 轉送 WebRTC ICE 訊息。專用中心只能將訊息中繼到同一瀏覽器進程中執行的頁面和其他標籤。由於專用集線器無法促進目前頁面以外的連接,因此它被視為專用。此集線器是預設的。
import { Network , Hubs } from '@sinclair/smoke'
const { Http } = new Network ( { hub : new Hubs . Private ( ) } )
該中心的實施目前正在等待中。
import { Network , Hubs } from '@sinclair/smoke'
const { Http } = new Network ( { hub : new Hubs . Public ( 'ws://server/hub' ) } )
Http API 支援透過 WebRTC 進行 Http 偵聽和取得。它還提供 WebSocket 模擬。
const { Http } = new Network ( )
使用listen函數接收來自遠端對等點的Http請求。
Http . listen ( { port : 5000 } , request => new Response ( 'hello' ) )
使用 fetch 函數向遠端對等點發出 Http 請求。
const response = await Http . fetch ( 'http://localhost:5000' )
const message = await response . text ( )
使用升級功能將Http請求轉換為WebSocket
Http . listen ( { port : 5000 } , request => Http . upgrade ( request , ( socket ) => socket . send ( 'hello' ) ) )
使用 connect 函數連接到遠端 WebSocket 伺服器。
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 ) )
Net API 透過 RTCDataChannel 提供 Tcp 仿真
const { Net } = new Network ( )
使用listen 函數接受傳入的套接字。
Net . listen ( { port : 5000 } , async socket => {
const data = await socket . read ( )
await socket . write ( data )
await socket . close ( )
} )
使用 connect 函數建立與遠端偵聽器的網路連線。
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
Media API 提供透過 WebRTC 傳送和接收 MediaStream 物件的功能。
const { Media } = new Network ( )
使用listen函式監聽傳入的MediaStream對象
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 ) )
} )
使用 send 函數將 MediaStream 傳送到偵聽器
const sender = await Media . send ( { hostname : 'localhost' , port : 6000 } , new MediaStream ( [ ... ] ) )
sender . close ( ) // stop sending live media
使用音訊函數建立可串流的音訊來源。
const audio = Media . audio ( { src : './audio.mp3' } )
const sender = Media . send ( { hostname : 'localhost' , port : 6000 } , audio . mediastream )
使用 video 函數建立可串流的 VideoSource。
const video = Media . video ( { src : './video.mp4' } )
const sender = Media . send ( { hostname : 'localhost' , port : 6000 } , video . mediastream )
使用pattern函數產生MediaStream測試模式。此功能對於在沒有網路攝影機或其他媒體來源的情況下測試即時媒體串流非常有用。
const pattern = Media . pattern ( )
const sender = Media . send ( { port : 5000 } , pattern . mediastream )
Smoke 提供了一個分層檔案系統,能夠在瀏覽器中儲存大檔案。該檔案系統由 IndexedDB 支持,支援串流讀寫、目錄枚舉、複製、移動、重新命名以及檔案和目錄監視事件。它被設計為充當網路服務的靜態文件存儲,但也可以用作需要在瀏覽器中存儲大文件的應用程式的通用文件系統。
使用 open 函數開啟具有給定資料庫名稱的檔案系統。如果資料庫不存在,則會建立該資料庫。
import { FileSystem } from '@sinclair/smoke'
const Fs = await FileSystem . open ( '<database-name>' )
使用 stat 函數傳回有關檔案或目錄的資訊。
const stat = await Fs . write ( '/path/file.txt' )
使用exists函數檢查路徑是否存在。
const exists = await Fs . exists ( '/path/file.txt' )
使用 mkdir 函數建立目錄。
await Fs . mkdir ( '/media/videos' )
使用 readdir 函數傳回給定目錄路徑的 stat 物件。
const stats = await Fs . readdir ( '/media/videos' )
使用 blob 函數將 Blob 物件傳回檔案路徑。
const blob = await Fs . readdir ( '/video.mp4' )
const url = URL . createObjectUrl ( blob )
使用 write 和 writeText 函數寫入檔案內容。
await Fs . write ( '/path/file.dat' , new Uint8Array ( [ 1 , 2 , 3 , 4 ] ) )
await Fs . writeText ( '/path/file.txt' , 'hello world' )
使用 read 和 readText 函數將從檔案中讀取內容。
const buffer = await fs . read ( '/path/file.dat' )
const content = await Fs . readText ( '/path/file.txt' )
使用刪除功能可以刪除檔案或目錄。
await Fs . delete ( '/path/file.txt' )
使用重新命名功能可以重新命名檔案或目錄。
await Fs . writeText ( '/path/fileA.txt' , '...' )
await Fs . rename ( '/path/fileA.txt' , 'fileB.txt' )
使用複製功能將檔案或目錄複製到目標目錄中。
await Fs . writeText ( '/path/fileA.txt' , '...' )
await Fs . copy ( '/path/fileA.txt' , '/backup' )
使用 move 函數將檔案或目錄移到目標目錄。
await Fs . writeText ( '/path/fileA.txt' , '...' )
await Fs . move ( '/path/fileA.txt' , '/backup' )
使用 watch 函數來監視檔案和目錄事件。
Fs . watch ( '/dir' , event => console . log ( event ) )
Smoke 對社區貢獻開放。請確保在提交拉取請求之前提交一個未解決的問題。 Smoke 專案在接受新功能之前更喜歡公開的社群討論。