chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

深入地研究WebRTC!Websocket服務器JscodeReact前端編碼器

LiveVideoStack ? 來源:LiveVideoStack ? 2020-09-22 09:58 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

我的動機 我們的目標是制作一個精簡易用的點對點文件共享網(wǎng)絡應用程序,將更多的精力投入到用戶體驗與簡單地辦事上。這個網(wǎng)絡應用程序不只是針對特定的個人群體服務的,而是針對整個社區(qū)服務。 既然有這么多文件共享網(wǎng)站,為什么我們還要做這些呢? 當然,我也思考過這個問題,但所有的這些網(wǎng)站都沒有真正地說明過這些文件在哪里共享或存儲。這可能是一種隱私威脅,因為在當前疫情的情況下,許多人或許經(jīng)常使用這些服務來共享文件甚至機密文件。使用安全的點對點連接和它的數(shù)據(jù)通道可以傳輸大量的文件,卻不需要存儲在任何服務器上,這使得它真正地結實與私有,因為只有連接的客戶端/對等端直接與中間服務器通信,不需要中間服務器進行傳輸。 WebRTC使對等連接和數(shù)據(jù)通道成為可能。WebRTC基本上是一種相互通信與傳送數(shù)據(jù)的全球網(wǎng)絡方式,類似于藍牙、NFC和WIFI數(shù)據(jù)共享。我們可以使用WebRTC實現(xiàn)跨平臺支持,因為它是基于網(wǎng)絡的。 讓我們更深入地研究WebRTC。 WebRTC

“WebRTC是一個免費的開放項目,通過簡單的APIs為瀏覽器與移動應用程序提供實時通信(RTC)功能。WebRTC組件已經(jīng)進行了優(yōu)化,以更好地滿足這一目的?!?webrtc.org

好吧,假設,一個“點對點”關聯(lián)考慮兩部設備之間發(fā)送的直接信息,而不需要服務器保存這些信息。聽起來這對我們的情況很理想對吧?不幸的是,這不是WebRTC工作的方式!

圖為使用WebRTC進行數(shù)據(jù)傳輸 盡管WebRTC實現(xiàn)了點對點連接,但它確實需要一個稱為信令服務器的服務器,該服務器用于共享有關預期將其相互連接的設備的數(shù)據(jù)。這些微妙之處可以通過任何傳統(tǒng)的信息共享技術來共享。WebSockets在這里受到青睞,因為它減少了在一個龐大的建立關聯(lián)的系統(tǒng)中共享這些額外數(shù)據(jù)的惰性。 簡而言之,信令服務器幫助建立連接,然而,當連接建立后,服務器將不再涉及相關設備之間共享的信息。 一年前,當我開始我的第一個WebRTC項目時,很難找到一個在“production”級別下工作得像樣的模型。后來我在網(wǎng)上找到了這個Youtube頻道編碼。開發(fā)人員給出了關于可用于生產(chǎn)的WebRTC應用程序的一些很好的例子。 WebRTC如何創(chuàng)建一個連接(技術) 好吧,沒有簡單的方法來解釋這一點,但我的看法是,在網(wǎng)絡上所有數(shù)量可觀的設備中,無論如何都必須有一個設備通過產(chǎn)生信號來啟動連接,并將其發(fā)送到信令服務器上。這個對等點被稱為啟動器,在simple-peer(此項目中使用的模塊)中,當創(chuàng)建一個啟動器對等點時,{initiator:true}會被傳遞給制作者/構造函數(shù)。

如圖:信號服務器在運行 當我們得到對等點的信號信息時,這些信息應該通過某種方式通過信令服務器發(fā)送到不同的集線器。不同的集線器獲取此信息并嘗試與發(fā)起程序建立關聯(lián)。在這個過程中,這些對等體同樣產(chǎn)生它們的信號信息并被發(fā)送給發(fā)起方。發(fā)起方獲取此信息并嘗試與其余對等方建立連接。 瞧!這些設備現(xiàn)在已經(jīng)連接起來,現(xiàn)在有一個數(shù)據(jù)通道,可以在沒有中間服務器的情況下共享信息。 盡量不要過分強調(diào)你無法理解WebRTC的上述工作方式以及簡單對等點如何把它抽象化。當我一開始擺弄WebRTC時,它嚇了我一大跳。接下來的部分將對這一點進行更簡單和細致的解釋。 與WebRTC共享文件(使用simple-peer)

const express = require("express"); const http = require("http"); const app = express(); const server = http.createServer(app); const socket = require("socket.io"); const io = socket(server); const users = {}; const socketToRoom = {}; io.on('connection', socket => { socket.on("join room", roomID => { if (users[roomID]) { const length = users[roomID].length; if (length === 2) { socket.emit("room full"); return; } users[roomID].push(socket.id); } else { users[roomID] = [socket.id]; } socketToRoom[socket.id] = roomID; const usersInThisRoom = users[roomID].filter(id => id !== socket.id); socket.emit("all users", usersInThisRoom); }); socket.on("sending signal", payload => { io.to(payload.userToSignal).emit('user joined', { signal: payload.signal, callerID: payload.callerID }); }); socket.on("returning signal", payload => { io.to(payload.callerID).emit('receiving returned signal', { signal: payload.signal, id: socket.id }); }); socket.on('disconnect', () => { const roomID = socketToRoom[socket.id]; let room = users[roomID]; if (room) { room = room.filter(id => id !== socket.id); users[roomID] = room; socket.broadcast.emit('user left', socket.id); } }); }); server.listen(process.env.PORT || 8000, () => console.log('server is running on port 8000')); Websocket服務器JscodeReact前端編碼器

import React, { useEffect, useRef, useState } from "react";import io from "socket.io-client";import Peer from "simple-peer";import styled from "styled-components";import streamSaver from "streamsaver"; const Container = styled.div` padding: 20px; display: flex; height: 100vh; width: 90%; margin: auto; flex-wrap: wrap;`; const worker = new Worker("../worker.js"); const Room = (props) => { const [connectionEstablished, setConnection] = useState(false); const [file, setFile] = useState(); const [gotFile, setGotFile] = useState(false); const chunksRef = useRef([]); const socketRef = useRef(); const peersRef = useRef([]); const peerRef = useRef(); const fileNameRef = useRef(""); const roomID = props.match.params.roomID; useEffect(() => { socketRef.current = io.connect("/"); socketRef.current.emit("join room", roomID); socketRef.current.on("all users", users => { peerRef.current = createPeer(users[0], socketRef.current.id); }); socketRef.current.on("user joined", payload => { peerRef.current = addPeer(payload.signal, payload.callerID); }); socketRef.current.on("receiving returned signal", payload => { peerRef.current.signal(payload.signal); setConnection(true); }); socketRef.current.on("room full", () => { alert("room is full"); }) }, []); function createPeer(userToSignal, callerID) { const peer = new Peer({ initiator: true, trickle: false, }); peer.on("signal", signal => { socketRef.current.emit("sending signal", { userToSignal, callerID, signal }); }); peer.on("data", handleReceivingData); return peer; } function addPeer(incomingSignal, callerID) { const peer = new Peer({ initiator: false, trickle: false, }); peer.on("signal", signal => { socketRef.current.emit("returning signal", { signal, callerID }); }); peer.on("data", handleReceivingData); peer.signal(incomingSignal); setConnection(true); return peer; } function handleReceivingData(data) { if (data.toString().includes("done")) { setGotFile(true); const parsed = JSON.parse(data); fileNameRef.current = parsed.fileName; } else { worker.postMessage(data); } } function download() { setGotFile(false); worker.postMessage("download"); worker.addEventListener("message", event => { const stream = event.data.stream(); const fileStream = streamSaver.createWriteStream(fileNameRef.current); stream.pipeTo(fileStream); }) } function selectFile(e) { setFile(e.target.files[0]); } function sendFile() { const peer = peerRef.current; const stream = file.stream(); const reader = stream.getReader(); reader.read().then(obj => { handlereading(obj.done, obj.value); }); function handlereading(done, value) { if (done) { peer.write(JSON.stringify({ done: true, fileName: file.name })); return; } peer.write(value); reader.read().then(obj => { handlereading(obj.done, obj.value); }) } } let body; if (connectionEstablished) { body = (

); } else { body = (

Once you have a peer connection, you will be able to share files

); } let downloadPrompt; if (gotFile) { downloadPrompt = (
You have received a file. Would you like to download the file?
); } return ( {body} {downloadPrompt} );}; export default Room; 在此Repo上找到整個代碼。如果你在瀏覽器中嘗試應用上述代碼并選擇一些圖片文件(最好小于100KB),它會立即下載這些圖片文件。這是因為這個對等點位于一個類似的瀏覽器中,而發(fā)送方處于提示狀態(tài)。 傳送和獲取的信息的大小是相等的。這表明我們可以選擇一次性移動整個記錄! 為什么使用數(shù)據(jù)緩沖區(qū)而不是blob? 在我們過去的代碼中,如果我們選擇了一個巨大的文件(大于100KB),那么文檔很可能不會被發(fā)送,這是WebRTC通道的某些約束的直接結果。

如圖:數(shù)組緩沖區(qū)漫畫插圖(mozilla.org) 每個數(shù)組緩沖區(qū)一次只能有16KB的限制。簡而言之,這意味著我們必須將文檔劃分成小數(shù)組緩沖區(qū)。 小文件可以通過WebRTC一次性發(fā)處,然而,對于大文檔,明智的做法是將文件隔離到較小的數(shù)組緩沖區(qū)中,并同樣發(fā)送每個部分。ArrayBuffer和Blob對象都有削減容量,這使得此過程更加簡單。為此,如果你仔細查看代碼,你會發(fā)現(xiàn)我們使用了一個名為stream saver的模塊,它可以將數(shù)組緩沖區(qū)轉換回blob。 筆記 因為javascript是單線程的。處理大量數(shù)組緩沖區(qū)可能導致漂亮的UI無法響應。為了解決這個問題,我們將使用服務工作人員。一個服務工作人員是瀏覽器在后臺運行的腳本,是與Web頁面分離的,這為不需要Web頁面或用戶交互的特性打開大門。

let array = [];self.addEventListener("message", event => { if (event.data === "download") { const blob = new Blob(array); self.postMessage(blob); array = []; } else if (event.data === "abort") { array = []; } else { array.push(event.data); }}) 在服務工作程序中處理數(shù)組緩沖區(qū) 將文件劃分為數(shù)組緩沖區(qū)的優(yōu)點 雖然它可能會感覺分隔文件只是一些額外的代碼,并且會讓東西相互糾纏,但我們得到以下好處,并且可以幫助改進我們的文檔共享應用程序。

跨平臺支持(由mozilla.org提供說明)

支持幾乎所有的瀏覽器

支持龐大的文檔大小——正如前面提到的,這是我們?yōu)槭裁匆獙崿F(xiàn)它的基本解釋。

一個更好的方法來破譯所發(fā)送信息的度量——通過在緩沖區(qū)中發(fā)送一個記錄,我們現(xiàn)在可以顯示信息,例如,發(fā)送的文檔的級別,發(fā)送記錄的速度等等。

識別未完成發(fā)送的文件——在無法完全發(fā)送文件的情況下,現(xiàn)在能夠以不同的方式獲取和處理文件。

結論 由于我們有一個使用WebRTC的文檔直接共享程序,而且它還利用了ArrayBuffer,我們現(xiàn)在應該開始考慮為應用程序的生產(chǎn)做準備的東西了。這些細節(jié)需要更多的探索,而不僅僅是遵循一個直接的教程。 可以補充的更多內(nèi)容:

信令服務器(STUN和TURN服務器)。

使多個對等連接可拓展。

當WebRTC不能工作時才用的一種混合共享方式。

提高傳輸效率和速度。

我希望我已經(jīng)提供了足夠的信息讓你們開始使用WebRTC應用程序。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 編碼器
    +關注

    關注

    45

    文章

    3929

    瀏覽量

    141982
  • 服務器
    +關注

    關注

    14

    文章

    10182

    瀏覽量

    91244
  • WebRTC
    +關注

    關注

    0

    文章

    57

    瀏覽量

    11896

原文標題:使用Webrtc和React Js在網(wǎng)絡上共享跨平臺的點對點文件

文章出處:【微信號:livevideostack,微信公眾號:LiveVideoStack】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    Vishay USB編碼器接口技術解析與應用指南

    Vishay/MCB Industrie RAMK/RAME USB編碼器接口是一款設計用于Vishay MCB編碼器(AMK和RAME系列,包括霍爾效應)的電子板。該接口板只需使用隨附的USB
    的頭像 發(fā)表于 11-12 11:51 ?650次閱讀

    雷恩PRECILEC重載式編碼器:重載工況,精準穩(wěn)定#編碼器

    編碼器
    開地電子
    發(fā)布于 :2025年10月31日 16:18:04

    雷恩 PRECILEC 重載編碼器:重載不 “失準”,穩(wěn)定超預期#編碼器

    編碼器
    開地電子
    發(fā)布于 :2025年10月31日 15:59:24

    一文吃透WebSocket:智能物聯(lián)網(wǎng)通信的入門與實戰(zhàn)全攻略!

    解決方案,助你輕松掌握這一核心技術。 一、WebSocket基礎知識 1.1 ?什么是Websocket? WebSocket是HTML5下一種新的協(xié)議(本質上是一個基于TCP的協(xié)議),主要解決傳統(tǒng)HTTP協(xié)議在 “實時通信”
    的頭像 發(fā)表于 10-15 18:16 ?322次閱讀
    一文吃透<b class='flag-5'>WebSocket</b>:智能物聯(lián)網(wǎng)通信的入門與實戰(zhàn)全攻略!

    Bourns發(fā)布全新增量式微型編碼器

    Bourns 推出 PEC04 系列 4 mm 增量式微型編碼器、PEC05 PEC05 系列 5 mm 增量式微型編碼器,以及 PEC06 型號 6 mm 增量式微型編碼器。Bourns 全新微型
    的頭像 發(fā)表于 09-22 16:05 ?1211次閱讀

    深入ZMC900E:主站控制編碼器的使用與優(yōu)勢

    視頻推薦在工業(yè)自動化領域,編碼器是確保設備精準運行的關鍵部件。本期我們將深入探討ZMC900E主站控制中的編碼器功能。編碼器
    的頭像 發(fā)表于 09-11 11:34 ?625次閱讀
    <b class='flag-5'>深入</b>ZMC900E:主站控制<b class='flag-5'>器</b><b class='flag-5'>編碼器</b>的使用與優(yōu)勢

    絕對值編碼器與增量式編碼器相比有哪些優(yōu)勢?

    絕對值編碼器與增量式編碼器相比有哪些優(yōu)勢?核心功能:斷電后位置信息不丟失,絕對值編碼器:通過機械結構或電子存儲(如電池備份),能實時輸出當前位置的唯一絕對值編碼(如二進制、格雷碼)。無
    的頭像 發(fā)表于 08-11 13:57 ?1465次閱讀
    絕對值<b class='flag-5'>編碼器</b>與增量式<b class='flag-5'>編碼器</b>相比有哪些優(yōu)勢?

    增量型編碼器與絕對值型編碼器怎么選擇?

    在選擇增量型編碼器與絕對值型編碼器時,需要考慮多個因素,包括應用需求、成本、精度、可靠性以及環(huán)境適應性等。以下是對兩種編碼器的詳細比較及選擇建議: 一、增量型編碼器 1. 優(yōu)點: ?
    的頭像 發(fā)表于 07-10 10:34 ?1150次閱讀

    一文讀懂什么是磁性編碼器

    磁性編碼器是一種用于測量角度和線性位置的傳感。它使用磁性信號來監(jiān)測旋轉或線性位置的變化,并把這些變化轉換成數(shù)字信號。磁性編碼器可用于各種應用中,比如機器人、汽車、數(shù)控機床等領域
    的頭像 發(fā)表于 04-27 17:18 ?903次閱讀

    新加坡服務器延遲大嗎?真相在這里#新加坡服務器 #服務器

    服務器
    jf_57681485
    發(fā)布于 :2025年04月18日 13:48:50

    編碼器與無軸承編碼器,到底如何選擇?

    在選擇軸編碼器與無軸承編碼器時,需要根據(jù)具體的應用場景、性能需求、環(huán)境條件和成本預算等因素進行綜合考慮。以下是對兩者的詳細對比,以幫助做出合適的選擇: 一、工作原理與結構 1. 軸編碼器
    的頭像 發(fā)表于 03-11 15:33 ?1138次閱讀
    軸<b class='flag-5'>編碼器</b>與無軸承<b class='flag-5'>編碼器</b>,到底如何選擇?

    伺服電機編碼器怎么選型

    伺服電機編碼器的選型是一個綜合性的過程,需要考慮多個因素以確保所選編碼器能夠滿足系統(tǒng)的性能要求。以下是一些關鍵的選型步驟和考慮因素: 一、明確應用需求 首先,需要明確伺服電機編碼器的應用需求,包括
    的頭像 發(fā)表于 03-11 12:01 ?1798次閱讀
    伺服電機<b class='flag-5'>編碼器</b>怎么選型

    DISCOAA編碼器性質特點

    DISCOAA編碼器的具體詳細資料或參數(shù) ?。不過,我們可以根據(jù)編碼器的通用知識和一些相關信息來概述編碼器的一般特點和類型。 編碼器通常用于將機械運動或位置轉換為電信號,以便進行監(jiān)測、
    的頭像 發(fā)表于 02-20 13:50 ?733次閱讀

    DISCOAA編碼器類型功能

    DISCOAA編碼器可能包括絕對編碼器和增量編碼器兩種類型,其主要功能是將輸入信號進行分析和處理,并將其轉換為數(shù)字信號 ?。 關于類型,雖然搜索結果中并未直接提及DISCOAA編碼器
    的頭像 發(fā)表于 02-20 13:47 ?740次閱讀

    編碼器的作用與功能解析

    在現(xiàn)代工業(yè)自動化與精確控制領域,編碼器作為一種關鍵的傳感設備,發(fā)揮著舉足輕重的作用。它能夠將機械位移轉換成可讀的數(shù)字信號或模擬信號,為各種控制系統(tǒng)提供精確的位置、速度或方向信息。本文將深入
    的頭像 發(fā)表于 01-24 08:41 ?3129次閱讀
    <b class='flag-5'>編碼器</b>的作用與功能解析