javascript - 客户端通过 websocket 连接从后端服务器数据库表中检索数据
问题描述
我正在使用以下服务器代码从 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 opened
,getting data....
最后控制台记录实际的data
.
isPaused
也设置为假。
我面临的问题并且不确定问题是什么,当我更新my_temp_table
数据库表中的国家/地区/临时值时,我希望看到我的客户端页面更新国家/临时数据(没有页面刷新),但它没有吨。
我期望的结果是,通过 websocket,只要我在服务器端的表更新,客户端就会tempData
通过下面的第二个 useEffect 钩子更新 .
当后端数据库表中的数据发生变化时,我基本上希望客户端通过 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>
)
}
解决方案
该代码只执行一次,因为没有对 Web 套接字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 数据库中汇集。看看这个其他例子。