getting main flow of everything but don't know if it works

This commit is contained in:
talksik
2022-05-07 17:45:26 -05:00
parent 3c68128469
commit b16778fa8d
4 changed files with 219 additions and 52 deletions
+38
View File
@@ -1,5 +1,9 @@
import {
ConnectToLineRequest,
RtcAnswerRequest,
RtcCallRequest,
RtcNewUserResponse,
RtcReceiveAnswerResponse,
ServerRequestChannels,
ServerResponseChannels,
SomeoneConnectedResponse,
@@ -32,6 +36,9 @@ const config = loadConfig();
const socketIdsToUserIds: {
[socketId: string]: string;
} = {};
const userIdsToSocketIds: {
[userId: string]: string;
} = {};
export default function InitializeWs(io: any) {
console.log("initializing web sockets");
@@ -62,6 +69,7 @@ export default function InitializeWs(io: any) {
const userInfo: JwtClaims = socket.userInfo;
socketIdsToUserIds[socket.id] = userInfo.userId.toString();
userIdsToSocketIds[userInfo.userId.toString()] = socket.id;
console.log(
`a user connected | user Id: ${userInfo.userId} and name: ${userInfo.name}`
@@ -231,9 +239,35 @@ export default function InitializeWs(io: any) {
// );
// });
// tell the proper other user to create a local peer object for the one on one mesh connection
socket.on(
ServerRequestChannels.RTC_CALL_REQUEST,
(req: RtcCallRequest) => {
const userSocketId = userIdsToSocketIds[req.userIdToCall];
io.to(userSocketId).emit(
`${ServerResponseChannels.RTC_NEW_USER_JOINED_RESPONSE_PREFIX}:${req.lineId}`,
new RtcNewUserResponse(userInfo.userId, req.simplePeerSignal)
);
}
);
socket.on(
ServerRequestChannels.RTC_ANSWER_REQUEST,
(req: RtcAnswerRequest) => {
const userSocketId = userIdsToSocketIds[req.userIdToCall];
io.to(userSocketId).emit(
`${ServerResponseChannels.RTC_RECEIVING_ANSWER_RESPONSE_PREFIX}:${req.lineId}`,
new RtcReceiveAnswerResponse(userInfo.userId, req.simplePeerSignal)
);
}
);
// ==== DISCONNECT ====
socket.on("disconnect", () => {
delete socketIdsToUserIds[socket.id];
delete userIdsToSocketIds[userInfo.userId];
// get all of the rooms of this socket
// notify everyone of this disconnection
@@ -242,6 +276,10 @@ export default function InitializeWs(io: any) {
console.log(
`list of sockets mappings in memory: ${socketIdsToUserIds}`
);
console.log(socket.rooms);
// ! NOTIFY ALL CONNECTED LINES SO THAT THEY CAN REMOVE FROM THEIR SESSION CONNECTED USERS ARRAY AND TUNED IN ARRAY
});
});
}
+31
View File
@@ -41,6 +41,9 @@ export enum ServerRequestChannels {
BROADCAST_TO_LINE = "BROADCAST_TO_LINE",
STOP_BROADCAST_TO_LINE = "STOP_BROADCAST_TO_LINE",
RTC_CALL_REQUEST = "RTC_CALL_PREFIX",
RTC_ANSWER_REQUEST = "RTC_ANSWER_REQUEST_PREFIX",
}
export enum ServerResponseChannels {
@@ -52,6 +55,10 @@ export enum ServerResponseChannels {
SOMEONE_STARTED_BROADCASTING = "SOMEONE_STARTED_BROADCASTING", //show their stream tracks
SOMEONE_STOPPED_BROADCASTING = "SOMEONE_STOPPED_BROADCASTING", // stop showing their stream tracks
// sending to the correct room of tunedin folks AND also making sure it's the right event handler in the right handler for this component
RTC_NEW_USER_JOINED_RESPONSE_PREFIX = "RTC_NEW_USER_JOINED_RESPONSE_PREFIX",
RTC_RECEIVING_ANSWER_RESPONSE_PREFIX = "RTC_RECEIVING_ANSWER_RESPONSE_PREFIX",
}
export default SocketChannels;
@@ -107,3 +114,27 @@ export class UserStoppedBroadcastingResponse {
export class SocketEmitter<T> {
constructor(public channel: SocketChannels, data: T) {}
}
export class RtcCallRequest {
constructor(
public lineId: string,
public userIdToCall: string,
public simplePeerSignal: any
) {}
}
export class RtcNewUserResponse {
constructor(public newUserId: string, public simplePeerSignal: any) {}
}
export class RtcAnswerRequest {
constructor(
public lineId: string,
public userIdToCall: string,
public simplePeerSignal: any
) {}
}
export class RtcReceiveAnswerResponse {
constructor(public answererUserId: string, public simplePeerSignal: any) {}
}
+2 -2
View File
@@ -55,8 +55,8 @@
[
"@electron-forge/plugin-webpack",
{
"port": "4000",
"loggerPort": "9001",
"port": "4002",
"loggerPort": "9005",
"mainConfig": "./webpack.main.config.js",
"devContentSecurityPolicy": "connect-src 'self' http://localhost:5000 ws://localhost:5000 'unsafe-eval'",
"renderer": {
@@ -1,5 +1,9 @@
import { FiActivity, FiSun } from "react-icons/fi";
import {
RtcAnswerRequest,
RtcCallRequest,
RtcNewUserResponse,
RtcReceiveAnswerResponse,
ServerResponseChannels,
SomeoneUntunedFromLineResponse,
} from "@nirvana/core/sockets/channels";
@@ -11,6 +15,7 @@ import LineIcon from "../lineIcon";
import { LineMemberState } from "@nirvana/core/models/line.model";
import MasterLineData from "@nirvana/core/models/masterLineData.model";
import Peer from "simple-peer";
import { ServerRequestChannels } from "../../../../../core/sockets/channels";
import moment from "moment";
import toast from "react-hot-toast";
import { useGetUserDetails } from "../../../controller/index";
@@ -157,6 +162,7 @@ export default function LineRow({
{/* mounts and unmounts based on if in the room or now */}
{isUserTunedIn && (
<StreamRoom
lineId={masterLineData.lineDetails._id.toString()}
currentBroadcasters={masterLineData.currentBroadcastersUserIds}
tunedInUsers={masterLineData.tunedInMemberIds}
/>
@@ -165,10 +171,14 @@ export default function LineRow({
);
}
type PeerMap = { [userId: string]: Peer };
function StreamRoom({
lineId,
tunedInUsers,
currentBroadcasters,
}: {
lineId: string;
tunedInUsers?: string[];
currentBroadcasters?: string[];
}) {
@@ -176,65 +186,152 @@ function StreamRoom({
// local stream specifically for this stream room
const [localStream, setLocalStream] = useState<MediaStream>();
const userStreamTagRef = useRef<HTMLVideoElement>(null);
const { data: userDetails } = useGetUserDetails();
// local peer map of userIds to peers
const [userPeers, setUserPeers] = useState<{ [userId: string]: Peer }>({});
const [userPeers, setUserPeers] = useState<PeerMap>({});
// ws listen to events of user disconnecting and such or rely on tunedin members prop
const { $ws } = useLineDataProvider();
useEffect(() => {
navigator.mediaDevices
.getUserMedia({
video: false,
audio: {
echoCancellation: true,
autoGainControl: true,
},
})
.then((userStream) => {
setLocalStream(userStream);
if (userDetails) {
navigator.mediaDevices
.getUserMedia({
video: false,
audio: {
echoCancellation: true,
autoGainControl: true,
},
})
.then((userStream) => {
setLocalStream(userStream);
// if (userStreamTagRef?.current)
// userStreamTagRef.current.srcObject = userStream;
// if (userStreamTagRef?.current)
// userStreamTagRef.current.srcObject = userStream;
// alternative to dom element
// const audio = new Audio();
// audio.autoplay = true;
// audio.srcObject = userStream;
// alternative to dom element
// const audio = new Audio();
// audio.autoplay = true;
// audio.srcObject = userStream;
// test distortion to go away on disabling audio
setTimeout(() => {
console.log("stopping audio stream ");
// test distortion to go away on disabling audio
setTimeout(() => {
console.log("stopping audio stream ");
userStream.getTracks().forEach((track) => {
track.enabled = !track.enabled;
userStream.getTracks().forEach((track) => {
track.enabled = !track.enabled;
track.stop();
track.stop();
});
}, 2000);
// take the initial list of tunedInUsers without my own id
const everyOtherTunedUserId = tunedInUsers.filter(
(tunedUserId) => tunedUserId !== userDetails?.user._id.toString()
);
const localPeerConnections: PeerMap = {};
everyOtherTunedUserId.forEach((otherTunedInUserId) => {
// create local peer objects for them
const localPeerInitiator = new Peer({
initiator: true,
stream: userStream,
trickle: false, // prevents the multiple tries on different ice servers and signal from getting called a bunch of times
});
// set it for our map that we will iterate through to display streams in other child view
localPeerConnections[otherTunedInUserId] = localPeerInitiator;
// notify each one with specific signal
localPeerInitiator.on("signal", (signal) => {
$ws.emit(
ServerRequestChannels.RTC_CALL_REQUEST,
new RtcCallRequest(lineId, otherTunedInUserId, signal)
);
});
});
}, 2000);
// take the initial list of tunedInUsers
// create local peer objects for them
// notify all of them individually
//
})
.catch((error) => {
console.error(error);
setUserPeers(localPeerConnections);
toast.error(
"Make sure that you have permissions enabled and microphone connected"
);
});
// answer calls
$ws.on(
`${ServerResponseChannels.RTC_NEW_USER_JOINED_RESPONSE_PREFIX}:${lineId}`,
(res: RtcNewUserResponse) => {
// create a local peer connection for this new user
$ws.on(
ServerResponseChannels.SOMEONE_UNTUNED_FROM_LINE,
(res: SomeoneUntunedFromLineResponse) => {
// take the relevant userId
res.userId;
}
);
}, []);
console.log(
"ooo newbie joined room, I guess I will accept it and send him my signal"
);
var peerForMeAndNewbie = new Peer({
initiator: false,
trickle: false, // prevents the multiple tries on different ice servers and signal from getting called a bunch of times
stream: localStream, // add in my own stream that I got before
});
peerForMeAndNewbie.on("signal", (signal) => {
console.log(
"as the answerer, I am going to send back my signal so that the newbie can update his local peer for me"
);
$ws.emit(
ServerRequestChannels.RTC_ANSWER_REQUEST,
new RtcAnswerRequest(lineId, res.newUserId, signal)
);
});
peerForMeAndNewbie.signal(res.simplePeerSignal);
setUserPeers((prevUsersPeers) => {
const newUserPeers = { ...prevUsersPeers };
newUserPeers[res.newUserId] = peerForMeAndNewbie;
return newUserPeers;
});
}
);
// take care of answers recevied
$ws.on(
`${ServerResponseChannels.RTC_RECEIVING_ANSWER_RESPONSE_PREFIX}:${lineId}`,
(res: RtcReceiveAnswerResponse) => {
console.log("oooo some master received my call and accepted it");
// find the peer we created earlier for this master
// ?is this okay? using the setter to get the current state?
setUserPeers((previousUserPeersMap) => {
const peerForAnswerer =
previousUserPeersMap[res.answererUserId];
if (peerForAnswerer) {
peerForAnswerer.signal(res.simplePeerSignal);
} else {
console.error(
"could not find the peer we created before for this master"
);
}
return previousUserPeersMap;
});
}
);
})
.catch((error) => {
console.error(error);
toast.error(
"Make sure that you have permissions enabled and microphone connected"
);
});
}
}, [userDetails, setUserPeers]);
// calculate diff to clean our userPeerMap to unmount and detroy certain peer connections
useEffect(() => {}, [tunedInUsers]);
// todo, someone tell the main object that I am finally connected after everything...different than tuned in
useEffect(() => {
console.log("change in tuned in users in the streaming room!!!");
@@ -245,13 +342,14 @@ function StreamRoom({
<>
<audio autoPlay ref={userStreamTagRef} muted />
this is the video of people
{Object.entries(userPeers).map(([userId, peer]) => (
<PeerStreamRenderer
key={userId}
isBroadcasting={currentBroadcasters?.includes(userId)}
peer={peer}
/>
))}
{userPeers &&
Object.entries(userPeers).map(([userId, peer]) => (
<PeerStreamRenderer
key={userId}
isBroadcasting={currentBroadcasters?.includes(userId)}
peer={peer}
/>
))}
</>
);
}