researching webrtc support

This commit is contained in:
Roland Osborne 2023-03-17 14:45:33 -07:00
parent 5e181d090f
commit ed11885711
4 changed files with 209 additions and 2 deletions

View File

@ -0,0 +1,59 @@
package databag
import (
"errors"
"github.com/gorilla/websocket"
"net/http"
)
var relayer = websocket.Upgrader{}
var left *websocket.Conn
var right *websocket.Conn
var cur bool = false
//Status handler for websocket connection
func Relay(w http.ResponseWriter, r *http.Request) {
// accept websocket connection
conn, err := relayer.Upgrade(w, r, nil)
if err != nil {
ErrMsg(err)
return
}
if (cur) {
right = conn;
PrintMsg("CONNECTED RIGHT");
} else {
left = conn;
PrintMsg("CONNECTED LEFT");
}
cur = !cur;
defer conn.Close()
conn.SetReadLimit(APPBodyLimit)
for true {
t, m, res := conn.ReadMessage()
if res != nil {
ErrMsg(res)
return
}
if t != websocket.TextMessage {
ErrMsg(errors.New("invalid websocket message type"))
return
}
if conn == left {
if err := right.WriteMessage(websocket.TextMessage, m); err != nil {
ErrMsg(err)
return
}
}
if conn == right {
if err := left.WriteMessage(websocket.TextMessage, m); err != nil {
ErrMsg(err)
return
}
}
}
}

View File

@ -796,4 +796,11 @@ var endpoints = routes{
"/status", "/status",
Status, Status,
}, },
route{
"Relay",
strings.ToUpper("Get"),
"/relay",
Relay,
},
} }

View File

@ -1,17 +1,152 @@
import { WelcomeWrapper } from './Welcome.styled'; import { WelcomeWrapper } from './Welcome.styled';
import { RightOutlined } from '@ant-design/icons'; import { RightOutlined } from '@ant-design/icons';
import { Space } from 'antd'; import { Input, Space } from 'antd';
import React, { createContext, useState, useRef, useEffect } from 'react';
import session from 'images/session.png'; import session from 'images/session.png';
export function Welcome() { export function Welcome() {
const video = useRef();
const vid = useRef();
const peer = useRef();
const ws = useRef();
const candidates = useRef([]);
const whiteNoise = () => {
const canvas = Object.assign(document.createElement("canvas"), {width: 320, height: 240});
const ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, 320, 240);
const p = ctx.getImageData(0, 0, 320, 240);
requestAnimationFrame(function draw(){
for (var i = 0; i < p.data.length; i++) {
p.data[i++] = p.data[i++] = p.data[i++] = Math.random() * 255;
}
ctx.putImageData(p, 0, 0);
requestAnimationFrame(draw);
});
return canvas.captureStream();
}
const start = async () => {
const stream = await navigator.mediaDevices.getUserMedia({video: true});
//const stream = await whiteNoise();
peer.current.addTransceiver(stream.getTracks()[0], {streams: [stream]});
};
const rtc = async () => {
const iceServers = [
{
urls: 'stun:192.168.13.233:5001?transport=udp',
username: 'user',
credential: 'pass'
},
{
urls: 'turn:192.168.13.233:5001?transport=udp',
username: 'user',
credential: 'pass'
}];
const pc = new RTCPeerConnection({
iceServers
});
//const pc = new RTCPeerConnection();
peer.current = pc;
pc.onicecandidate = (e) => {
if (!e.candidate) return;
ws.current.send(JSON.stringify({ candidate: e.candidate }));
console.log(JSON.stringify(e.candidate));
// If a srflx candidate was found, notify that the STUN server works!
if(e.candidate.type == "srflx"){
console.log("The STUN server is reachable!");
console.log(` Your Public IP Address is: ${e.candidate.address}`);
}
// If a relay candidate was found, notify that the TURN server works!
if(e.candidate.type == "relay"){
console.log("The TURN server is reachable !");
}
};
pc.onicecandidateerror = (e) => {
console.error(e);
};
pc.ontrack = ({streams: [stream]}) => {
console.log("ON TRACK!");
vid.current.srcObject = stream;
};
const dc = pc.createDataChannel("both", {negotiated: true, id: 0});
pc.onnegotiationneeded = async () => {
console.log("NEGOTIATION");
create();
};
}
const create = async () => {
const offer = await peer.current.createOffer();
await peer.current.setLocalDescription(offer);
ws.current.send(JSON.stringify({ offer: offer }));
console.log(":: OFFER: ", offer);
}
useEffect(() => {
rtc();
ws.current = new WebSocket('wss://balzack.coredb.org/relay');
ws.current.onmessage = async (ev) => {
const msg = JSON.parse(ev.data);
if (msg.candidate) {
console.log("> CANDIDATE: ", msg.candidate);
candidates.current.push(msg.candidate);
await peer.current.addIceCandidate(msg.candidate);
}
else if (msg.offer) {
console.log("> OFFER: ", msg.offer);
peer.current.setRemoteDescription(msg.offer);
await peer.current.setLocalDescription(await peer.current.createAnswer());
ws.current.send(JSON.stringify({ answer: peer.current.localDescription }));
}
else if (msg.answer) {
console.log("> ANSWER: ", msg.answer);
peer.current.setRemoteDescription(msg.answer);
}
}
ws.current.onclose = (e) => {
console.log("CLOSED");
}
ws.current.onopen = () => {
console.log("OPENED");
}
ws.current.error = (e) => {
console.log("ERROR");
}
}, []);
return ( return (
<WelcomeWrapper> <WelcomeWrapper>
<div class="title"> <div class="title">
<div class="header">Databag</div> <div class="header">Databag</div>
<div>Communication for the decentralized web</div> <div>Communication for the decentralized web</div>
</div> </div>
<img class="session" src={session} alt="Session Background" />
<div style={{ width: 320, height: 240, backgroundColor: 'white' }}>
<video ref={vid} width={320} height={240} autoPlay
complete={() => console.log("VIDEO COMPLETE")} progress={() => console.log("VIDEO PROGRESS")} error={() => console.log("VIDEO ERROR")} waiting={() => console.log("VIDEO WAITING")} />
</div>
<div style={{ width: 100, height: 32}} onClick={create}>Create</div>
<div style={{ width: 100, height: 32}} onClick={start}>Start</div>
<div class="message"> <div class="message">
<Space> <Space>
<div>Setup your profile</div> <div>Setup your profile</div>

View File

@ -9,6 +9,12 @@ export const WelcomeWrapper = styled.div`
justify-content: center; justify-content: center;
color: #555555; color: #555555;
.video {
width: 640px;
height: 480px;
background-color: yellow;
}
.title { .title {
width: 100%; width: 100%;
display: flex; display: flex;