Closed dameng324 closed 3 years ago
增加了GzipHostConfigurator和GzipSecureHostConfigurator 来对不加密压缩和加密压缩两种方式进行单元测试。 单元测试已通过。
经过调查,这个问题在.net6中已经修复了。https://github.com/dotnet/runtime/issues/57893
代码看起来不错,不过我有两个关注: 1) Gzip 这个需不需要把它作为SuperSocket的核心功能,比如SuperSocket.WebSocket有自己的压缩算法,这一块和你加的Gzip有点重复。扩展开来思考,具体协议可能会有自己的压缩算法,可能不采用传输层压缩,而是应用层消息压缩。可不可以加一个SuperSocket.Gzip的project,把你加的Gzip相关的代码放到里面去。是否这样会更好? 2) 我不确定 netcore/net5+ 里面的 NetworkStream 的性能是否和async socket相差不大,啃个需要加余个benchmark验证一下。
明白你的顾虑,是否可以这样设计:
我做了一个benchmark来验证 tcpchannel和streamTcpchannel的性能对比, repo:https://github.com/BigDream324/SuperSocket/tree/channelBenchMark 结果如下:
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19043.1165 (21H1/May2021Update)
AMD Ryzen 7 5800X, 1 CPU, 16 logical and 8 physical cores
.NET SDK=6.0.100-preview.7.21379.14
[Host] : .NET 5.0.9 (5.0.921.35908), X64 RyuJIT
DefaultJob : .NET 5.0.9 (5.0.921.35908), X64 RyuJIT
Method | PackageCount | Mean | Error | StdDev |
---|---|---|---|---|
TcpPipeChannelTest | 100 | 7.734 ms | 0.5062 ms | 1.493 ms |
StreamPipeChannelTest | 100 | 7.646 ms | 0.4571 ms | 1.348 ms |
TcpPipeChannelTest | 100000 | 399.321 ms | 9.3090 ms | 27.007 ms |
StreamPipeChannelTest | 100000 | 401.558 ms | 9.6951 ms | 28.281 ms |
What about memory usage, gc and cpu usage?
SuperSocket.Channel 不知道压缩这东西的存在, 只在引用了SuperSocket.Gzip并使用了其中的类库的时候才加载相关的逻辑,是否这样更合适?
在Gzip项目中提供 GzipChannelCreatorFactory 的实现,来实现Gzip相应的功能,是这样理解对吧?
使用benchmarkDotNet测试CPU使用率时跑不出结果,原因未明。 其他memory和GC在这里
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19043.1165 (21H1/May2021Update)
AMD Ryzen 7 5800X, 1 CPU, 16 logical and 8 physical cores
.NET SDK=6.0.100-preview.7.21379.14
[Host] : .NET 5.0.9 (5.0.921.35908), X64 RyuJIT
DefaultJob : .NET 5.0.9 (5.0.921.35908), X64 RyuJIT
Method | PackageCount | Mean | Error | StdDev | Gen 0 | Gen 1 | Allocated |
---|---|---|---|---|---|---|---|
TcpPipeChannelTest | 100 | 7.639 ms | 0.5838 ms | 1.721 ms | 39.0625 | 39.0625 | 664 KB |
StreamPipeChannelTest | 100 | 7.512 ms | 0.3743 ms | 1.103 ms | 39.0625 | - | 659 KB |
TcpPipeChannelTest | 100000 | 393.736 ms | 9.9431 ms | 28.847 ms | 6000.0000 | 1000.0000 | 104,571 KB |
StreamPipeChannelTest | 100000 | 382.756 ms | 9.3283 ms | 27.505 ms | 6000.0000 | 1000.0000 | 105,408 KB |
从NetworkStream的源码可以看到,Read和Write也是调用的Socket的Read和Write方法,理论上性能差别不会很大。https://source.dot.net/#System.Net.Sockets/System/Net/Sockets/NetworkStream.cs
等我重新梳理下这块代码再重新提PR,TcpPipeChannel和StreamPipeChannel的问题你这边可以考虑,Gzip这块不再涉及对这块的修改。
通过使用GZipStream封装了一层GzipReadWriteStream来使链路压缩。
原理与SslStream的处理类似 接收: networkStream=>sslStream=>GzipStream解压 发送:GzipStream压缩=>sslStream=>networkStream
唯一一点不够完美的是 GzipStream使用Read读取内容时,会出现有数据了但仍不返回的现象。使用ReadAsync等异步方法接受时OK的,所以GzipReadWriteStream中将改方法设置为Obsolete。
会导致的结果是某些TestCase中直接使用Stream封装成TextReader来读取,导致读不到东西,使用EasyClient是没有这个问题的。