-
-
Save tsh-code/5d34542fe5274341439ef92de7861cd3 to your computer and use it in GitHub Desktop.
WebRTC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import express, { Application } from "express"; | |
import socketIO, { Server as SocketIOServer } from "socket.io"; | |
import { createServer, Server as HTTPServer } from "http"; | |
export class Server { | |
private httpServer: HTTPServer; | |
private app: Application; | |
private io: SocketIOServer; | |
private readonly DEFAULT_PORT = 5000; | |
constructor() { | |
this.initialize(); | |
this.handleRoutes(); | |
this.handleSocketConnection(); | |
} | |
private initialize(): void { | |
this.app = express(); | |
this.httpServer = createServer(this.app); | |
this.io = socketIO(this.httpServer); | |
} | |
private handleRoutes(): void { | |
this.app.get("/", (req, res) => { | |
res.send(`<h1>Hello World</h1>`); | |
}); | |
} | |
private handleSocketConnection(): void { | |
this.io.on("connection", socket => { | |
console.log("Socket connected."); | |
}); | |
} | |
public listen(callback: (port: number) => void): void { | |
this.httpServer.listen(this.DEFAULT_PORT, () => | |
callback(this.DEFAULT_PORT) | |
); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async function callUser(socketId) { | |
const offer = await peerConnection.createOffer(); | |
await peerConnection.setLocalDescription(new RTCSessionDescription(offer)); | |
socket.emit("call-user", { | |
offer, | |
to: socketId | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
socket.on("call-user", data => { | |
socket.to(data.to).emit("call-made", { | |
offer: data.offer, | |
socket: socket.id | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function createUserItemContainer(socketId) { | |
const userContainerEl = document.createElement("div"); | |
const usernameEl = document.createElement("p"); | |
userContainerEl.setAttribute("class", "active-user"); | |
userContainerEl.setAttribute("id", socketId); | |
usernameEl.setAttribute("class", "username"); | |
usernameEl.innerHTML = `Socket: ${socketId}`; | |
userContainerEl.appendChild(usernameEl); | |
userContainerEl.addEventListener("click", () => { | |
unselectUsersFromList(); | |
userContainerEl.setAttribute("class", "active-user active-user--selected"); | |
const talkingWithInfo = document.getElementById("talking-with-info"); | |
talkingWithInfo.innerHTML = `Talking with: "Socket: ${socketId}"`; | |
callUser(socketId); | |
}); | |
return userContainerEl; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
navigator.getUserMedia( | |
{ video: true, audio: true }, | |
stream => { | |
const localVideo = document.getElementById("local-video"); | |
if (localVideo) { | |
localVideo.srcObject = stream; | |
} | |
}, | |
error => { | |
console.warn(error.message); | |
} | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private configureApp(): void { | |
this.app.use(express.static(path.join(__dirname, "../public"))); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<title>Dogeller</title> | |
<link | |
href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500,700&display=swap" | |
rel="stylesheet" | |
/> | |
<link rel="stylesheet" href="./styles.css" /> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> | |
</head> | |
<body> | |
<div class="container"> | |
<header class="header"> | |
<div class="logo-container"> | |
<img src="./img/doge.png" alt="doge logo" class="logo-img" /> | |
<h1 class="logo-text"> | |
Doge<span class="logo-highlight">ller</span> | |
</h1> | |
</div> | |
</header> | |
<div class="content-container"> | |
<div class="active-users-panel" id="active-user-container"> | |
<h3 class="panel-title">Active Users:</h3> | |
</div> | |
<div class="video-chat-container"> | |
<h2 class="talk-info" id="talking-with-info"> | |
Select active user on the left menu. | |
</h2> | |
<div class="video-container"> | |
<video autoplay class="remote-video" id="remote-video"></video> | |
<video autoplay muted class="local-video" id="local-video"></video> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script src="./scripts/index.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Server } from "./server"; | |
const server = new Server(); | |
server.listen(port => { | |
console.log(`Server is listening on http://localhost:${port}`); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private activeSockets: string[] = []; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
socket.on("make-answer", data => { | |
socket.to(data.to).emit("answer-made", { | |
socket: socket.id, | |
answer: data.answer | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
npm init |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
socket.on("call-made", async data => { | |
await peerConnection.setRemoteDescription( | |
new RTCSessionDescription(data.offer) | |
); | |
const answer = await peerConnection.createAnswer(); | |
await peerConnection.setLocalDescription(new RTCSessionDescription(answer)); | |
socket.emit("make-answer", { | |
answer, | |
to: data.socket | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
socket.on("answer-made", async data => { | |
await peerConnection.setRemoteDescription( | |
new RTCSessionDescription(data.answer) | |
); | |
if (!isAlreadyCalling) { | |
callUser(data.socket); | |
isAlreadyCalling = true; | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
socket.on("update-user-list", ({ users }) => { | |
updateUserList(users); | |
}); | |
socket.on("remove-user", ({ socketId }) => { | |
const elToRemove = document.getElementById(socketId); | |
if (elToRemove) { | |
elToRemove.remove(); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"scripts": { | |
"start": "ts-node src/index.ts", | |
"dev": "nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/index.ts" | |
}, | |
"devDependencies": { | |
"@types/express": "^4.17.2", | |
"@types/socket.io": "^2.1.4", | |
"nodemon": "^1.19.4", | |
"ts-node": "^8.4.1", | |
"typescript": "^3.7.2" | |
}, | |
"dependencies": { | |
"express": "^4.17.1", | |
"socket.io": "^2.3.0" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
navigator.getUserMedia( | |
{ video: true, audio: true }, | |
stream => { | |
const localVideo = document.getElementById("local-video"); | |
if (localVideo) { | |
localVideo.srcObject = stream; | |
} | |
stream.getTracks().forEach(track => peerConnection.addTrack(track, stream)); | |
}, | |
error => { | |
console.warn(error.message); | |
} | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { RTCPeerConnection, RTCSessionDescription } = window; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private initialize(): void { | |
this.app = express(); | |
this.httpServer = createServer(this.app); | |
this.io = socketIO(this.httpServer); | |
this.configureApp(); | |
this.handleSocketConnection(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
peerConnection.ontrack = function({ streams: [stream] }) { | |
const remoteVideo = document.getElementById("remote-video"); | |
if (remoteVideo) { | |
remoteVideo.srcObject = stream; | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const socket = io.connect("localhost:5000"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
this.io.on("connection", socket => { | |
const existingSocket = this.activeSockets.find( | |
existingSocket => existingSocket === socket.id | |
); | |
if (!existingSocket) { | |
this.activeSockets.push(socket.id); | |
socket.emit("update-user-list", { | |
users: this.activeSockets.filter( | |
existingSocket => existingSocket !== socket.id | |
) | |
}); | |
socket.broadcast.emit("update-user-list", { | |
users: [socket.id] | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
socket.on("disconnect", () => { | |
this.activeSockets = this.activeSockets.filter( | |
existingSocket => existingSocket !== socket.id | |
); | |
socket.broadcast.emit("remove-user", { | |
socketId: socket.id | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function updateUserList(socketIds) { | |
const activeUserContainer = document.getElementById("active-user-container"); | |
socketIds.forEach(socketId => { | |
const alreadyExistingUser = document.getElementById(socketId); | |
if (!alreadyExistingUser) { | |
const userContainerEl = createUserItemContainer(socketId); | |
activeUserContainer.appendChild(userContainerEl); | |
} | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I made an example and fixed all the mistakes of the author.
https://github.com/exzos28/webrtc-echo-server