Code Monkey home page Code Monkey logo

Comments (4)

samuel-tranchet avatar samuel-tranchet commented on May 21, 2024

Hi jingjiangtao,

I'll let the other contributors answer to the question "why" because I'm new to RenderStreaming development.

But I may have a related piece of information : I'm in charge of the furioos-compatibility branch, which goal is to ensure native compatibility of RenderStreaming applications with Furioos streaming platform. In this context we had to implement WebSocket signaling from c# package to Furioos internal signaling system. It might not be directly compatible with Socket.io but I could give it a try before comiting the feature this week.

Can you provide a link to a socket.io signaling server ?

Thanks

from unityrenderstreaming.

jingjiangtao avatar jingjiangtao commented on May 21, 2024

@samuel-tranchet Thanks for Reply.๐Ÿ˜Š
Sorry I don't know Furioos. I am new to unity and webrtc. But I am learning WebRTC recently, and I implemented a simple signaling server with socket.io. Sorry I can't provide a socket.io signaling server, but I can provide part of my code for a one-to-one video call. Hope this helps.
Best wishes.

  • server.ts
"use strict";

import https = require("https");
import fs = require("fs");
import socketIo = require("socket.io");
import express = require("express");

const app = express();
app.use(express.static("./public"));

let USER_COUNT: number = 3;

let options: https.ServerOptions = {
    key: fs.readFileSync("../cert/xxx.key"),
    cert: fs.readFileSync("../cert/xxx.pem")
};

const httpsServer = https.createServer(options, app);

const io = socketIo(httpsServer);
// connection event
io.sockets.on("connection", socket => {
    // join event
    socket.on("join", room => {
        socket.join(room);
        let myRoom = io.sockets.adapter.rooms[room];
        let users = myRoom ? Object.keys(myRoom.sockets).length : 0;

        if (users < USER_COUNT) {
            socket.emit("joined", room, socket.id);
            if (users > 1) {
                socket.to(room).emit("otherJoin", room);
            }
        } else {
            socket.leave(room);
            socket.emit("full", room, socket.id);
        }
    });
    // leave event
    socket.on("leave", room => {
        let myRoom = io.sockets.adapter.rooms[room];
        let users = myRoom ? Object.keys(myRoom.sockets).length : 0;
        socket.to(room).emit("bye", room, socket.id);
        socket.emit("leaved", room, socket.id);
    });

    socket.on("message", (room, data) => {
        socket.to(room).emit("message", room, data);
    });
});

httpsServer.listen(3001, "0.0.0.0");
  • client.ts
part of client code
......

function conn(): void {
    socket = io.connect();

    socket.on("joined", (roomId: string, id: any) => {
        console.log("receive joined " + roomId + " " + id);

        state = "joined";
        createPeerConnection();

        btnConnectServer.disabled = true;
        btnLeave.disabled = false;
        console.log("receive joined state:" + state);
    });

    socket.on("otherJoin", (roomId: string, id: any) => {
        console.log("receive otherJoin " + roomId + " " + id);
        if (state == "joinedUnbind") {
            createPeerConnection();
        }
        state = "joinedConn";
        call();
        console.log("receive otherJoin state:" + state);
    });

    socket.on("full", (roomId: string, id: any) => {
        console.log("receive full " + roomId + " " + id);
        state = "leaved";
        socket.disconnect();
        btnConnectServer.disabled = false;
        btnLeave.disabled = true;
        console.log("receive full state:" + state);
    });

    socket.on("leaved", (roomId: string, id: any) => {
        console.log("receive leaved " + roomId + " " + id);
        state = "leaved";
        socket.disconnect();
        btnConnectServer.disabled = false;
        btnLeave.disabled = true;
        console.log("receive leaved state:" + state);
    });

    socket.on("bye", (roomId: string, id: any) => {
        console.log("receive bye " + roomId + " " + id);
        state = "joinedUnbind";
        closePeerConnection();
        remoteVideo.srcObject = null;
        console.log("receive bye state:" + state);
    });

    socket.on("message", (roomId: string, data: any) => {
        console.log("receive message " + roomId + " " + data);

        if (data) {
            let msg = data as CandidateData;
            if (msg.type == "offer") {
                pc.setRemoteDescription(new RTCSessionDescription(data));
                pc.createAnswer()
                    .then(getAnswer)
                    .catch(handleError);
            } else if (msg.type == "answer") {
                pc.setRemoteDescription(new RTCSessionDescription(data));
            } else if (msg.type == "candidate") {
                let candidate = new RTCIceCandidate({
                    sdpMLineIndex: msg.label,
                    candidate: msg.candidate
                });

                pc.addIceCandidate(candidate);
            } else {
                console.error("invalid message:", data);
            }
        }
    });

    socket.emit("join", room);
}

function createPeerConnection(): void {
    console.log("create peer connection");

    // create PeerConnection
    if (!pc) {
        let pcConfig: RTCConfiguration = {
            iceServers: [
                {
                    urls: "xxx:3478"
                },
                {
                    urls: "turn:xxx:3478",
                    credential: "xxx",
                    username: "xxx"
                }
            ]
        };
        pc = new RTCPeerConnection(pcConfig);
        pc.onicecandidate = e => {
            console.log("gather ICECandidate");

            if (e.candidate) {
                // send message
                let data: CandidateData = {
                    type: "candidate",
                    label: e.candidate.sdpMLineIndex,
                    id: e.candidate.sdpMid,
                    candidate: e.candidate.candidate
                };
                sendMessage(room, data);
            }
        };

        pc.ontrack = e => {
            remoteVideo.srcObject = e.streams[0];
        };
    }

    if (localStream) {
        localStream.getTracks().forEach(track => {
            pc.addTrack(track, localStream);
        });
    }
}

function call(): void {
    if (state === "joinedConn") {
        if (pc) {
            let options: RTCOfferOptions = {
                offerToReceiveAudio: true,
                offerToReceiveVideo: true
            };
            pc.createOffer(options)
                .then(getOffer)
                .catch(handleError);
        }
    }
}

function getOffer(desc: RTCSessionDescription): void {
    pc.setLocalDescription(desc);
    sendMessage(room, desc);
}

function getAnswer(desc: RTCSessionDescription): void {
    pc.setLocalDescription(desc);
    sendMessage(room, desc);
}

function sendMessage(roomId: string, data: any): void {
    console.log("send p2p message:" + roomId + " " + data);
    socket.emit("message", roomId, data);
}

function closeLocalMedia(): void {
    console.log("close local media");

    if (localStream && localStream.getTracks()) {
        localStream.getTracks().forEach(track => {
            track.stop();
        });
        localStream = null;
    }
}

function leave(): void {
    if (socket) {
        socket.emit("leave", room);
    }
    closePeerConnection();
    closeLocalMedia();
    btnConnectServer.disabled = false;
    btnLeave.disabled = true;
}

function closePeerConnection(): void {
    console.log("close peer connection");

    if (pc) {
        pc.close();
        pc = null;
    }
    console.log("close pc");
}

from unityrenderstreaming.

Nemo-G avatar Nemo-G commented on May 21, 2024

Hi @jingjiangtao , at very early stage I've participated a little in the integration of RenderStreaming. I will share some of my thoughts.

TLDR: There is no specific reason to use http.

In all, WebRTC signal is just a spec. Basically if you implement your own signaling server, you are free to create offer as you wish. You could have one Unity dedicated server to support multiple user at same time although it is not meaningful since they will affect each other in one stream. Actually, my team reimplement the signal server to fit our needs.

For unity end, it is quite easy to send http request and once you are connected to streaming server. You don't actually need to send signal unless you want to disconnect. In this situation, http is just enough.

from unityrenderstreaming.

jingjiangtao avatar jingjiangtao commented on May 21, 2024

Hi @Nemo-G , Thanks for reply. I know the reason and I will close this issue.

from unityrenderstreaming.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.