.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.什么是服务注册中心? 在学习服务注册与发现时,我们要先搞明白到底什么是服务注册与发现. 在这里我举一个生活中非常普遍的例子——网购来简单说明,网购在我们日常生活中已经是非常普遍了,其实网购中的(商 ...
随机推荐
- django实现客户端文件下载
基于django项目,由于不是专门讲文件的下载,这里仅是项目需要,所以可能不是特别的详细.仅做流程的演示: 实现过程: 1.准备下载url # 下载文件 url(r'^download_file/$' ...
- Java生鲜电商平台-订单配送模块的架构与设计
Java生鲜电商平台-订单配送模块的架构与设计 生鲜电商系统最终的目的还是用户下单支付购买, 所以订单管理系统是电商系统中最为复杂的系统,其作为中枢决定着整个商城的运转, 本文将对于生鲜类电商平台的订 ...
- CSS animation 属性
定义和用法 animation属性是下列属性的一个缩写属性: animation-name animation-duration animation-timing-function animation ...
- 装上这 10 个插件,你就是这条 Gai 最靓的仔!
直奔主题,给大家推荐 10 个好用的插件. 1.「Adblock Plus」 世界排名第一的免费广告拦截程序 相信大家都有这样的体验,进某个论坛.新闻或者购物网站,广告满天飞,关掉之后还时不时弹出 ...
- react-native聊天室|RN版聊天App仿微信实例|RN仿微信界面
一.前言 9月,又到开学的季节.为每个一直默默努力的自己点赞!最近都沉浸在react native原生app开发中,之前也有使用vue/react/angular等技术开发过聊天室项目,另外还使用RN ...
- JavaScript 数学
JavaScript Math 数学 神奇的圆周率 Math.PI ; // 返回 3.1415926535-- Math 数学方法 Math.round() Math.round(X):返回 X 的 ...
- CarTool 使用,获取图片资源
程序:gitHub: 项目地址 使用方法: 1.拿到资源包 在itunes里找到喜欢的应用,然后下载,直接将app拖到桌面.得到一个一个ipa资源包,如图 2.将资源包改成zip格式 3.解压zip资 ...
- IOS中的深拷贝和浅拷贝
标签: 什么是深拷贝?什么是浅拷贝? 为什么经常看到字符串属性要这样定义,那个copy是神马意思? @property(nonatomic,copy)NSString* name; 为什么下面的写法是 ...
- bayaim_hadoop1_2.2.0伪分布式搭建
------------------bayaim_hadoop1_2.2.0伪分布式搭建_2018年11月06日09:21:46--------------------------------- 1. ...
- hi3559v100 sdk中双系统AMP架构的初步了解
hi3559v100是海思推出的camera soc处理器.采用的是双核处理器.一个是a7,运行的linux3.18内核.一个是a17使用的是huaweiliteos操作系统,Hi3559V100 系 ...