文章目录
- 前言
- 一、WebSocket是什么?
- 二、项目结构
- 三、代码实现
- 1. 后端实现
- 2. 前端实现
- 四、启动项目
- 总结
前言
随着区块链技术的发展,实时监控区块链网络中的区块和交易信息变得越来越重要。无论是开发去中心化应用(DApp),还是构建区块链浏览器,实时获取链上信息对于确保数据的透明和安全都是关键。在这篇博客中,我们将介绍如何使用 Node.js
结合 ethers.js
库,实现对区块链私有链的区块事件监听,并通过 WebSocket
技术将这些信息实时推送到前端页面进行展示。
本文将带你一步步实现一个简洁的区块链监控应用,实时展示最新生成的区块以及其中的交易。通过这个项目,你不仅能学会如何与区块链节点交互,还能了解如何使用 WebSocket
技术在前后端之间建立实时通信。
一、WebSocket是什么?
WebSocket 是一种全双工通信协议,允许客户端和服务器之间建立持续的、双向的连接,能够进行实时数据的交换。与传统的 HTTP 协议不同,WebSocket 在最初使用 HTTP 握手建立连接后,连接就会保持打开状态,直到客户端或服务器主动关闭。这种特性使得 WebSocket 特别适合需要频繁数据更新的场景,比如在线聊天、实时通知、股票行情、多人在线游戏等。
WebSocket的特点:
- 全双工通信:客户端和服务器可以随时互相发送消息,而不需要客户端先发起请求。
- 低延迟:由于连接保持活跃,数据可以快速传输,减少了 HTTP 协议的重复握手、建立连接的开销。
- 节省带宽:WebSocket 只需要一次握手,后续的数据传输不需要像 HTTP 那样每次附带大量的头部信息。
WebSocket的工作原理:
- 握手:客户端通过 HTTP 发起握手请求,服务器接收到请求并返回握手应答,确认使用 WebSocket 连接。
- 数据传输:握手完成后,连接持续打开,双方可以随时发送和接收数据,而不需要重新建立连接。
- 关闭连接:当通信结束时,客户端或服务器可以发起关闭请求,断开连接。
WebSocket应用场景:
- 在线游戏:支持实时游戏状态的更新。
- 实时股票行情:提供秒级股票价格更新。
- 在线聊天:实现消息的即时发送和接收。
- 实时协作:支持多人同时编辑文档或绘图。
在 Node.js
环境中,可以使用如 ws
模块来搭建 WebSocket 服务器和客户端。
在本项目中,我们使用 WebSocket 来建立服务器与前端的连接,每当区块链上有新的区块生成时,后端会通过 WebSocket 将区块信息推送给前端,前端收到后更新界面。
二、项目结构
项目的文件结构如下:
三、代码实现
1. 后端实现
在后端部分,我们使用 ethers.js
库连接到本地运行的 Geth 私有链(如果不知道如何搭建本地私链的可以去以往搭建博客🚪查看搭建教程),启动之后这样就可以了
通过监听新区块的生成,我们将区块信息通过 WebSocket 实时发送到前端。server.js
的实现如下:
// server.js
const { ethers, JsonRpcProvider } = require('ethers');
const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
// 连接到 Geth 私有链
const provider = new ethers.JsonRpcProvider('http://127.0.0.1:8888');
// 监听新块
provider.on('block', async (blockNumber) => {
console.log(`New Block: ${blockNumber}`);
const block = await provider.getBlock(blockNumber, true);
console.log('block===:', block);
console.log(block.transactions);
const data = {
blockNumber: block.number,
blockHash: block.hash,
timestamp: block.timestamp,
transactions: block.transactions.map(tx => ({
hash: tx,
}))
};
console.log('data===:', data);
// 通过 WebSocket 发送数据到客户端
wss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(data));
}
});
});
// 配置静态文件夹
app.use(express.static('public'));
// 启动服务器
server.listen(4000, () => {
console.log('Server is listening on port 4000');
});
代码解读
-
依赖库引入: 我们使用
ethers.js
来连接 Geth 节点,使用express
作为 HTTP 服务器,ws
库用于创建 WebSocket 服务。 -
连接 Geth 节点: 使用
ethers.JsonRpcProvider
来连接 Geth 节点。在此示例中,节点运行在http://127.0.0.1:8888
,即本地的私有链。 -
监听区块事件: 通过
provider.on('block', async (blockNumber) => {...})
,每当有新块生成时,该函数会被触发。我们获取区块详细信息,并提取区块哈希、区块高度和交易哈希等数据。 -
WebSocket 数据传输: 每当区块信息更新时,数据会通过
WebSocket
发送给所有连接的客户端。 -
服务器启动: 我们将 HTTP 服务器监听在
4000
端口,并通过express.static
公开public
文件夹中的静态文件。
2. 前端实现
前端部分非常简洁,主要用于展示最新的区块信息和交易哈希。index.html
文件的实现如下:
<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blockchain Monitor</title>
</head>
<body>
<h1>Blockchain 监控</h1>
<div id="output"></div>
<script>
const ws = new WebSocket('ws://localhost:4000');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
const output = document.getElementById('output');
const blockInfo = `
<h2>区块高度: ${data.blockNumber}</h2>
<h3>区块Hash: ${data.blockHash}</h3>
<h3>timestamp: ${data.timestamp}</h3>
<ul>
${data.transactions.map(tx => ` <li> <strong>Transaction Hash:</strong> ${tx.hash}<br> </li> `).join('')}
</ul>
`;
output.innerHTML = blockInfo;
};
ws.onopen = () => {
console.log('Connected to WebSocket server');
};
ws.onclose = () => {
console.log('Disconnected from WebSocket server');
};
</script>
</body>
</html>
代码解读
-
WebSocket 连接: 前端通过
new WebSocket('ws://localhost:4000')
连接到后端的 WebSocket 服务器。 -
处理区块数据: 当收到来自服务器的区块数据时,通过
ws.onmessage
事件解析数据并更新页面。 -
页面展示: 页面显示最新区块的高度、区块哈希、时间戳以及该区块中的所有交易哈希。
四、启动项目
-
启动 Geth 私有链: 首先需要启动 Geth 私有链,并确保其监听在
http://127.0.0.1:8888
上 -
安装依赖: 在项目根目录下运行以下命令安装所需的依赖库:
npm install ethers express ws
- 启动服务器: 运行以下命令启动后端服务器:
node server.js
- 打开浏览器: 在vscode打开
index.html
,右键点击Open In Default Browser
你将看到最新的区块信息和交易哈希,例如:
通过这个示例,你可以进一步扩展功能,比如展示更多的区块详细信息、过滤特定交易、监控智能合约事件,或者是将区块数据在
provider.on('block')
事件中进行存储数据库的操作等,构建出功能丰富的区块链应用。
总结
通过本文,我们详细介绍了如何使用 Node.js
和 ethers.js
库实现对 Geth 私有链的区块事件监听,并通过 WebSocket
技术将区块信息实时推送到前端。我们从 WebSocket 的基础概念讲起,展示了如何搭建一个全双工通信的实时系统,最终实现了一个区块链监控应用,能够实时展示最新生成的区块和交易信息。本文还包含了完整的后端与前端代码示例,帮助开发者掌握从监听区块事件到通过 WebSocket 进行前后端实时通信的整个过程。希望这篇文章能帮助你在区块链应用开发中实现更多实时数据交互的功能。如果你有任何疑问或建议,欢迎在评论区留言讨论🌹