1

ユーザーがビデオチャット イベント ルームを作成し (バックエンドのデータベースに挿入することで)、ウェブサイトにアカウントを持つ他のユーザーが参加できるようにするアプリを作成しようとしています。現時点ではログイン部分は作成されていませんが、問題ありません。

バックエンドは Spring Boot RestAPI (および 8080 で実行) で実行され、フロントエンドは nodejs (および 3000 で実行) で実行されます。ピア ツー ピア システムは、nodejs サーバーと Peer.js API を使用して行われます (3001 で実行されます)。

主な質問は次のとおりです。

ユーザーが DB から取得したイベントをクリックすると、最初のイベントであればホストになります。そうでない場合は、単純なユーザーになります。ユーザーがルームに入ると、ホストはページを更新する必要があり (ルームに再接続するなど)、ユーザーも同様に、両方が接続されるようにします。どうしてですか?ファイルコードを以下に示します。

2 つ目: このシステムが Safari で機能しない理由と、機能する場合の解決方法

サーバー.js:

const express = require('express')
const app = express()
const server = require('http').Server(app)
const io = require('socket.io')(server)
const { v4: uuidV4 } = require('uuid')

app.set('view engine', 'ejs')
app.use(express.static('public'))

app.get('/', (req, res) => {
    var http = require("http")
    // BELOW IT IS THE BACKEND CONNECTION. TO TEST YOUR CODE, YOU NEED AN ARRAY THAT HAVE ARRAYS WITH sessionID AND name PARAMS LIKE SO: [{"sessionID":"1231", "name":"event"},{...}].
    http.get("http://localhost:8080/events", (resp) => {
        let data = "";
        resp.on("data", (chunk) => {
            data += chunk;
        });
        resp.on("end", () => {
            console.log(data);
            res.render('index', {events: data})
        });
    })
    .on("error", (err) => {
        console.log("Error: " + err.message);
    });
})

app.get('/join', (req, res) => {
    res.render('join')
})

app.get('/event', (req, res) => {
    res.redirect(`/${uuidV4()}`)
})

app.get('/:room', (req, res) => {
  res.render('room', { roomId: req.params.room })
})

io.on('connection', socket => {
  socket.on('join-room', (roomId, userId) => {
        console.log("User connected: " + userId)
        socket.join(roomId)
        socket.to(roomId).broadcast.emit('user-connected', userId)

        socket.on('disconnect', () => {
            socket.to(roomId).broadcast.emit('user-disconnected', userId)
        })
  })
})

server.listen(3000)

script.js:

const socket = io('/')
const videoGrid = document.getElementById('video-grid')
const myPeer = new Peer(undefined, { // user id
  host: '/', // path to event
  port: '3001' // post
})
const myVideo = document.createElement('video')
myVideo.muted = true
const peers = {}

navigator.mediaDevices.getUserMedia({
  video: true,
  audio: true
}).then(stream => {
  addVideoStream(myVideo, stream)

  myPeer.on('call', call => {
    call.answer(stream) // HOST SEE OTHERS
    const video = document.createElement('video')
    call.on('stream', userVideoStream => { // OTHERS SEE HOST
      addVideoStream(video, userVideoStream)
    })
  })

  socket.on('user-connected', userId => {
    connectToNewUser(userId, stream)
    console.log(peers);
  })
})

socket.on('user-disconnected', userId => {
  if (peers[userId]) peers[userId].close()
})

myPeer.on('open', id => {
  socket.emit('join-room', ROOM_ID, id)
})

function connectToNewUser(userId, stream) {
  const call = myPeer.call(userId, stream)
  const video = document.createElement('video')
  call.on('stream', userVideoStream => {
    addVideoStream(video, userVideoStream)
  })
  call.on('close', () => {
    video.remove()
  })

  peers[userId] = call
}

function addVideoStream(video, stream) {
  video.srcObject = stream
  video.addEventListener('loadedmetadata', () => {
    video.play()
  })
  videoGrid.append(video)
}

room.ejs:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Template</title>
    <script>
        const ROOM_ID = "<%= roomId %>"
    </script>
    <script src="https://unpkg.com/peerjs@1.3.1/dist/peerjs.min.js" defer></script>
    <script src="/socket.io/socket.io.js" defer></script>
    <script src="script.js" defer></script>
    <style>
        #video-grid{
            display: grid;
            grid-template-columns: repeat(auto-fill, 300px);
            grid-auto-rows: 300px;
        }
        video{
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
    </style>
</head>
<body>
    <div id="video-grid">

    </div>
</body>
</html>

index.ejs:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>index</title>
    <script>
        var raw = "<%= events %>"
        raw = raw.replaceAll("&#34;", "\"") // DONE BECAUSE WHEN PASSING THE PARAM, INSTEAD OF " IT IS THE &#34; ENTITY
        var events = JSON.parse(raw)
        
        window.onload = (event) => {
            var table = document.querySelectorAll("#events")[0];
            table.innerHTML = '';
            for (let index = 0; index < events.length; index++) {
                table.innerHTML += "<tr><td><a href='/" + events[index].sessionID + "'>" + events[index].name + "</a></td></tr>"
            }
        };
    </script>
</head>
<body>
    <h1><a href="/event">Create Event</a></h1>
    <table id="events">

    </table>
</body>
</html>
4

0 に答える 0