.NET Core 学习笔记之 WebSocketsSample
阅读原文时间:2023年07月11日阅读:1

1. 服务端

Program:

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace WebSocketsServer
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}

    public static IWebHost BuildWebHost(string\[\] args) =>  
        WebHost.CreateDefaultBuilder(args)  
            .UseStartup<Startup>()  
            .Build();  
}  

}

Startup:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace WebSocketsServer
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.  
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)  
    {  
        if (env.IsDevelopment())  
        {  
            app.UseDeveloperExceptionPage();  
        }

        // configure keep alive interval, receive buffer size  
        app.UseWebSockets();

        app.Map("/samplesockets", app2 =>  
        {  
            // middleware to handle websocket request  
            app2.Use(async (context, next) =>  
            {  
                if (context.WebSockets.IsWebSocketRequest)  
                {  
                    var webSocket = await context.WebSockets.AcceptWebSocketAsync();  
                    await SendMessagesAsync(context, webSocket, loggerFactory.CreateLogger("SendMessages"));  
                }  
                else  
                {  
                    await next();  
                }  
            });  
        });

        app.Run(async (context) =>  
        {  
            await context.Response.WriteAsync("Web Sockets sample");  
        });  
    }

    private async Task SendMessagesAsync(HttpContext context, WebSocket webSocket, ILogger logger)  
    {  
        var buffer = new byte\[\];  
        WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);  
        while (!result.CloseStatus.HasValue)  
        {  
            if (result.MessageType == WebSocketMessageType.Text)  
            {  
                string content = Encoding.UTF8.GetString(buffer, , result.Count);  
                if (content.StartsWith("REQUESTMESSAGES:"))  
                {  
                    string message = content.Substring("REQUESTMESSAGES:".Length);  
                    for (int i = ; i < ; i++)  
                    {  
                        string messageToSend = $"{message} - {i}";  
                        if (i == )  
                        {  
                            messageToSend += ";EOS"; // send end of sequence to not let the client wait for another message  
                        }  
                        byte\[\] sendBuffer = Encoding.UTF8.GetBytes(messageToSend);  
                        await webSocket.SendAsync(new ArraySegment<byte>(sendBuffer), WebSocketMessageType.Text, endOfMessage: true, CancellationToken.None);  
                        logger.LogDebug("sent message {0}", messageToSend);  
                        await Task.Delay();  
                    }  
                }

                if (content.Equals("SERVERCLOSE"))  
                {  
                    await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Bye for now", CancellationToken.None);  
                    logger.LogDebug("client sent close request, socket closing");  
                    return;  
                }  
                else if (content.Equals("SERVERABORT"))  
                {  
                    context.Abort();  
                }  
            }

            result = await webSocket.ReceiveAsync(buffer, CancellationToken.None);  
        }  
    }  
}  

}

launchSettings.json

{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:58167/",
"sslPort":
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"WebSocketsServer": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:58168/"
}
}
}

2. 客户端

Program.cs

代码如下:

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

namespace WebSocketClient
{
class Program
{
static async Task Main()
{
Console.WriteLine("Client - wait for server");
Console.ReadLine();
await InitiateWebSocketCommunication("ws://localhost:58167/samplesockets");
//"ws://localhost:6295/samplesockets"
//http://localhost:58167/
Console.WriteLine("Program end");
Console.ReadLine();
}

    static async Task InitiateWebSocketCommunication(string address)  
    {  
        try  
        {  
            var webSocket = new ClientWebSocket();  
            await webSocket.ConnectAsync(new Uri(address), CancellationToken.None);

            await SendAndReceiveAsync(webSocket, "A");  
            await SendAndReceiveAsync(webSocket, "B");  
            await webSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes("SERVERCLOSE")),  
                WebSocketMessageType.Text,  
                endOfMessage: true,  
                CancellationToken.None);  
            var buffer = new byte\[\];  
            var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer),  
                CancellationToken.None);

            Console.WriteLine($"received for close: " +  
                $"{result.CloseStatus} " +  
                $"{result.CloseStatusDescription} " +  
                $"{Encoding.UTF8.GetString(buffer, 0, result.Count)}");  
            await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure,  
                "Bye",  
                CancellationToken.None);

        }  
        catch (Exception ex)  
        {  
            Console.WriteLine(ex.Message);  
        }  
    }

    static async Task SendAndReceiveAsync(WebSocket webSocket, string term)  
    {  
        byte\[\] data = Encoding.UTF8.GetBytes($"REQUESTMESSAGES:{term}");  
        var buffer = new byte\[\];

        await webSocket.SendAsync(new ArraySegment<byte>(data),  
            WebSocketMessageType.Text,  
            endOfMessage: true,  
            CancellationToken.None);  
        WebSocketReceiveResult result;  
        bool sequenceEnd = false;  
        do  
        {  
            result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer),  
                CancellationToken.None);  
            string dataReceived = Encoding.UTF8.GetString(buffer, , result.Count);  
            Console.WriteLine($"received {dataReceived}");  
            if (dataReceived.Contains("EOS"))  
            {  
                sequenceEnd = true;  
            }

        } while (!(result?.CloseStatus.HasValue ?? false) && !sequenceEnd);  
    }  
}  

}

运行截图

谢谢浏览!