瀏覽代碼

加上註解

maa3520 1 年之前
父節點
當前提交
b0cf705e9e
共有 4 個文件被更改,包括 44 次插入29 次删除
  1. 5 3
      routers/api.js
  2. 7 8
      server.js
  3. 6 1
      static/index.html
  4. 26 17
      static/js/frontend.js

+ 5 - 3
routers/api.js

@@ -102,12 +102,14 @@ router.get("/weather", async (req, res) => {
   }
 });
 
-router.post('/websocket-test', (req, res) => {
+router.post('/websocket-test', (req, res) => { //這邊做一個測試
   const message = req.body.message || 'Test message from server';
-  // 使用 global.wss 访问 WebSocket 服务器实例
   global.wss.clients.forEach(client => {
     if (client.readyState === WebSocket.OPEN) {
-      client.send(message);
+      client.send(JSON.stringify({
+        type: 'testMessage',
+        message: message
+      }));
     }
   });
 

+ 7 - 8
server.js

@@ -10,7 +10,7 @@ db.users_init_fixed()
 db.vote_init_random(5);     // you COULD change this, but you could also leave it alone?
 
 const app = express();
-const server = http.createServer(app);
+const server = http.createServer(app); //把express透過http createServer 
 
 const PORT = process.env.PORT || 8000; // 允許從 .env 文件或環境變量中設定端口
 app.use(express.static("static"))
@@ -32,15 +32,14 @@ app.use('/api/v1', apiRouter);
 
 
 
-const wss = new WebSocket.Server({ server });
-global.wss = wss; //fix it future
+const wss = new WebSocket.Server({ server }); //server的資訊拿去架設websocket
+global.wss = wss; //fix it future   把wss設定存放到global供其他js檔案存取 PS:寫成global不是很好的做法 你可以考慮替換成更好的方法?
 
+wss.on('connection', ws => { //建立連線
+  console.log('New WebSocket connection'); //提示server端成功建立連線
 
-wss.on('connection', ws => {
-  console.log('New WebSocket connection');
-
-  ws.on('message', message => {
-      console.log(`Received message: ${message}`);
+  ws.on('message', message => { //接收客戶端傳送來的訊息
+      console.log(`Received message: ${message}`); //紀錄客戶端傳送來的訊息
       // 廣播消息給所有連接的客戶端
       wss.clients.forEach(client => {
           if (client !== ws && client.readyState === WebSocket.OPEN) {

+ 6 - 1
static/index.html

@@ -7,7 +7,7 @@
     <title>Jicnic - Jlan your next picnic!</title>
     <link rel="stylesheet" href="/styles/styles.css" />
     <link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon" />
-    <script src="https://unpkg.com/axios/dist/axios.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
     <script defer src="/js/api_calls.js"></script>
     <script defer src="/js/frontend.js"></script>
   </head>
@@ -43,6 +43,11 @@
       <section class="refresh">
         <button id="refreshVotes">🔄</button>
       </section>
+      <section class="refresh">
+        <div  style="color: rgb(0, 48, 48)">
+          <span class="ws">test</span>
+        </div>
+      </section>
       <section class="days-view"></section>
     </main>
   </body>

+ 26 - 17
static/js/frontend.js

@@ -115,28 +115,30 @@ class FrontendState {
   }
 
   initWebSocket() {
-    const host = window.location.hostname;
-    const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
-    const wsPort = window.location.port ? `:${window.location.port}` : ''; // 适应可能的端口变化
-    const wsUrl = `${wsProtocol}//${host}${wsPort}`;
+    const host = window.location.hostname; //設定WebSocket host ip
+    const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; //設定protocol 如果是https 就用wss 反之ws
+    const wsPort = window.location.port ? `:${window.location.port}` : ''; //設定ws用的port
+    const wsUrl = `${wsProtocol}//${host}${wsPort}`; //拼起來就是完整的WebSocket囉
 
-    this.ws = new WebSocket(wsUrl);
+    this.ws = new WebSocket(wsUrl); //設定完畢並開啟服務
 
-    this.ws.onopen = () => {
-      console.log('WebSocket connected');
+    this.ws.onopen = () => { //onopen ws服務開啟的時候會先執行的
+      console.log('WebSocket connected'); //提示ws已經連線成功
     };
 
-    this.ws.onmessage = (event) => {
-      console.log('Message from server ', event.data);
-      const data = JSON.parse(event.data); // 解析服务器发送的消息
+    this.ws.onmessage = (event) => { //這邊負責監聽比如從伺服端傳來的訊息
+      console.log('Message from server ', event.data); //log 從server端傳來的訊息
+      const data = JSON.parse(event.data); //json解析 data
 
-      // 检查消息类型
-      if (data.type === 'voteUpdate') {
-        this.refreshVotesState(true); // 当收到投票更新消息时,刷新投票状态
+      if (data.type === 'voteUpdate') { //如果type為voteUpdate 更新vote結果 ps: 這是自己定義的 
+        this.refreshVotesState(true);
+      }
+      if (data.type === 'testMessage') { //如果type為voteUpdate 更新vote結果 ps: 這是自己定義的 
+        this.updateWSMessage(data.message);
       }
     };
 
-    this.ws.onerror = (error) => {
+    this.ws.onerror = (error) => { //這邊負責紀錄傳送異常的訊息
       console.error('WebSocket error', error);
     };
   }
@@ -169,7 +171,7 @@ class FrontendState {
     }
   }
 
-  async refreshWeatherState(updateView = true) {
+  async refreshWeatherState(updateView = true) { 
     let {
       success,
       data,
@@ -186,7 +188,7 @@ class FrontendState {
     }
   }
 
-  async refreshSessionState(updateView = true) {
+  async refreshSessionState(updateView = true) { 
     let {
       success,
       data,
@@ -220,6 +222,11 @@ class FrontendState {
       this.weatherForecasts
     );
   }
+
+  async updateWSMessage(message) {
+    const wsMessageDiv = document.querySelector(".ws");
+    wsMessageDiv.textContent = message;
+  }
 }
 
 const fes = new FrontendState();
@@ -266,6 +273,8 @@ function updateErrorMessage(message) {
   errorMessageDiv.textContent = message;
 }
 
+
+
 const authform = document.querySelector("form.authform");
 authform.addEventListener("click", handleAuthEvent);
 
@@ -297,5 +306,5 @@ const daysViewDiv = document.querySelector("section.days-view");
 daysViewDiv.addEventListener("click", handleVoteEvent);
 
 document.getElementById('refreshVotes').addEventListener('click', function () {
-  fes.refreshVotesState(true);
+  fes.refreshVotesState(true);// 重新獲取並顯示最新的投票資訊 並更新VIEW
 });