node.js - 为什么我必须刷新页面才能连接到对等系统?
问题描述
我正在尝试创建一个应用程序,允许用户创建视频聊天活动室(通过将其插入后端的数据库),然后让在网站上拥有帐户的其他用户加入它。目前,登录部分没有创建,但这不是问题。
后端在 Spring Boot RestAPI 中完成(并在 8080 上运行),前端在 nodejs 中完成(并在 3000 上运行)。点对点系统使用 nodejs 服务器和 Peer.js API 完成(并在 3001 上运行)。
主要问题如下:
当用户单击从数据库中获取的事件时,如果它是第一个事件,则它成为主机。如果没有,那么它就变成了一个简单的用户。当用户进入房间时,主机必须刷新页面(例如重新连接到房间),用户也必须刷新页面,才能同时连接。为什么会这样?我会给你下面的文件代码。
第二个:为什么这个系统不适用于 Safari,如果它有效,如何解决?
server.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)
脚本.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)
}
房间.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>
索引.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(""", "\"") // DONE BECAUSE WHEN PASSING THE PARAM, INSTEAD OF " IT IS THE " 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>
解决方案
推荐阅读
- thymeleaf - 如何防止 th:onclick 中的单引号在使用 thymeleaf 时被转义
- java - 为什么我得到 Ja.lang.StackOverflowError
- qt - 将 QVector 属性暴露给 D-Bus
- arrays - 如何处理“索引超出范围”Swift 4
- javascript - 选择选项不起作用Vue js
- logging - Kubernetes:如何将容器日志文件挂载到主机
- php - 模态不更新第 2 行的数据,依此类推
- javascript - 如果事件时间加上 4 小时大于 js 中的当前时间,则执行重定向
- drupal-8 - 如何在 Drupal 8 配置表单中获取 full_html textarea 字段?
- bash - 使用 sed 替换包含换行符的特定模式