You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Node.js Express服务器与C# Windows Forms客户端的全客户端变更通知实现方案咨询

嘿,这个实时通知的需求其实挺常见的,作为网络新手,我给你拆解几个好上手的方案,一步步来肯定能搞定:

方案1:WebSocket(最推荐,实时性强)

HTTP是"请求-响应"模式,服务器没法主动给客户端发消息,而WebSocket是双向通信协议,刚好能解决服务器主动推送变更通知的问题,适合你的场景。

服务器端(Node.js Express)

我推荐用轻量易用的ws库,先安装它:

npm install ws

然后写核心代码:

const express = require('express');
const http = require('http');
const WebSocket = require('ws');

const app = express();
const server = http.createServer(app);
// 启动WebSocket服务
const wss = new WebSocket.Server({ server });

// 用Set存储所有在线的客户端连接
const connectedClients = new Set();

// 处理新客户端连接
wss.on('connection', (ws) => {
  console.log('有新客户端连进来啦');
  connectedClients.add(ws);

  // 客户端断开时移除连接
  ws.on('close', () => {
    console.log('客户端断开连接');
    connectedClients.delete(ws);
  });

  // 接收客户端发来的修改通知,然后广播给所有人
  ws.on('message', (message) => {
    connectedClients.forEach(client => {
      // 只给在线的客户端发消息
      if (client.readyState === WebSocket.OPEN) {
        client.send(message);
      }
    });
  });
});

server.listen(3000, () => {
  console.log('服务器跑在 http://localhost:3000');
});

客户端(C# WinForms)

用.NET自带的System.Net.WebSockets.ClientWebSocket就行,不用额外装包,核心代码示例:

using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

public partial class MainForm : Form
{
    private ClientWebSocket _webSocket;
    private readonly CancellationTokenSource _cts = new CancellationTokenSource();

    public MainForm()
    {
        InitializeComponent();
    }

    // 窗体加载时连接WebSocket服务器
    private async void MainForm_Load(object sender, EventArgs e)
    {
        _webSocket = new ClientWebSocket();
        try
        {
            await _webSocket.ConnectAsync(new Uri("ws://localhost:3000"), _cts.Token);
            MessageBox.Show("成功连到服务器啦");
            // 单独开个任务监听服务器发来的消息
            _ = ListenForServerMessages();
        }
        catch (Exception ex)
        {
            MessageBox.Show($"连接失败:{ex.Message}");
        }
    }

    // 监听服务器消息的方法
    private async Task ListenForServerMessages()
    {
        var buffer = new byte[4096];
        while (_webSocket.State == WebSocketState.Open)
        {
            var receiveResult = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), _cts.Token);
            if (receiveResult.MessageType == WebSocketMessageType.Text)
            {
                var message = Encoding.UTF8.GetString(buffer, 0, receiveResult.Count);
                // WinForms不能在后台线程操作UI,所以用Invoke切回主线程
                this.Invoke((Action)(() =>
                {
                    MessageBox.Show($"收到数据变更通知:{message}");
                    // 这里写你更新本地数据的逻辑
                }));
            }
        }
    }

    // 比如点击"修改数据"按钮后,给服务器发通知
    private async void btnUpdateData_Click(object sender, EventArgs e)
    {
        if (_webSocket.State != WebSocketState.Open)
        {
            MessageBox.Show("还没连到服务器呢");
            return;
        }
        // 这里可以换成你实际的变更内容
        var updateMsg = $"用户修改了XXX数据:{DateTime.Now}";
        var buffer = Encoding.UTF8.GetBytes(updateMsg);
        await _webSocket.SendAsync(
            new ArraySegment<byte>(buffer), 
            WebSocketMessageType.Text, 
            true, 
            _cts.Token
        );
    }

    // 窗体关闭时清理WebSocket连接
    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        _cts.Cancel();
        if (_webSocket.State == WebSocketState.Open)
        {
            _webSocket.CloseAsync(
                WebSocketCloseStatus.NormalClosure, 
                "客户端关闭", 
                CancellationToken.None
            );
        }
    }
}
方案2:轮询(最简单,快速上手)

如果觉得WebSocket有点复杂,可以先从轮询入手——就是客户端定期给服务器发请求,问"有没有新的数据变更?"。

服务器端

维护一个全局的更新时间戳,每次数据修改就更新它,再提供一个接口让客户端查询:

let lastUpdateTime = Date.now();
let latestChangedData = null;

// 处理数据修改的接口
app.post('/update-data', (req, res) => {
  // 这里写你的数据修改逻辑
  latestChangedData = req.body;
  lastUpdateTime = Date.now();
  res.send("数据修改成功");
});

// 客户端轮询查更新的接口
app.get('/check-updates', (req, res) => {
  const clientLastTime = parseInt(req.query.lastTime) || 0;
  if (clientLastTime < lastUpdateTime) {
    res.json({
      hasUpdate: true,
      updateTime: lastUpdateTime,
      data: latestChangedData
    });
  } else {
    res.json({ hasUpdate: false });
  }
});

客户端

用WinForms的Timer控件定期发HTTP请求检查更新:

using System;
using System.Net.Http;
using System.Windows.Forms;

public partial class MainForm : Form
{
    private HttpClient _httpClient;
    private Timer _pollTimer;
    private long _lastUpdateTime = 0;

    public MainForm()
    {
        InitializeComponent();
        _httpClient = new HttpClient();
        _pollTimer = new Timer();
        _pollTimer.Interval = 5000; // 每5秒查一次
        _pollTimer.Tick += CheckForUpdates;
    }

    private void MainForm_Load(object sender, EventArgs e)
    {
        _pollTimer.Start();
    }

    private async void CheckForUpdates(object sender, EventArgs e)
    {
        try
        {
            var response = await _httpClient.GetAsync(
                $"http://localhost:3000/check-updates?lastTime={_lastUpdateTime}"
            );
            response.EnsureSuccessStatusCode();
            var updateInfo = await response.Content.ReadFromJsonAsync<UpdateInfo>();
            
            if (updateInfo.HasUpdate)
            {
                _lastUpdateTime = updateInfo.UpdateTime;
                MessageBox.Show($"收到数据变更:{updateInfo.Data}");
                // 更新本地数据
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show($"查更新失败:{ex.Message}");
        }
    }

    // 用来接收服务器返回的更新信息
    public class UpdateInfo
    {
        public bool HasUpdate { get; set; }
        public long UpdateTime { get; set; }
        public object Data { get; set; }
    }
}
方案对比&新手建议
  • WebSocket:实时性拉满,服务器主动推消息,适合对实时性要求高的场景;代码稍复杂,但学会后是通用技能
  • 轮询:代码最简单,不用学新协议;但实时性差(取决于轮询间隔),会多一些无用请求,服务器压力稍大

建议你先从轮询入手,快速跑通整个流程,理解数据变更通知的逻辑;之后再尝试WebSocket,这是更标准的实时通信方案,以后做类似项目也能用。调试的时候记得多开几个客户端测试,修改数据后看其他客户端能不能收到通知~

内容的提问来源于stack exchange,提问作者Lysander12 PT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 08:07:39