【问题标题】:Client to retrieve data from backend server database table via a websocket connection客户端通过 websocket 连接从后端服务器数据库表中检索数据
【发布时间】:2021-11-27 05:53:36
【问题描述】:

我正在使用以下服务器代码从 postgres 数据库中检索数据:

    const express = require('express')
    const app = express()
    const server = require('http').createServer(app);
    const pool = require("postgresql");
    const WebSocket = require('ws');
    
    const wss = new WebSocket.Server({ server:server });
    
const getTempData = async () => {
  try {
    const tempData = await pool.query("select country, temp from my_temp_table");
    return JSON.stringify(tempData.rows)
  } catch(err) {
      console.error(err.messasge);
  }
}

wss.on('connection', async (webSocketClient) => {
  console.log('A new client Connected!');   
  const tempDetails = await getTempData();
  
  webSocketClient.send(tempDetails);      
  webSocketClient.on('message', (message) => {
    console.log('received: %s', message);    
  });
});           
server.listen(3000, () => console.log(`Listening on port :3000`))

现在在客户端,我创建了以下到 localhost 3000 的 websocket 连接。

当第一次渲染下面的客户端代码时,数据显示在我还得到所有控制台日志消息的地方,即ws openedgetting data....,最后是控制台记录实际的data

isPaused 也设置为 false。

我面临的问题是我希望看到我的客户端页面更新国家/临时数据(没有页面刷新),当我更新my_temp_table 数据库中的国家/临时值时表,但它没有。

我预期的结果是,通过 websocket,只要我在服务器端的表更新,客户端就会通过下面的第二个 useEffect 挂钩更新tempData

当后端数据库表中的数据发生变化时,我基本上希望客户端通过 websocket 拉入并显示来自服务器的更改。

import React, { useState, useEffect, useRef } from 'react';

export default function Temperature() {

  const [isPaused, setPause] = useState(false);
  const [tempData, setTempData] = useState([]);
  const [name, setName] = useState(null);
  const ws = useRef(null);

  useEffect(() => {
    ws.current = new WebSocket("ws://localhost:3000");
    ws.current.onopen = () => {
      console.log("ws opened");
    }
    ws.current.onclose = () => console.log("ws closed");    

    return () => {
        ws.current.close();
    };
  }, []);

  useEffect(() => {
      if (!ws.current) return;

      ws.current.onmessage = e => {
          if (isPaused) return;
          console.log("getting temp data....");
          const data = JSON.parse(e.data);
          setTempData(data)          
          console.log("data: ",data);
      };
  }, [isPaused]);

  return (
    <div>
        <button onClick={() => setPause(!isPaused)}>
            {isPaused ? "Resume" : "Pause"}
        </button>

        { tempData? 
          tempData.map((data, i) => ( 
            <div>
              <span>{data.country}</span> 
              <span>{data.temp}</span> 
            </div>
          ))
          : null }
    </div>
  )
}

【问题讨论】:

    标签: javascript node.js reactjs express websocket


    【解决方案1】:

    代码只执行一次,因为没有重复调用网络套接字send 事件。创建 Web 套接字时,它会从数据库中获取数据并发送,就是这样。

    您可能想要多次触发此事件的某种操作。例如,在您的代码中:

    wss.on("connection", async webSocketClient => {
        console.log("A new client Connected!");
    
        setInterval(() => {
            const timeNow = Date.now();
    
            webSocketClient.send(
                JSON.stringify([
                    { country: "country-a", temp: timeNow },
                    { country: "country-b", temp: timeNow },
                ])
            );
        }, 1000);
    
        webSocketClient.on("message", message => {
            console.log("received: %s", message);
        });
    });
    

    我看到您正在使用一些包从 PostgreSQL 数据库中进行池化。看看this other example

    【讨论】:

      【解决方案2】:

      您的客户如何知道服务器端的数据库是否有任何变化? 您可以创建一个在每次特定数据更改时触发的事件,并在客户端套接字上侦听这些事件。就像您在当前代码中处理 onmessage 事件一样。

      你可以根据这个事件来渲染 react 组件。

      【讨论】:

      • 我有点不确定你的意思,因为 websockets 对我来说是新的。当您说“您可以创建一个在每次特定数据更改时触发的事件并在您的客户端套接字上监听这些事件”时,您能否详细说明一下?任何示例代码都会有帮助,所以我明白你的意思。
      • 抱歉,这可能是一个完整的项目。但是我建议您是否可以从以下文章中获得一些帮助。 sitepoint.com/real-time-apps-websockets-server-sent-events
      • 所以基本上 SSE 与 websockets 不同,我将使用与 websockets 完全不同的东西?在我的场景中,客户端不需要向服务器发送数据,它只需要在数据发生变化时从服务器接收数据,并将这些变化反映在客户端中,无需刷新页面。服务器发送的事件会执行此要求吗?
      • 是的,在这种情况下,服务器将向所有连接的客户端发送事件的任何时间点。(这可能是发送给所有客户端的消息,或者您可以只是广播消息)。根据该消息,您可以在客户端应用程序中设置一些状态并根据状态更改呈现特定组件。您可以向套接字发送一些数据,也可以只发送一条简单的消息,然后客户端可以从 api 获取数据。
      • 我已经为你创建了一个演示项目,请查看我的 repo github.com/brijeshdave/wesocket_server_drivern_event
      猜你喜欢
      • 2016-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-29
      • 2017-11-30
      • 1970-01-01
      相关资源
      最近更新 更多