.NET Core 学习笔记之 WebSocketsSample
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);
}
}
}
运行截图

谢谢浏览!
.NET Core 学习笔记之 WebSocketsSample的更多相关文章
- .NET CORE学习笔记系列(2)——依赖注入[7]: .NET Core DI框架[服务注册]
原文https://www.cnblogs.com/artech/p/net-core-di-07.html 包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IS ...
- .NET CORE学习笔记系列(2)——依赖注入[6]: .NET Core DI框架[编程体验]
原文https://www.cnblogs.com/artech/p/net-core-di-06.html 毫不夸张地说,整个ASP.NET Core框架是建立在一个依赖注入框架之上的,它在应用启动 ...
- .NET CORE学习笔记系列(2)——依赖注入[5]: 创建一个简易版的DI框架[下篇]
为了让读者朋友们能够对.NET Core DI框架的实现原理具有一个深刻而认识,我们采用与之类似的设计构架了一个名为Cat的DI框架.在上篇中我们介绍了Cat的基本编程模式,接下来我们就来聊聊Cat的 ...
- .NET CORE学习笔记系列(2)——依赖注入[4]: 创建一个简易版的DI框架[上篇]
原文https://www.cnblogs.com/artech/p/net-core-di-04.html 本系列文章旨在剖析.NET Core的依赖注入框架的实现原理,到目前为止我们通过三篇文章从 ...
- .NET CORE学习笔记系列(2)——依赖注入【3】依赖注入模式
原文:https://www.cnblogs.com/artech/p/net-core-di-03.html IoC主要体现了这样一种设计思想:通过将一组通用流程的控制权从应用转移到框架中以实现对流 ...
- .NET CORE学习笔记系列(2)——依赖注入【2】基于IoC的设计模式
原文:https://www.cnblogs.com/artech/p/net-core-di-02.html 正如我们在<控制反转>提到过的,很多人将IoC理解为一种“面向对象的设计模式 ...
- .NET CORE学习笔记系列(2)——依赖注入【1】控制反转IOC
原文:https://www.cnblogs.com/artech/p/net-core-di-01.html 一.流程控制的反转 IoC的全名Inverse of Control,翻译成中文就是“控 ...
- .NET Core学习笔记(7)——Exception最佳实践
1.为什么不要给每个方法都写try catch 为每个方法都编写try catch是错误的做法,理由如下: a.重复嵌套的try catch是无用的,多余的. 这一点非常容易理解,下面的示例代码中,O ...
- .net core学习笔记,组件篇:服务的注册与发现(Consul)初篇
1.什么是服务注册中心? 在学习服务注册与发现时,我们要先搞明白到底什么是服务注册与发现. 在这里我举一个生活中非常普遍的例子——网购来简单说明,网购在我们日常生活中已经是非常普遍了,其实网购中的(商 ...
随机推荐
- PLC与外接按钮开关接线方法图解
一个电机控制电路如图1所示,电路中使用常开按钮启动电机,用常闭按钮停止电机运行,图1中KM是控制电机电源的继电器.这样的电路若是使用PLC时的外接线图如图2所示.同时为使PLC运行,在PLC中输入由图 ...
- DevExpress的下拉框控件ComboxBoxEdit怎样绑定键值对选项
场景 DevExpress的下拉框控件ComboBoxEdit控件的使用: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1028 ...
- 你不知道的JS第一卷
这两天,开始看你不知道的JavaScript,第一卷.
- [b0038] python 归纳 (二三)_多进程数据共享和同步_队列Queue
1 队列读写 # -*- coding: utf-8 -*- """ 多进程 共享 队列 multiprocessing.Process 逻辑: 一个进程往队列写数据, ...
- 利用python去实现数学基本值的计算
def get_nums(): nums = []#获取列表 num = input('请输入数字:').strip() while num != '': nums.append(num)#添加数字 ...
- Python—网络抓包与解包(pcap、dpkt)
pcap安装 [root@localhost ~]# pip install pypcap 抓包与解包 # -*- coding:utf-8 -*- import pcap, dpkt import ...
- itest(爱测试) 3.5.0 发布,开源BUG 跟踪管理& 敏捷测试管理软件
v3.5.0 下载地址 :itest下载 itest 简介:查看简介 V3.5.0 增加了 9个功能增强,和17个BUG修复 ,详情如下所述. 9个功能增强 : (1)增加xmind(思维导图) 转E ...
- 解决vue/cli3.0 语法验证规则 ESLint: Expected indentation of 2 spaces but found 4. (indent)
当你使用vue/cli3.0的时,有可能出现雁阵规则 ESLint: Expected indentation of 2 spaces but found 4. (indent) 解决方法 1.在vu ...
- ES3、ES5、ES6对象代理的写法差异
ES3的对象代理写法: console.log('定义私有变量ES3写法:') // ES3 var Person = function (){ var data = { name:'ES3', ag ...
- 2016年蓝桥杯B组C/C++决赛题目
2016年第七届蓝桥杯B组C/C++决赛题目 点击查看2016年第七届蓝桥杯B组C/C++决赛题解 1.一步之遥 从昏迷中醒来,小明发现自己被关在X星球的废矿车里. 矿车停在平直的废弃的轨道上. 他的 ...