tianyun před 3 měsíci
rodič
revize
5bbc9ec786
4 změnil soubory, kde provedl 104 přidání a 72 odebrání
  1. 3 4
      chat-room/main.py
  2. 9 0
      chat-room/restart.sh
  3. 0 1
      chat-room/start.sh
  4. 92 67
      chat-room/templates/room.html

+ 3 - 4
chat-room/main.py

@@ -14,6 +14,7 @@ def on_join(data):
     room = data['room']
     join_room(room)
     rooms[request.sid] = room
+    socketio.emit('user_joined', request.sid, room=room, skip_sid=request.sid)
     socketio.emit('message', {'type': 'system', 'msg': '新用户加入'}, room=room)
 
 
@@ -23,20 +24,18 @@ def on_leave():
     if room:
         leave_room(room)
         del rooms[request.sid]
+        socketio.emit('user_left', request.sid, room=room)
         socketio.emit('message', {'type': 'system', 'msg': '用户离开'}, room=room)
 
 
 @socketio.on('offer')
 def handle_offer(data):
-    # 添加发送者标识
     data['sender'] = request.sid
-    # 广播给房间内其他用户
-    socketio.emit('offer', data, room=data['room'], skip_sid=request.sid)
+    socketio.emit('offer', data, room=data['target'])
 
 @socketio.on('answer')
 def handle_answer(data):
     data['sender'] = request.sid
-    # 发送给指定用户
     socketio.emit('answer', data, room=data['target'])
 
 @socketio.on('candidate')

+ 9 - 0
chat-room/restart.sh

@@ -0,0 +1,9 @@
+# 检查是否已有 main.py 进程在运行
+if pgrep -f "main.py --name chatroom" > /dev/null
+then
+    echo "Process is already running. Restarting..."
+    # 终止已有的 main.py 进程
+    pkill -f "main.py --name chatroom"
+fi
+# 启动新的 main.py 进程
+nohup python -u main.py --name chatroom &

+ 0 - 1
chat-room/start.sh

@@ -1 +0,0 @@
-nohup python -u main.py --name chatroom &

+ 92 - 67
chat-room/templates/room.html

@@ -19,32 +19,32 @@
     let socket = io();
     const peers = {};
 
-    // 初始化WebSocket连接
-    socket.on("connect", () => {
-        socket.emit("join", {room: room_id});
-    });
+      // 初始化WebSocket连接
+      socket.on("connect", () => {
+        socket.emit("join", { room: room_id });
+      });
 
-    // 获取麦克风权限
-    async function init() {
+      // 获取麦克风权限
+      async function init() {
         try {
-            localStream = await navigator.mediaDevices.getUserMedia({
-                audio: true,
-            });
-            document.getElementById("status").innerHTML = "麦克风已就绪";
-            document.getElementById("micButton").disabled = false;
+          localStream = await navigator.mediaDevices.getUserMedia({
+            audio: true,
+          });
+          document.getElementById("status").innerHTML = "麦克风已就绪";
+          document.getElementById("micButton").disabled = false;
         } catch (err) {
-            console.error("Error accessing microphone:", err);
-            document.getElementById("status").innerHTML = "无法访问麦克风: " + err.message;
-            document.getElementById("micButton").disabled = true;
+          console.error("Error accessing microphone:", err);
+          document.getElementById("status").innerHTML = "无法访问麦克风: " + err.message;
+          document.getElementById("micButton").disabled = true;
         }
-    }
+      }
 
-    // 切换麦克风状态
-    async function toggleMic() {
+      // 切换麦克风状态
+      async function toggleMic() {
         if (!localStream) {
-            console.error("No localStream available");
-            document.getElementById("status").innerHTML = "麦克风未就绪,请刷新页面重试";
-            return;
+          console.error("No localStream available");
+          document.getElementById("status").innerHTML = "麦克风未就绪,请刷新页面重试";
+          return;
         }
 
         isMute = !isMute;
@@ -52,64 +52,74 @@
         button.textContent = isMute ? "🎤 点击说话" : "🔴 正在说话";
 
         localStream
-            .getAudioTracks()
-            .forEach((track) => (track.enabled = !isMute));
+          .getAudioTracks()
+          .forEach((track) => (track.enabled = !isMute));
 
         if (!isMute) {
+          createPeerConnections();
+        }
+      }
+
+      // 创建与房间内其他用户的对等连接
+      async function createPeerConnections() {
+        for (let peerId in peers) {
+          if (peerId !== socket.id) {
             const peer = new RTCPeerConnection();
-            peers[socket.id] = peer;
+            peers[peerId] = peer;
 
             localStream
-                .getTracks()
-                .forEach((track) => peer.addTrack(track, localStream));
+              .getTracks()
+              .forEach((track) => peer.addTrack(track, localStream));
 
             peer.onicecandidate = (e) => {
-                if (e.candidate) {
-                    socket.emit("candidate", {
-                        candidate: e.candidate,
-                        room: room_id,
-                        target: socket.id, // 添加目标标识
-                    });
-                }
+              if (e.candidate) {
+                socket.emit("candidate", {
+                  candidate: e.candidate,
+                  room: room_id,
+                  target: peerId,
+                });
+              }
             };
 
             try {
-                const offer = await peer.createOffer();
-                await peer.setLocalDescription(offer);
-
-                socket.emit("offer", {
-                    sdp: offer,
-                    room: room_id, // 使用room字段
-                });
+              const offer = await peer.createOffer();
+              await peer.setLocalDescription(offer);
+
+              socket.emit("offer", {
+                sdp: offer,
+                room: room_id,
+                target: peerId,
+              });
             } catch (err) {
-                console.error("Error creating or sending offer:", err);
-                document.getElementById("status").innerHTML = "创建连接时出错,请刷新页面重试";
+              console.error("Error creating or sending offer:", err);
+              document.getElementById("status").innerHTML = "创建连接时出错,请刷新页面重试";
             }
+          }
         }
-    }
+      }
 
-    // WebRTC信令处理
-    socket.on("offer", async (data) => {
-        // 添加发送者过滤
+      // WebRTC信令处理
+      socket.on("offer", async (data) => {
         if (data.sender === socket.id) return;
 
         const peer = new RTCPeerConnection();
         peers[data.sender] = peer;
 
         peer.onicecandidate = (e) => {
-            if (e.candidate) {
-                socket.emit("candidate", {
-                    candidate: e.candidate,
-                    target: data.sender,
-                    room: room_id,
-                });
-            }
+          if (e.candidate) {
+            socket.emit("candidate", {
+              candidate: e.candidate,
+              target: data.sender,
+              room: room_id,
+            });
+          }
         };
 
         peer.ontrack = (e) => {
-            const audio = document.createElement("audio");
-            audio.srcObject = e.streams[0];
-            audio.play();
+          const audio = document.createElement("audio");
+          audio.srcObject = e.streams[0];
+          audio.autoplay = true;
+          document.body.appendChild(audio);
         };
 
         await peer.setRemoteDescription(data.sdp);
@@ -117,28 +127,43 @@
         await peer.setLocalDescription(answer);
 
         socket.emit("answer", {
-            sdp: answer,
-            target: data.sender, // 指定目标用户
-            room: room_id,
+          sdp: answer,
+          target: data.sender,
+          room: room_id,
         });
-    });
+      });
 
-    socket.on("answer", (data) => {
+      socket.on("answer", (data) => {
         if (data.sender === socket.id) return;
         const peer = peers[data.sender];
         if (peer) {
-            peer.setRemoteDescription(data.sdp);
+          peer.setRemoteDescription(data.sdp);
         }
-    });
+      });
 
-    // 修改candidate处理逻辑
-    socket.on("candidate", (data) => {
+      socket.on("candidate", (data) => {
         if (data.sender === socket.id) return;
         const peer = peers[data.sender];
-        peer.addIceCandidate(new RTCIceCandidate(data.candidate));
-    });
+        if (peer) {
+          peer.addIceCandidate(new RTCIceCandidate(data.candidate));
+        }
+      });
+
+      socket.on("user_joined", (userId) => {
+        peers[userId] = null;
+        if (!isMute) {
+          createPeerConnections();
+        }
+      });
+
+      socket.on("user_left", (userId) => {
+        if (peers[userId]) {
+          peers[userId].close();
+          delete peers[userId];
+        }
+      });
 
-    init();
+      init();
 </script>
 </body>
 </html>