客户端通过 websocket 连接从后端服务器数据库 table 检索数据
Client to retrieve data from backend server database table via a websocket connection
我正在使用以下服务器代码从 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`))
现在在客户端,我创建了以下到本地主机 3000 的 websocket 连接。
当第一次呈现下面的客户端代码时,数据显示在那里我也得到了所有的控制台日志消息,即 ws opened
、getting data....
和最后的控制台记录实际的 data
。
isPaused
也设置为 false。
我面临的问题是我不确定问题是什么,当我更新 country/temp 时,我希望看到我的客户端页面更新 country/temp 数据(没有页面刷新) my_temp_table
数据库 table 中的值,但它没有。
我预期的结果是,通过 websocket,只要我在服务器端更新 table,客户端就会通过下面的第二个 useEffect 挂钩更新 tempData
。
我基本上希望当后端数据库中的数据发生变化时,客户端通过 websocket 拉入并显示来自服务器的变化 table。
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>
)
}
您的客户如何知道服务器端的数据库是否有任何变化?
您可以创建一个事件,每次特定数据更改时都会触发该事件,并在您的客户端套接字上侦听这些事件。就像您在当前代码中处理 onmessage 事件一样。
你可以根据这个事件渲染react组件
代码只执行一次,因为没有重复调用网络套接字 send
事件。创建网络套接字后,它会从数据库中获取数据并发送,仅此而已。
您可能需要某种多次触发此事件的操作。例如,在您的代码中:
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.
我正在使用以下服务器代码从 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`))
现在在客户端,我创建了以下到本地主机 3000 的 websocket 连接。
当第一次呈现下面的客户端代码时,数据显示在那里我也得到了所有的控制台日志消息,即 ws opened
、getting data....
和最后的控制台记录实际的 data
。
isPaused
也设置为 false。
我面临的问题是我不确定问题是什么,当我更新 country/temp 时,我希望看到我的客户端页面更新 country/temp 数据(没有页面刷新) my_temp_table
数据库 table 中的值,但它没有。
我预期的结果是,通过 websocket,只要我在服务器端更新 table,客户端就会通过下面的第二个 useEffect 挂钩更新 tempData
。
我基本上希望当后端数据库中的数据发生变化时,客户端通过 websocket 拉入并显示来自服务器的变化 table。
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>
)
}
您的客户如何知道服务器端的数据库是否有任何变化? 您可以创建一个事件,每次特定数据更改时都会触发该事件,并在您的客户端套接字上侦听这些事件。就像您在当前代码中处理 onmessage 事件一样。
你可以根据这个事件渲染react组件
代码只执行一次,因为没有重复调用网络套接字 send
事件。创建网络套接字后,它会从数据库中获取数据并发送,仅此而已。
您可能需要某种多次触发此事件的操作。例如,在您的代码中:
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.