在现代 Web 应用中,实时通信变得越来越重要。无论是聊天应用、在线游戏、股票行情推送还是协作编辑工具,都需要服务器能够主动向客户端推送数据。在 .NET 生态系统中,WebSocket 和 SignalR 是实现这一功能的两个主要方案。
本文将对这两种技术进行比较,分析它们的异同点和使用场景,并提供简单示例代码帮助你快速上手。
一、什么是 WebSocket?
WebSocket 是 HTML5 提供的一种全双工通信协议,允许客户端与服务器之间建立持久连接,实现双向实时通信。相比传统的 HTTP 请求-响应模式,WebSocket 更加高效,适合需要频繁交互的应用。
WebSocket 特点:
- 基于 TCP 协议
- 支持双向通信
- 连接是长连接(保持打开)
- 轻量级,性能高
- 需要手动管理连接和消息处理
使用场景:
- 实时数据推送(如股票行情)
- 在线多人游戏
- 多人协作编辑
- IoT 设备通信等
二、什么是 SignalR?
SignalR 是微软开发的一个基于 .NET 的库,它简化了实时通信的实现。SignalR 内部封装了多种传输方式(包括 WebSocket、Server-Sent Events、长轮询等),并根据浏览器和网络环境自动选择最优的方式。
SignalR 特点:
- 抽象了底层通信细节
- 支持跨平台(.NET Core / .NET 6+)
- 自动降级兼容性差的浏览器
- 提供 Hub 模式,易于组织业务逻辑
- 可集成到 ASP.NET Core 中
使用场景:
- 快速构建实时功能(无需关注底层通信细节)
- Web 应用中的通知系统
- 即时通讯(IM)应用
- 实时仪表盘、状态监控
三、WebSocket vs SignalR 对比
特性 | WebSocket | SignalR |
---|---|---|
通信方式 | 全双工 | 全双工(通过封装) |
是否需要手动处理连接 | 需要 | 不需要 |
是否支持多路复用 | 不支持 | 支持(Hub) |
是否支持自动降级 | 不支持 | 支持(长轮询等) |
开发复杂度 | 较高 | 较低 |
性能 | 高 | 略低于 WebSocket |
适合场景 | 高性能、定制化通信 | 快速开发、通用实时功能 |
四、示例代码
示例 1:WebSocket 服务端 + 客户端(.NET)
服务端(控制台程序)
using System;
using System.Net;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://localhost:5000/");
listener.Start();
Console.WriteLine("WebSocket Server started on http://localhost:5000");
while (true)
{
HttpListenerContext context = await listener.GetContextAsync();
if (context.Request.IsWebSocketRequest)
{
WebSocketContext webSocketContext = await context.AcceptWebSocketAsync(null);
_ = HandleWebSocketConnection(webSocketContext.WebSocket);
}
else
{
context.Response.StatusCode = 400;
context.Response.Close();
}
}
}
private static async Task HandleWebSocketConnection(WebSocket socket)
{
byte[] buffer = new byte[1024 * 4];
while (socket.State == WebSocketState.Open)
{
WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
string message = Encoding.UTF8.GetString(buffer, 0, result.Count);
Console.WriteLine($"Received: {message}");
// Echo back the message
byte[] response = Encoding.UTF8.GetBytes($"Echo: {message}");
await socket.SendAsync(new ArraySegment<byte>(response), WebSocketMessageType.Text, true, CancellationToken.None);
}
}
}
客户端(JavaScript)
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Client</title>
</head>
<body>
<input type="text" id="messageInput" placeholder="Enter message" />
<button onclick="sendMessage()">Send</button>
<div id="output"></div>
<script>
const ws = new WebSocket('ws://localhost:5000');
ws.onmessage = function (event) {
document.getElementById('output').innerText += event.data + '\n';
};
function sendMessage() {
const input = document.getElementById('messageInput');
const message = input.value;
ws.send(message);
input.value = '';
}
</script>
</body>
</html>
示例 2:SignalR 服务端 + 客户端(ASP.NET Core)
服务端(Startup.cs 或 Program.cs)
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddSignalR();
var app = builder.Build();
app.MapHub<ChatHub>("/chatHub");
app.Run();
public class ChatHub : Hub
{
public async Task Send(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
客户端(JavaScript)
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/5.0.13/signalr.min.js"></script>
<input type="text" id="userInput" placeholder="User" />
<input type="text" id="messageInput" placeholder="Message" />
<button onclick="sendMessage()">Send</button>
<div id="chat"></div>
<script>
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chatHub")
.build();
connection.on("ReceiveMessage", function (user, message) {
const msg = `${user}: ${message}`;
document.getElementById("chat").innerHTML += `<p>${msg}</p>`;
});
connection.start().catch(function (err) {
return console.error(err.toString());
});
function sendMessage() {
const user = document.getElementById("userInput").value;
const message = document.getElementById("messageInput").value;
connection.invoke("Send", user, message).catch(function (err) {
return console.error(err.toString());
});
document.getElementById("messageInput").value = "";
}
</script>
五、总结
场景 | 推荐技术 |
---|---|
高性能、低延迟、自定义协议 | WebSocket |
快速开发、通用实时功能 | SignalR |
浏览器兼容性要求高 | SignalR |
需要精细控制通信过程 | WebSocket |
如果你正在开发一个简单的聊天室或通知系统,SignalR 是更好的选择;而如果你需要构建一个高性能、低延迟的物联网通信系统,WebSocket 更合适。
六、延伸阅读
- Microsoft SignalR 文档
- WebSocket W3C 标准文档
- ASP.NET Core WebSocket 支持
希望这篇博客对你有所帮助!如果你有更多关于 C# 或实时通信的问题,欢迎留言交流
来源链接:https://www.cnblogs.com/wwwan/p/18863581
© 版权声明
本站所有资源来自于网络,仅供学习与参考,请勿用于商业用途,否则产生的一切后果将由您(转载者)自己承担!
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
THE END
暂无评论内容