基于 C# Ashx 与长轮询实现简易在线聊天室

沈知远
沈知远
发布时间:2026-10-14| 3人浏览过
原创

在 HTML5 WebSocket 普及之前,实现网页版即时通讯通常依赖定时轮询或长连接+长轮询技术。本文提供一个基于 C# (ASP.NET) 和原生 JavaScript/AJAX 的多人聊天室实现方案,利用长轮询维持实时性,并通过内存集合管理用户状态与聊天记录。

实现原理与架构

该聊天室采用前后端分离的简单结构,不依赖第三方库或数据库:

  • 前端交互:使用原生 JavaScript 发送 AJAX 请求,接收 JSON 格式数据并动态渲染聊天记录与在线列表。
  • 后端处理:C# .ashx 一般处理程序作为核心服务,负责解析客户端请求(发送消息、获取消息、设置状态)。
  • 通信模式:采用长轮询机制。前端持续请求后端获取未读消息,后端在有新消息时立即响应,从而实现近实时的信息推送。
  • 数据存储:所有聊天记录和在线用户列表均保存在服务器端的静态内存集合中。

服务端核心逻辑 (C#)

服务端代码位于 ChatHandler.ashx 中,继承自 IHttpHandler。主要涉及线程安全的并发操作,因为多个用户可能同时访问。

第1步:定义数据结构与存储容器

服务端需维护两个主要的静态集合:一个用于存储聊天消息,一个用于记录当前在线用户名。由于是多线程环境,必须引入锁机制(如 lock 或 ReaderWriterLockSlim)来保证数据读写的安全性。

// 消息实体类定义
private class Msg {
    public string name { get; set; }
    public string sendtime { get; set; }
    public string content { get; set; }
    // ... 其他属性如 readedCount 等
}

// 全局静态变量
private static List<Msg> msgs = new List<Msg>();
private static List<string> onLineNames = new List<string>;
private static object syncObject = new object();

第2步:实现消息发送与状态同步

当用户点击“发送”或“进入聊天室”时,前端调用 ProcessRequest 中的对应 Case。后端会将新消息封装成对象加入 msgs 列表,并将当前时间戳和内容存入。

case "send":
{
    responseObject = SendMessage(chatName, msg, "normal");
    break;
}
case "on":
{
    // 将用户名加入在线列表
    lock (syncObject)
    {
        onLineNames.Add(chatName);
    }
    // 生成一条特殊的上线通知消息
    responseObject = SetChatStatus(chatName, actionName);
    break;
}

注意:为了简化演示,使用了 lock(syncObject) 进行简单的互斥锁保护。在生产环境中,建议根据实际负载选择更精细的锁策略或使用分布式缓存。

第3步:实现长轮询获取新消息

这是实现即时性的关键。前端不断发起 action=receive 请求,后端需要检查是否有该用户未读取的消息。如果有,立即返回;如果没有,则让线程短暂休眠(如 Thread.Sleep(1000)),然后循环检查,直到有新消息到达才退出循环并返回结果。这种循环等待机制构成了“长轮询”。

前端交互实现 (JavaScript + AJAX)

前端页面是一个纯 HTML 文件,通过内嵌 JS 完成所有逻辑。核心功能包括初始化 DOM、绑定按钮事件以及周期性轮询。

第4步:构建 AJAX 通信层

创建一个通用的 callAjax 函数,封装 XMLHttpRequest 对象。设定请求方式为 POST,目标为 ChatHandler.ashx,并将参数序列化为查询字符串发送。

function callAjax(ajax, param, callback) {
    ajax.open("post", "ChatHandler.ashx", true);
    ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    ajax.onreadystatechange = function () {
        if (ajax.readyState == 4 && ajax.status == 200) {
            var json = eval("(" + ajax.responseText + ")");
            callback(json);
        }
    };
    ajax.send(param);
}

第5步:实现消息展示与自动更新

收到后端返回的 JSON 后,解析其中的消息数组,并在聊天框内插入新的 DOM 节点。对于用户的上下线状态变化,还需刷新右侧的在线人员列表。

图例:张三视角下的聊天界面,显示双方对话与顶部栏信息。

运行效果测试

启动 IIS 或 VS 内置服务器后,打开多个浏览器标签页模拟不同用户。在各自昵称输入框中输入名称并点击“确认进入”,即可看到彼此在线。

图例:李四视角,此时可以看到张三已上线的提示信息。

在任一窗口发送消息,其他窗口会在几秒钟内(取决于轮询间隔)自动刷出最新内容。当某用户关闭页面或断开连接时,window.onunload 事件会触发最后一次的离线通知请求,确保其他用户看到离线的提示。

图例:小美视角,展示多人同时在线及历史记录滚动加载的效果。

总结与注意事项

该方案虽然简陋,但清晰地展示了在没有现代 Web Socket 技术支持下,如何利用传统 HTTP 协议栈构建即时互动应用。关键点在于理解:
- 后端如何通过循环阻塞来实现类似推流的伪实时响应。
- 前端如何维护本地会话状态并与服务器保持心跳般的请求频率。

如果在实际部署中遇到消息延迟或内存溢出问题,可考虑将静态集合替换为 Redis 或 Memcached,并优化轮询的频率与锁的粒度。

以上就是基于 C# Ashx 与长轮询实现简易在线聊天室的详细内容,更多关于 C# 网络编程及前端异步通信的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。