首先,要使用WebSocket与网页实时通信,需要在C#时编写WebSocket服务端,并在网页中使用JavaScript编写WebSocket客户端。下面是实现该功能的完整攻略:
C# WebSocket服务端
- 创建新项目。在Visual Studio里新建一个Class Library项目。
- 安装Newtonsoft.Json NuGet包。在项目中右击References,选择Manage NuGet Packages,搜索安装Newtonsoft.Json。
- 创建WebSocket服务端。在项目内新建一个类,命名为WebSocketServer,继承自Microsoft.Web.WebSockets.WebSocketHandler。
- 实现WebSocketServer。在WebSocketServer中,重写OnOpen、OnMessage、OnClose方法,实现WebSocket的开启、接收信息、关闭等操作。代码如下:
using Microsoft.Web.WebSockets;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace CSharpWebSocketServer
{
public class WebSocketServer : WebSocketHandler
{
private static List<WebSocketServer> _webSocketServers = new List<WebSocketServer>();
private string _clientId;
public WebSocketServer(string clientId)
{
_clientId = clientId;
//将WebSocketServer实例添加到_webSocketServers列表中
_webSocketServers.Add(this);
}
//发送信息
private async Task SendMessage(string message)
{
if (this.WebSocket != null &&
this.WebSocket.State == WebSocketState.Open)
{
//将message传入到客户端中
await this.WebSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(message)),
WebSocketMessageType.Text, true, System.Threading.CancellationToken.None);
}
}
//广播信息
private static async Task BroadcastMessage(string message)
{
var copy = _webSocketServers.ToList();
foreach (var webSocketServer in copy)
{
await webSocketServer.SendMessage(message);
}
}
//WebSocket开启
public override void OnOpen()
{
//跟客户端确认连接已建立,否则连接将会断开
var authenticationString = Context.Headers["Sec-WebSocket-Key"] + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
var bytes = Encoding.UTF8.GetBytes(authenticationString);
var sha1 = SHA1.Create();
var hash = sha1.ComputeHash(bytes);
var response = Convert.ToBase64String(hash);
this.WebSocket.Send($"HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: {response}\r\n\r\n");
}
//WebSocket接收信息
public override void OnMessage(string message)
{
//广播信息
BroadcastMessage(message);
}
//WebSocket断开
public override void OnClose()
{
//将WebSocketServer实例从_webSocketServers列表中移除
_webSocketServers.Remove(this);
//广播离开信息
var leaveMessage = new { Type = "leave", Id = _clientId };
BroadcastMessage(JsonConvert.SerializeObject(leaveMessage));
}
}
}
- 创建WebSocket服务端主程序。在项目内新建一个类,命名为Program,定义Main方法。在Main方法中,实例化一个HttpListenerWrapper,并利用HttpListenerWrapper启动WebSocket服务端。代码如下:
using System;
using System.Threading.Tasks;
namespace CSharpWebSocketServer
{
class Program
{
static void Main(string[] args)
{
var httpListenerWrapper = new HttpListenerWrapper();
httpListenerWrapper.Start();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
public class HttpListenerWrapper
{
// WebSocket请求的地址
const string ListenerAddress = "http://localhost:8888/realtime";
internal void Start()
{
using (var listener = new System.Net.HttpListener())
{
listener.Prefixes.Add(ListenerAddress + "/");
listener.Start();
Console.WriteLine($"开始监听地址{ListenerAddress}");
while (true)
{
var context = listener.GetContextAsync().Result;
if (context.Request.IsWebSocketRequest)
{
AcceptWebSocketAsync(context).Wait();
}
}
}
}
async Task AcceptWebSocketAsync(System.Net.HttpListenerContext context)
{
if (context.Request.IsWebSocketRequest)
{
var subProtocol = context.Request.Headers["Sec-WebSocket-Protocol"];
var webSocketContext = await context.AcceptWebSocketAsync(subProtocol);
var clientId = Guid.NewGuid().ToString();
var webSocketServer = new WebSocketServer(clientId);
webSocketServer.WebSocket = webSocketContext.WebSocket;
Console.WriteLine($"客户端{clientId}已连接");
await webSocketServer.OnOpenAsync();
while (webSocketServer.WebSocket.State == WebSocketState.Open)
{
var message = string.Empty;
var buffer = new byte[4096];
var result = await webSocketServer.WebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), System.Threading.CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Text)
{
message = Encoding.UTF8.GetString(buffer, 0, result.Count);
}
else if (result.MessageType == WebSocketMessageType.Binary)
{
Console.WriteLine("Binary messages are not supported");
}
await webSocketServer.OnMessageAsync(message);
}
await webSocketServer.OnCloseAsync(null);
}
}
}
}
JavaScript WebSocket客户端
在网页中使用JavaScript的WebSocket API与WebSocket服务端进行通信。下面是一个基于WebSocket的聊天室的示例:
- 创建HTML文件。在HTML文件中添加一个input、一个button和一个div元素,用来输入信息和显示聊天记录。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket Chat Room</title>
</head>
<body>
<div id="logs"></div>
<input type="text" id="input-text">
<button id="btn-send">Send</button>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="chat.js"></script>
</body>
</html>
- 创建JavaScript文件。在JavaScript文件中,先定义一些初始值,如WebSocket服务端地址、WebSocket对象、客户端ID等。然后,绑定button的点击事件,在事件处理程序中,获取输入框的信息,发送到WebSocket服务端,并将信息显示在页面上。代码如下:
$(function () {
var wsUrl = 'ws://localhost:8888/realtime';
var socket;
var clientId;
socket = new WebSocket(wsUrl);
//接收到WebSocket服务端的消息
socket.onmessage = function (evt) {
var message = JSON.parse(evt.data);
switch (message.Type) {
//有人加入聊天室
case "join":
$('#logs').append('<div>' + message.Username + ' joined the chat.</div>');
break;
//有人发消息
case "message":
$('#logs').append('<div>' + message.Username + ': ' + message.Content + '</div>');
break;
//有人离开聊天室
case "leave":
$('#logs').append('<div>' + message.Id + ' left the chat.</div>');
break;
}
$('#logs').scrollTop($('#logs')[0].scrollHeight - $('#logs').height());
};
//WebSocket服务端连接已打开
socket.onopen = function (evt) {
clientId = generateClientId();
var joinMessage = { Type: "join", Username: clientId };
socket.send(JSON.stringify(joinMessage));
};
//WebSocket服务端连接已关闭
socket.onclose = function (evt) {
console.log('WebSocket closed.');
};
//WebSocket服务端连接出错
socket.onerror = function (evt) {
console.log('WebSocket error.');
};
//绑定"Send"按钮点击事件
$('#btn-send').on('click', function () {
var inputText = $('#input-text').val();
$('#input-text').val('');
var message = { Type: "message", Username: clientId, Content: inputText };
socket.send(JSON.stringify(message));
$('#logs').append('<div>Me: ' + inputText + '</div>');
});
//生成客户端ID
function generateClientId() {
var d = new Date().getTime();
if (window.performance && typeof window.performance.now === "function") {
d += performance.now(); //use high-precision timer if available
}
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
return uuid;
}
});
以上就是使用WebSocket实现网页实时通信的完整攻略。除了以上的聊天室示例,还可以使用WebSocket实现更多的实时交互功能,如赛事直播、在线游戏等。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#使用WebSocket与网页实时通信的实现示例 - Python技术站