优化适配器纠错能力

优化TcpService接口继承
优化DmtpService接口继承

优化协议文件
This commit is contained in:
若汝棋茗
2023-12-11 20:36:51 +08:00
parent f3bada26d6
commit e53b1f37c1
67 changed files with 598 additions and 390 deletions

View File

@@ -3,7 +3,7 @@
<ApplicationIcon>logo.ico</ApplicationIcon>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>$(MSBuildProjectName).snk</AssemblyOriginatorKeyFile>
<Version>2.0.0-beta.235</Version>
<Version>2.0.0-beta.238</Version>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Company>若汝棋茗</Company>

View File

@@ -47,7 +47,7 @@ namespace TouchSocket.Dmtp.AspNetCore
private WebSocket m_client;
private DmtpActor m_dmtpActor;
private TcpDmtpAdapter m_dmtpAdapter;
private DmtpAdapter m_dmtpAdapter;
private WebSocketDmtpService m_service;
private ValueCounter m_receiveCounter;
private ValueCounter m_sendCounter;
@@ -126,7 +126,7 @@ namespace TouchSocket.Dmtp.AspNetCore
internal void InternalSetConfig(TouchSocketConfig config)
{
this.m_config = config;
this.m_dmtpAdapter = new TcpDmtpAdapter()
this.m_dmtpAdapter = new DmtpAdapter()
{
ReceivedCallBack = this.PrivateHandleReceivedData,
Logger = this.Logger

View File

@@ -33,7 +33,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="actionConfig"></param>
/// <returns></returns>
public static IServiceCollection AddTcpDmtpService<TService, TImpService>(this IServiceCollection services, Action<TouchSocketConfig> actionConfig)
where TService : class, ITcpDmtpService
where TService : class, ITcpDmtpServiceBase
where TImpService : class, TService
{
return services.AddTcpService<TService, TImpService>(actionConfig);
@@ -93,7 +93,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="actionConfig"></param>
/// <returns></returns>
public static IServiceCollection AddHttpService<TService, TImpService>(this IServiceCollection services, Action<TouchSocketConfig> actionConfig)
where TService : class, IHttpService
where TService : class, IHttpServiceBase
where TImpService : class, TService
{
return services.AddTcpService<TService, TImpService>(actionConfig);
@@ -153,7 +153,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="actionConfig"></param>
/// <returns></returns>
public static IServiceCollection AddHttpDmtpService<TService, TImpService>(this IServiceCollection services, Action<TouchSocketConfig> actionConfig)
where TService : class, IHttpDmtpService
where TService : class, IHttpDmtpServiceBase
where TImpService : class, TService
{
return services.AddTcpService<TService, TImpService>(actionConfig);

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -81,11 +81,6 @@ namespace TouchSocket.Core.AspNetCore
{
return true;
}
if (fromType.IsGenericType)
{
fromType = fromType.GetGenericTypeDefinition();
}
foreach (var item in this.m_services)
{
if (item.ServiceType == fromType)

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -83,19 +83,24 @@ namespace TouchSocket.Core
}
else
{
var requestInfo = this.GetInstance();
var indexStart = byteBlock.Buffer.IndexOfFirst(byteBlock.Pos, byteBlock.CanReadLen, this.StartCode);
if (indexStart == -1)
{
return FilterResult.Cache;
}
if (!requestInfo.OnParsingStartCode(byteBlock.ToArray(byteBlock.Pos, this.StartCode.Length)))
var requestInfo = this.GetInstance();
if (requestInfo.OnParsingStartCode(byteBlock.ToArray(byteBlock.Pos, this.StartCode.Length)))
{
byteBlock.Pos += this.StartCode.Length;
}
else
{
byteBlock.Pos += 1;
return FilterResult.GoOn;
}
byteBlock.Pos += this.StartCode.Length;
request = requestInfo;
int len;
@@ -128,7 +133,7 @@ namespace TouchSocket.Core
}
else
{
byteBlock.Pos += this.EndCode.Length;
byteBlock.Pos += 1;
return FilterResult.GoOn;
}
}

View File

@@ -43,25 +43,18 @@ namespace TouchSocket.Core
while (this.m_surLen > 0 && byteBlock.CanRead)
{
var r = (int)Math.Min(this.m_surLen, byteBlock.CanReadLen);
try
var bytes = byteBlock.ToArray(byteBlock.Pos, r);
request.OnAppendBody(bytes);
this.m_surLen -= r;
byteBlock.Pos += r;
if (this.m_surLen == 0)
{
var bytes = byteBlock.ToArray(byteBlock.Pos, r);
request.OnAppendBody(bytes);
this.m_surLen -= r;
byteBlock.Pos += r;
if (this.m_surLen == 0)
if (request.OnFinished())
{
if (request.OnFinished())
{
return FilterResult.Success;
}
request = null;
return FilterResult.GoOn;
return FilterResult.Success;
}
}
catch (Exception ex)
{
this.OnError(ex.Message, false, true);
request = null;
return FilterResult.GoOn;
}
}
return FilterResult.GoOn;
@@ -74,9 +67,10 @@ namespace TouchSocket.Core
}
var requestInfo = this.GetInstance();
byteBlock.Read(out var header, this.HeaderLength);
var header = byteBlock.ToArray(byteBlock.Pos, this.HeaderLength);
if (requestInfo.OnParsingHeader(header))
{
byteBlock.Pos += this.HeaderLength;
request = requestInfo;
if (requestInfo.BodyLength == 0)
{
@@ -92,31 +86,25 @@ namespace TouchSocket.Core
while (this.m_surLen > 0 && byteBlock.CanRead)
{
var r = (int)Math.Min(this.m_surLen, byteBlock.CanReadLen);
try
var bytes = byteBlock.ToArray(byteBlock.Pos, r);
request.OnAppendBody(bytes);
this.m_surLen -= r;
byteBlock.Pos += r;
if (this.m_surLen == 0)
{
var bytes = byteBlock.ToArray(byteBlock.Pos, r);
request.OnAppendBody(bytes);
this.m_surLen -= r;
byteBlock.Pos += r;
if (this.m_surLen == 0)
if (request.OnFinished())
{
if (request.OnFinished())
{
return FilterResult.Success;
}
request = null;
return FilterResult.GoOn;
return FilterResult.Success;
}
}
catch (Exception ex)
{
this.OnError(ex.Message, false, true);
request = null;
return FilterResult.GoOn;
}
}
return FilterResult.GoOn;
}
else
{
byteBlock.Pos += 1;
return FilterResult.GoOn;
}
}

View File

@@ -18,7 +18,6 @@ namespace TouchSocket.Core
/// <summary>
/// 用户自定义数据处理适配器,使用该适配器时,接收方收到的数据中,<see cref="ByteBlock"/>将为null
/// 同时<see cref="IRequestInfo"/>将实现为TRequest发送数据直接发送。
/// <para>此处设计思路借鉴SuperSocket。</para>
/// </summary>
public abstract class CustomDataHandlingAdapter<TRequest> : SingleStreamDataHandlingAdapter where TRequest : class, IRequestInfo
{
@@ -99,7 +98,6 @@ namespace TouchSocket.Core
}
}
/// <summary>
/// <inheritdoc/>
/// </summary>
@@ -111,7 +109,6 @@ namespace TouchSocket.Core
this.GoSend(buffer, offset, length);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
@@ -163,7 +160,7 @@ namespace TouchSocket.Core
if (this.TempByteBlock.Len > this.MaxPackageSize)
{
this.OnError("缓存的数据长度大于设定值的情况下未收到解析信号");
this.OnError(default, "缓存的数据长度大于设定值的情况下未收到解析信号", true, true);
}
}
if (this.UpdateCacheTimeWhenRev)

View File

@@ -44,14 +44,17 @@ namespace TouchSocket.Core
}
var block = new ByteBlock(request.BodyLength);
byteBlock.Read(block, request.BodyLength);
block.Write(byteBlock.Buffer, byteBlock.Pos, request.BodyLength);
block.SeekToStart();
if (request.OnParsingBody(block))
{
byteBlock.Pos += request.BodyLength;
return FilterResult.Success;
}
else
{
request = default;//放弃所有解析
byteBlock.Pos += 1;
return FilterResult.GoOn;
}
}
@@ -63,12 +66,13 @@ namespace TouchSocket.Core
}
var requestInfo = this.GetInstance();
byteBlock.Read(out var header, this.HeaderLength);
var header = byteBlock.ToArray(byteBlock.Pos, this.HeaderLength);
if (requestInfo.OnParsingHeader(header))
{
byteBlock.Pos += this.HeaderLength;
if (requestInfo.BodyLength > this.MaxPackageSize)
{
this.OnError($"接收的BodyLength={requestInfo.BodyLength},大于设定的MaxPackageSize={this.MaxPackageSize}");
this.OnError(default,$"接收的BodyLength={requestInfo.BodyLength},大于设定的MaxPackageSize={this.MaxPackageSize}",true,true);
return FilterResult.GoOn;
}
request = requestInfo;
@@ -79,19 +83,23 @@ namespace TouchSocket.Core
}
var block = new ByteBlock(request.BodyLength);
byteBlock.Read(block, request.BodyLength);
block.Write(byteBlock.Buffer,byteBlock.Pos, request.BodyLength);
block.SeekToStart();
if (requestInfo.OnParsingBody(block))
{
byteBlock.Pos += request.BodyLength;
return FilterResult.Success;
}
else
{
request = default;//放弃所有解析
byteBlock.Pos += 1;
return FilterResult.GoOn;
}
}
else
{
byteBlock.Pos += 1;
return FilterResult.GoOn;
}
}

View File

@@ -43,14 +43,15 @@ namespace TouchSocket.Core
return FilterResult.Cache;
}
byteBlock.Read(out var body, request.BodyLength);
var body = byteBlock.ToArray(byteBlock.Pos, request.BodyLength);
if (request.OnParsingBody(body))
{
byteBlock.Pos += request.BodyLength;
return FilterResult.Success;
}
else
{
request = default;//放弃所有解析
byteBlock.Pos += 1;
return FilterResult.GoOn;
}
}
@@ -62,9 +63,10 @@ namespace TouchSocket.Core
}
var requestInfo = this.GetInstance();
byteBlock.Read(out var header, this.HeaderLength);
var header = byteBlock.ToArray(byteBlock.Pos, this.HeaderLength);
if (requestInfo.OnParsingHeader(header))
{
byteBlock.Pos += this.HeaderLength;
request = requestInfo;
if (request.BodyLength > byteBlock.CanReadLen)//body不满足解析开始缓存然后保存对象
{
@@ -72,19 +74,21 @@ namespace TouchSocket.Core
return FilterResult.Cache;
}
byteBlock.Read(out var body, request.BodyLength);
var body= byteBlock.ToArray(byteBlock.Pos, request.BodyLength);
if (request.OnParsingBody(body))
{
byteBlock.Pos += request.BodyLength;
return FilterResult.Success;
}
else
{
request = default;//放弃所有解析
byteBlock.Pos += 1;
return FilterResult.GoOn;
}
}
else
{
byteBlock.Pos += 1;
return FilterResult.GoOn;
}
}

View File

@@ -12,6 +12,40 @@
namespace TouchSocket.Core
{
/// <summary>
/// 用户自定义不固定包头请求
/// </summary>
public interface IUnfixedHeaderRequestInfo : IRequestInfo
{
/// <summary>
/// 数据体长度
/// </summary>
int BodyLength { get; }
/// <summary>
/// 协议头长度
/// </summary>
int HeaderLength { get; }
/// <summary>
/// 当收到数据,由框架封送有效载荷数据。
/// <para>如果返回false意味着放弃本次解析的所有数据包括已经解析完成的Header</para>
/// </summary>
/// <param name="body">载荷数据</param>
/// <returns>是否成功有效</returns>
bool OnParsingBody(byte[] body);
/// <summary>
/// 当收到数据,由框架封送数据,您需要在此函数中,解析自己的数据包头。
/// <para>如果满足包头的解析请返回True并且递增整个包头的长度到<see cref="ByteBlock.Pos"/>,然后赋值<see cref="BodyLength"/></para>
/// <para>如果返回false意味着缓存剩余数据此时如果仅仅是因为长度不足则不必修改其他。</para>
/// <para>但是如果是因为数据错误,则需要修改<see cref="ByteBlock.Pos"/>到正确位置,如果都不正确,则设置<see cref="ByteBlock.Pos"/>等于<see cref="ByteBlock.Len"/></para>
/// </summary>
/// <param name="byteBlock"></param>
/// <returns>是否满足解析包头</returns>
bool OnParsingHeader(ByteBlock byteBlock);
}
/// <summary>
/// 用户自定义固定包头解析器,使用该适配器时,接收方收到的数据中,<see cref="ByteBlock"/>将为null同时<see cref="IRequestInfo"/>将实现为TUnfixedHeaderRequestInfo。
/// </summary>
@@ -37,14 +71,15 @@ namespace TouchSocket.Core
return FilterResult.Cache;
}
byteBlock.Read(out var body, request.BodyLength);
var body = byteBlock.ToArray(byteBlock.Pos, request.BodyLength);
if (request.OnParsingBody(body))
{
byteBlock.Pos += request.BodyLength;
return FilterResult.Success;
}
else
{
request = default;//放弃所有解析
byteBlock.Pos += 1;
return FilterResult.GoOn;
}
}
@@ -60,14 +95,15 @@ namespace TouchSocket.Core
return FilterResult.Cache;
}
byteBlock.Read(out var body, request.BodyLength);
var body = byteBlock.ToArray(byteBlock.Pos, request.BodyLength);
if (request.OnParsingBody(body))
{
byteBlock.Pos += request.BodyLength;
return FilterResult.Success;
}
else
{
request = default;//放弃所有解析
byteBlock.Pos += 1;
return FilterResult.GoOn;
}
}
@@ -84,38 +120,4 @@ namespace TouchSocket.Core
/// <returns></returns>
protected abstract TUnfixedHeaderRequestInfo GetInstance();
}
/// <summary>
/// 用户自定义不固定包头请求
/// </summary>
public interface IUnfixedHeaderRequestInfo : IRequestInfo
{
/// <summary>
/// 数据体长度
/// </summary>
int BodyLength { get; }
/// <summary>
/// 协议头长度
/// </summary>
int HeaderLength { get; }
/// <summary>
/// 当收到数据,由框架封送数据,您需要在此函数中,解析自己的数据包头。
/// <para>如果满足包头的解析请返回True并且递增整个包头的长度到<see cref="ByteBlock.Pos"/>,然后赋值<see cref="BodyLength"/></para>
/// <para>如果返回false意味着缓存剩余数据此时如果仅仅是因为长度不足则不必修改其他。</para>
/// <para>但是如果是因为数据错误,则需要修改<see cref="ByteBlock.Pos"/>到正确位置,如果都不正确,则设置<see cref="ByteBlock.Pos"/>等于<see cref="ByteBlock.Len"/></para>
/// </summary>
/// <param name="byteBlock"></param>
/// <returns>是否满足解析包头</returns>
bool OnParsingHeader(ByteBlock byteBlock);
/// <summary>
/// 当收到数据,由框架封送有效载荷数据。
/// <para>如果返回false意味着放弃本次解析的所有数据包括已经解析完成的Header</para>
/// </summary>
/// <param name="body">载荷数据</param>
/// <returns>是否成功有效</returns>
bool OnParsingBody(byte[] body);
}
}

View File

@@ -61,10 +61,11 @@ namespace TouchSocket.Core
/// <summary>
/// 在解析时发生错误。
/// </summary>
/// <param name="ex">异常</param>
/// <param name="error">错误异常</param>
/// <param name="reset">是否调用<see cref="Reset"/></param>
/// <param name="log">是否记录日志</param>
protected virtual void OnError(string error, bool reset = true, bool log = true)
protected virtual void OnError(Exception ex,string error, bool reset, bool log)
{
if (reset)
{
@@ -77,7 +78,7 @@ namespace TouchSocket.Core
}
/// <summary>
/// 重置解析器到初始状态,一般在<see cref="OnError(string, bool, bool)"/>被触发时,由返回值指示是否调用。
/// 重置解析器到初始状态,一般在<see cref="OnError(Exception,string, bool, bool)"/>被触发时,由返回值指示是否调用。
/// </summary>
protected abstract void Reset();
}

View File

@@ -78,7 +78,7 @@ namespace TouchSocket.Core
}
catch (Exception ex)
{
this.OnError(ex.Message);
this.OnError(ex,ex.Message, true, true);
}
}
@@ -272,7 +272,7 @@ namespace TouchSocket.Core
protected abstract void PreviewReceived(ByteBlock byteBlock);
/// <summary>
/// 重置解析器到初始状态,一般在<see cref="DataHandlingAdapter.OnError(string, bool, bool)"/>被触发时,由返回值指示是否调用。
/// 重置解析器到初始状态,一般在<see cref="DataHandlingAdapter.OnError(Exception,string, bool, bool)"/>被触发时,由返回值指示是否调用。
/// </summary>
protected override void Reset()
{

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1083,9 +1083,10 @@ namespace TouchSocket.Dmtp
{
var transferBytes = new ArraySegment<byte>[]
{
new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(protocol)),
new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(length)),
new ArraySegment<byte>(buffer,offset,length)
new ArraySegment<byte>(DmtpMessage.Head),
new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(protocol)),
new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(length)),
new ArraySegment<byte>(buffer,offset,length)
};
this.OutputSend.Invoke(this, transferBytes);
this.LastActiveTime = DateTime.Now;
@@ -1106,9 +1107,10 @@ namespace TouchSocket.Dmtp
{
var transferBytes = new ArraySegment<byte>[]
{
new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(protocol)),
new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(length)),
new ArraySegment<byte>(buffer,offset,length)
new ArraySegment<byte>(DmtpMessage.Head),
new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(protocol)),
new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(length)),
new ArraySegment<byte>(buffer,offset,length)
};
this.LastActiveTime = DateTime.Now;
return this.OutputSendAsync.Invoke(this, transferBytes);

View File

@@ -19,9 +19,9 @@ using TouchSocket.Core;
namespace TouchSocket.Dmtp
{
/// <summary>
/// TcpDmtpAdapter
/// DmtpAdapter
/// </summary>
public class TcpDmtpAdapter : CustomFixedHeaderByteBlockDataHandlingAdapter<DmtpMessage>
public class DmtpAdapter : CustomFixedHeaderByteBlockDataHandlingAdapter<DmtpMessage>
{
private readonly SemaphoreSlim m_locker = new SemaphoreSlim(1, 1);
@@ -32,7 +32,7 @@ namespace TouchSocket.Dmtp
public override bool CanSplicingSend => true;
/// <inheritdoc/>
public override int HeaderLength => 6;
public override int HeaderLength => 8;
/// <summary>
/// 最大拼接
@@ -62,7 +62,7 @@ namespace TouchSocket.Dmtp
{
throw new Exception("发送的BodyLength={requestInfo.BodyLength},大于设定的MaxPackageSize={this.MaxPackageSize}");
}
using (var byteBlock = new ByteBlock(message.GetLength()))
using (var byteBlock = new ByteBlock(message.MaxLength))
{
message.Build(byteBlock);
await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len);
@@ -80,7 +80,7 @@ namespace TouchSocket.Dmtp
{
throw new Exception("发送的BodyLength={requestInfo.BodyLength},大于设定的MaxPackageSize={this.MaxPackageSize}");
}
using (var byteBlock = new ByteBlock(message.GetLength()))
using (var byteBlock = new ByteBlock(message.MaxLength))
{
message.Build(byteBlock);
this.GoSend(byteBlock.Buffer, 0, byteBlock.Len);
@@ -105,7 +105,7 @@ namespace TouchSocket.Dmtp
{
throw new Exception("发送数据大于设定值,相同解析器可能无法收到有效数据,已终止发送");
}
if (length > this.MaxPackageSize)
if (length > MaxSplicing)
{
try
{
@@ -152,7 +152,7 @@ namespace TouchSocket.Dmtp
throw new Exception("发送数据大于设定值,相同解析器可能无法收到有效数据,已终止发送");
}
if (length > this.MaxPackageSize)
if (length > MaxSplicing)
{
try
{

View File

@@ -22,20 +22,25 @@ namespace TouchSocket.Dmtp
/// <para>|ProtocolFlags|Length|Data|</para>
/// <para>|ushort|int32|bytes|</para>
/// </summary>
public class DmtpMessage : DisposableObject, IFixedHeaderByteBlockRequestInfo
public class DmtpMessage : DisposableObject, IFixedHeaderByteBlockRequestInfo, IRequestInfoBuilder
{
private int m_bodyLength;
/// <summary>
/// Dmtp协议的消息。
/// <para>|*2*|**4**|***************n***********|</para>
/// <para>|ProtocolFlags|Length|Data|</para>
/// <para>|ushort|int32|bytes|</para>
/// <para>|*2*|*2*|**4**|***************n***********|</para>
/// <para>|Head|ProtocolFlags|Length|Data|</para>
/// <para>|dm|ushort|int32|bytes|</para>
/// </summary>
public DmtpMessage()
{
}
/// <summary>
/// Head
/// </summary>
public static readonly byte[] Head = new byte[] { 100, 109 };
/// <summary>
/// Dmtp协议的消息。
/// <para>|*2*|**4**|***************n***********|</para>
@@ -60,12 +65,16 @@ namespace TouchSocket.Dmtp
/// </summary>
public ushort ProtocolFlags { get; set; }
/// <inheritdoc/>
public int MaxLength => this.BodyByteBlock == null ? 6 : this.BodyByteBlock.Len + 6;
/// <summary>
/// 构建数据到<see cref="ByteBlock"/>
/// </summary>
/// <param name="byteBlock"></param>
public void Build(ByteBlock byteBlock)
{
byteBlock.Write(Head);
byteBlock.Write(TouchSocketBitConverter.BigEndian.GetBytes(this.ProtocolFlags));
if (this.BodyByteBlock == null)
{
@@ -78,19 +87,6 @@ namespace TouchSocket.Dmtp
}
}
/// <summary>
/// 构建数据到<see langword="byte[]" />
/// </summary>
/// <returns></returns>
public byte[] BuildAsBytes()
{
using (var byteBlock = new ByteBlock(this.GetLength()))
{
this.Build(byteBlock);
return byteBlock.ToArray();
}
}
/// <summary>
/// 从当前内存中解析出一个<see cref="DmtpMessage"/>
/// <para>注意:
@@ -106,7 +102,10 @@ namespace TouchSocket.Dmtp
{
var buffer = bytes.Array;
var offset = bytes.Offset;
if (bytes.Array[offset++] != Head[0]|| bytes.Array[offset++] != Head[1])
{
throw new Exception("这可能不是Dmtp协议数据");
}
var protocolFlags = TouchSocketBitConverter.BigEndian.ToUInt16(buffer, offset);
var bodyLength = TouchSocketBitConverter.BigEndian.ToInt32(buffer, 2 + offset);
var byteBlock = new ByteBlock(bodyLength);
@@ -134,10 +133,17 @@ namespace TouchSocket.Dmtp
public static DmtpMessage CreateFrom(ByteBlock block)
{
var buffer = block.Buffer;
var protocolFlags = TouchSocketBitConverter.BigEndian.ToUInt16(buffer, 0);
var bodyLength = TouchSocketBitConverter.BigEndian.ToInt32(buffer, 2);
var offset = 0;
if (buffer[offset++] != Head[0] || buffer[offset++] != Head[1])
{
throw new Exception("这可能不是Dmtp协议数据");
}
var protocolFlags = TouchSocketBitConverter.BigEndian.ToUInt16(buffer, offset);
offset += 2;
var bodyLength = TouchSocketBitConverter.BigEndian.ToInt32(buffer, offset);
offset += 4;
var byteBlock = new ByteBlock(bodyLength);
byteBlock.Write(buffer, 6, bodyLength);
byteBlock.Write(buffer, offset, bodyLength);
byteBlock.SeekToStart();
return new DmtpMessage()
{
@@ -163,15 +169,6 @@ namespace TouchSocket.Dmtp
}
}
/// <summary>
/// 获取整个<see cref="DmtpMessage"/>的数据长度。
/// </summary>
/// <returns></returns>
public int GetLength()
{
return this.BodyByteBlock == null ? 6 : this.BodyByteBlock.Len + 6;
}
bool IFixedHeaderByteBlockRequestInfo.OnParsingBody(ByteBlock byteBlock)
{
if (byteBlock.Len == this.m_bodyLength)
@@ -185,10 +182,16 @@ namespace TouchSocket.Dmtp
bool IFixedHeaderByteBlockRequestInfo.OnParsingHeader(byte[] header)
{
if (header.Length == 6)
if (header.Length == 8)
{
this.ProtocolFlags = TouchSocketBitConverter.BigEndian.ToUInt16(header, 0);
this.m_bodyLength = TouchSocketBitConverter.BigEndian.ToInt32(header, 2);
var offset = 0;
if (header[offset++] != Head[0] || header[offset++] != Head[1])
{
throw new Exception("这可能不是Dmtp协议数据");
}
this.ProtocolFlags = TouchSocketBitConverter.BigEndian.ToUInt16(header, offset);
offset += 2;
this.m_bodyLength = TouchSocketBitConverter.BigEndian.ToInt32(header, offset);
return true;
}
return false;

View File

@@ -219,7 +219,7 @@ namespace TouchSocket.Dmtp
private void SwitchProtocolToDmtp()
{
this.Protocol = DmtpUtility.DmtpProtocol;
this.SetDataHandlingAdapter(new TcpDmtpAdapter());
this.SetDataHandlingAdapter(new DmtpAdapter());
this.m_dmtpActor = new SealedDmtpActor(this.m_allowRoute)
{
OutputSend = this.DmtpActorSend,

View File

@@ -21,7 +21,7 @@ namespace TouchSocket.Dmtp
/// <summary>
/// HttpDmtpService
/// </summary>
public class HttpDmtpService : HttpDmtpService<HttpDmtpSocketClient>
public class HttpDmtpService : HttpDmtpService<HttpDmtpSocketClient>, IHttpDmtpService
{
}
@@ -29,7 +29,7 @@ namespace TouchSocket.Dmtp
/// HttpDmtpService泛型类型
/// </summary>
/// <typeparam name="TClient"></typeparam>
public partial class HttpDmtpService<TClient> : HttpService<TClient>, IHttpDmtpService where TClient : HttpDmtpSocketClient, new()
public partial class HttpDmtpService<TClient> : HttpService<TClient>, IHttpDmtpService<TClient> where TClient : HttpDmtpSocketClient, new()
{
/// <summary>
/// 连接令箭

View File

@@ -157,7 +157,7 @@ namespace TouchSocket.Dmtp
this.m_dmtpActor = actor;
this.Protocol = DmtpUtility.DmtpProtocol;
this.SetDataHandlingAdapter(new TcpDmtpAdapter());
this.SetDataHandlingAdapter(new DmtpAdapter());
}
private void ThisDmtpActorOutputSend(DmtpActor actor, ArraySegment<byte>[] transferBytes)

View File

@@ -1,15 +1,8 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Http;
namespace TouchSocket.Dmtp
@@ -17,7 +10,15 @@ namespace TouchSocket.Dmtp
/// <summary>
/// IHttpDmtpService
/// </summary>
public interface IHttpDmtpService : IHttpService, IDmtpService
public interface IHttpDmtpService<TClient> : IHttpDmtpServiceBase, IHttpService<TClient> where TClient : IHttpDmtpSocketClient
{
}
}
/// <summary>
/// IHttpDmtpService
/// </summary>
public interface IHttpDmtpService : IHttpDmtpService<HttpDmtpSocketClient>
{
}
}

View File

@@ -0,0 +1,23 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
using TouchSocket.Http;
namespace TouchSocket.Dmtp
{
/// <summary>
/// IHttpDmtpServiceBase
/// </summary>
public interface IHttpDmtpServiceBase : IHttpServiceBase, IDmtpService
{
}
}

View File

@@ -11,13 +11,14 @@
//------------------------------------------------------------------------------
using TouchSocket.Sockets;
using TouchSocket.Http;
namespace TouchSocket.Dmtp
{
/// <summary>
/// IHttpDmtpSocketClient
/// </summary>
public interface IHttpDmtpSocketClient : IHttpDmtpClientBase, ISocketClient
public interface IHttpDmtpSocketClient : IHttpSocketClient, IHttpDmtpClientBase
{
}
}

View File

@@ -1,15 +1,8 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Sockets;
namespace TouchSocket.Dmtp
@@ -17,7 +10,16 @@ namespace TouchSocket.Dmtp
/// <summary>
/// ITcpDmtpService
/// </summary>
public interface ITcpDmtpService : ITcpService, IDmtpService
/// <typeparam name="TClient"></typeparam>
public interface ITcpDmtpService<TClient>: ITcpDmtpServiceBase,ITcpService<TClient> where TClient : ITcpDmtpSocketClient
{
}
}
/// <summary>
/// ITcpDmtpService
/// </summary>
public interface ITcpDmtpService: ITcpDmtpService<TcpDmtpSocketClient>
{
}
}

View File

@@ -0,0 +1,23 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
using TouchSocket.Sockets;
namespace TouchSocket.Dmtp
{
/// <summary>
/// ITcpDmtpServiceBase
/// </summary>
public interface ITcpDmtpServiceBase : ITcpServiceBase, IDmtpService
{
}
}

View File

@@ -209,7 +209,7 @@ namespace TouchSocket.Dmtp
/// <inheritdoc/>
protected override void LoadConfig(TouchSocketConfig config)
{
config.SetTcpDataHandlingAdapter(() => new TcpDmtpAdapter());
config.SetTcpDataHandlingAdapter(() => new DmtpAdapter());
base.LoadConfig(config);
if (this.Resolver.IsRegistered(typeof(IDmtpRouteService)))
{

View File

@@ -20,7 +20,7 @@ namespace TouchSocket.Dmtp
/// <summary>
/// TcpDmtpService
/// </summary>
public class TcpDmtpService : TcpDmtpService<TcpDmtpSocketClient>
public class TcpDmtpService : TcpDmtpService<TcpDmtpSocketClient>, ITcpDmtpService
{
}
@@ -28,7 +28,7 @@ namespace TouchSocket.Dmtp
/// TcpDmtpService泛型类型
/// </summary>
/// <typeparam name="TClient"></typeparam>
public partial class TcpDmtpService<TClient> : TcpService<TClient>, ITcpDmtpService where TClient : TcpDmtpSocketClient, new()
public class TcpDmtpService<TClient> : TcpService<TClient>, ITcpDmtpService<TClient> where TClient : TcpDmtpSocketClient, new()
{
#region
@@ -45,7 +45,7 @@ namespace TouchSocket.Dmtp
/// <inheritdoc/>
protected override void LoadConfig(TouchSocketConfig config)
{
config.SetTcpDataHandlingAdapter(() => new TcpDmtpAdapter());
config.SetTcpDataHandlingAdapter(() => new DmtpAdapter());
base.LoadConfig(config);
if (this.Resolver.IsRegistered(typeof(IDmtpRouteService)))

View File

@@ -52,7 +52,7 @@ namespace TouchSocket.Dmtp
private ValueCounter m_receiveCounter;
private int m_sendBufferSize = 1024 * 10;
private ValueCounter m_sendCounter;
private TcpDmtpAdapter m_dmtpAdapter;
private DmtpAdapter m_dmtpAdapter;
#endregion
@@ -134,7 +134,7 @@ namespace TouchSocket.Dmtp
CreatedChannel = this.OnDmtpActorCreateChannel
}; ;
this.m_dmtpAdapter = new TcpDmtpAdapter()
this.m_dmtpAdapter = new DmtpAdapter()
{
ReceivedCallBack = this.PrivateHandleReceivedData
};

View File

@@ -145,18 +145,18 @@ namespace TouchSocket.Dmtp
}
/// <summary>
/// 构建<see cref="ITcpDmtpService"/>类服务器,并启动。
/// 构建<see cref="ITcpDmtpServiceBase"/>类服务器,并启动。
/// </summary>
/// <typeparam name="TService"></typeparam>
/// <param name="config"></param>
/// <returns></returns>
public static TService BuildWithTcpDmtpService<TService>(this TouchSocketConfig config) where TService : ITcpDmtpService, new()
public static TService BuildWithTcpDmtpService<TService>(this TouchSocketConfig config) where TService : ITcpDmtpServiceBase, new()
{
return config.BuildService<TService>();
}
/// <summary>
/// 构建<see cref="ITcpDmtpService"/>类服务器,并启动。
/// 构建<see cref="ITcpDmtpServiceBase"/>类服务器,并启动。
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
@@ -191,18 +191,18 @@ namespace TouchSocket.Dmtp
}
/// <summary>
/// 构建<see cref="IHttpDmtpService"/>类服务器,并启动。
/// 构建<see cref="IHttpDmtpServiceBase"/>类服务器,并启动。
/// </summary>
/// <typeparam name="TService"></typeparam>
/// <param name="config"></param>
/// <returns></returns>
public static TService BuildWithHttpDmtpService<TService>(this TouchSocketConfig config) where TService : IHttpDmtpService, new()
public static TService BuildWithHttpDmtpService<TService>(this TouchSocketConfig config) where TService : IHttpDmtpServiceBase, new()
{
return config.BuildService<TService>();
}
/// <summary>
/// 构建<see cref="IHttpDmtpService"/>类服务器,并启动。
/// 构建<see cref="IHttpDmtpServiceBase"/>类服务器,并启动。
/// </summary>
/// <param name="config"></param>
/// <returns></returns>

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -107,7 +107,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="actionConfig"></param>
/// <returns></returns>
public static IServiceCollection AddTcpService<TService, TImpService>(this IServiceCollection services, Action<TouchSocketConfig> actionConfig)
where TService : class, ITcpService
where TService : class, ITcpServiceBase
where TImpService : class, TService
{
return AddServiceHostedService<TService, TImpService>(services, actionConfig);

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -17,14 +17,14 @@ namespace TouchSocket.Http
/// <summary>
/// HTTP/HTTPS服务器
/// </summary>
public class HttpService<TClient> : TcpService<TClient>, IHttpService where TClient : HttpSocketClient, new()
public class HttpService<TClient> : TcpService<TClient>, IHttpService<TClient> where TClient : HttpSocketClient, new()
{
}
/// <summary>
/// HTTP/HTTPS服务器
/// </summary>
public class HttpService : HttpService<HttpSocketClient>
public class HttpService : HttpService<HttpSocketClient>, IHttpService
{
}
}

View File

@@ -1,23 +1,24 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Sockets;
namespace TouchSocket.Http
{
/// <summary>
/// HttpService接口
/// IHttpService
/// </summary>
public interface IHttpService : ITcpService
public interface IHttpService<TClient> : IHttpServiceBase, ITcpService<TClient> where TClient : IHttpSocketClient
{
}
}
/// <summary>
/// IHttpService
/// </summary>
public interface IHttpService : IHttpService<HttpSocketClient>
{
}
}

View File

@@ -0,0 +1,23 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
using TouchSocket.Sockets;
namespace TouchSocket.Http
{
/// <summary>
/// IHttpServiceBase
/// </summary>
public interface IHttpServiceBase : ITcpServiceBase
{
}
}

View File

@@ -53,7 +53,7 @@ namespace TouchSocket.Sockets
/// <typeparam name="TService"></typeparam>
/// <param name="config"></param>
/// <returns></returns>
public static TService BuildWithHttpService<TService>(this TouchSocketConfig config) where TService : IHttpService
public static TService BuildWithHttpService<TService>(this TouchSocketConfig config) where TService : IHttpServiceBase
{
var service = Activator.CreateInstance<TService>();
service.Setup(config);

View File

@@ -70,7 +70,7 @@ namespace TouchSocket.Http
this.tempByteBlock.Write(byteBlock.Buffer, byteBlock.Pos, byteBlock.CanReadLen);
if (this.tempByteBlock.Len > this.MaxPackageSize)
{
this.OnError("缓存的数据长度大于设定值的情况下未收到解析信号");
this.OnError(default,"缓存的数据长度大于设定值的情况下未收到解析信号", true, true);
}
}
}

View File

@@ -80,7 +80,7 @@ namespace TouchSocket.Http
this.tempByteBlock.Write(byteBlock.Buffer, byteBlock.Pos, byteBlock.CanReadLen);
if (this.tempByteBlock.Len > this.MaxPackageSize)
{
this.OnError("缓存的数据长度大于设定值的情况下未收到解析信号");
this.OnError(default,"缓存的数据长度大于设定值的情况下未收到解析信号", true, true);
}
}
}

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,71 +1,52 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Sockets;
namespace TouchSocket.NamedPipe
{
/// <summary>
/// 命名管道服务器接口
/// INamedPipeService
/// </summary>
public interface INamedPipeService : IService, IIdSender, IIdRequsetInfoSender
/// <typeparam name="TClient"></typeparam>
public interface INamedPipeService<TClient> : INamedPipeServiceBase where TClient : INamedPipeSocketClient
{
/// <summary>
/// 当前在线客户端数量
/// 用户连接完成
/// </summary>
int Count { get; }
ConnectedEventHandler<TClient> Connected { get; set; }
/// <summary>
/// 获取最大可连接数
/// 有用户连接的时候
/// </summary>
int MaxCount { get; }
ConnectingEventHandler<TClient> Connecting { get; set; }
/// <summary>
/// 管道监听集合
/// 有用户断开连接
/// </summary>
IEnumerable<NamedPipeMonitor> Monitors { get; }
DisconnectEventHandler<TClient> Disconnected { get; set; }
/// <summary>
/// 获取当前连接的所有客户端
/// 即将断开连接(仅主动断开时有效)。
/// </summary>
INamedPipeSocketClientCollection SocketClients { get; }
DisconnectEventHandler<TClient> Disconnecting { get; set; }
/// <summary>
/// 清理当前已连接的所有客户端
/// </summary>
void Clear();
/// <summary>
/// 获取当前在线的所有Id集合
/// 尝试获取TClient
/// </summary>
/// <param name="id">Id</param>
/// <param name="socketClient">TClient</param>
/// <returns></returns>
IEnumerable<string> GetIds();
/// <summary>
/// 重置Id
/// </summary>
/// <param name="oldId"></param>
/// <param name="newId"></param>
/// <exception cref="ClientNotFindException"></exception>
/// <exception cref="Exception"></exception>
void ResetId(string oldId, string newId);
/// <summary>
/// 根据Id判断<see cref="INamedPipeSocketClient"/>是否存在
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
bool SocketClientExist(string id);
bool TryGetSocketClient(string id, out TClient socketClient);
}
}
/// <summary>
/// INamedPipeService
/// </summary>
public interface INamedPipeService : INamedPipeService<NamedPipeSocketClient>
{
}
}

View File

@@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using TouchSocket.Sockets;
namespace TouchSocket.NamedPipe
{
/// <summary>
/// 命名管道服务器接口
/// </summary>
public interface INamedPipeServiceBase : IService, IIdSender, IIdRequsetInfoSender
{
/// <summary>
/// 当前在线客户端数量
/// </summary>
int Count { get; }
/// <summary>
/// 获取最大可连接数
/// </summary>
int MaxCount { get; }
/// <summary>
/// 管道监听集合
/// </summary>
IEnumerable<NamedPipeMonitor> Monitors { get; }
/// <summary>
/// 获取当前连接的所有客户端
/// </summary>
INamedPipeSocketClientCollection SocketClients { get; }
/// <summary>
/// 清理当前已连接的所有客户端
/// </summary>
void Clear();
/// <summary>
/// 获取当前在线的所有Id集合
/// </summary>
/// <returns></returns>
IEnumerable<string> GetIds();
/// <summary>
/// 重置Id
/// </summary>
/// <param name="oldId"></param>
/// <param name="newId"></param>
/// <exception cref="ClientNotFindException"></exception>
/// <exception cref="Exception"></exception>
void ResetId(string oldId, string newId);
/// <summary>
/// 根据Id判断<see cref="INamedPipeSocketClient"/>是否存在
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
bool SocketClientExist(string id);
}
}

View File

@@ -26,7 +26,7 @@ namespace TouchSocket.NamedPipe
/// <summary>
/// 命名管道服务器
/// </summary>
public class NamedPipeService : NamedPipeService<NamedPipeSocketClient>
public class NamedPipeService : NamedPipeService<NamedPipeSocketClient>, INamedPipeService
{
/// <summary>
/// 处理数据
@@ -48,7 +48,7 @@ namespace TouchSocket.NamedPipe
/// 泛型命名管道服务器。
/// </summary>
/// <typeparam name="TClient"></typeparam>
public class NamedPipeService<TClient> : NamedPipeServiceBase where TClient : NamedPipeSocketClient, new()
public class NamedPipeService<TClient> : NamedPipeServiceBase,INamedPipeService<TClient> where TClient : NamedPipeSocketClient, new()
{
/// <summary>
/// 泛型命名管道服务器

View File

@@ -22,7 +22,7 @@ namespace TouchSocket.NamedPipe
/// <summary>
/// 命名管道服务器基类
/// </summary>
public abstract class NamedPipeServiceBase : ServiceBase, INamedPipeService
public abstract class NamedPipeServiceBase : ServiceBase, INamedPipeServiceBase
{
/// <summary>
/// <inheritdoc/>

View File

@@ -21,7 +21,7 @@ namespace TouchSocket.NamedPipe
public static class NamedPipeServiceExtension
{
/// <inheritdoc cref="IService.Start"/>
public static TService Start<TService>(this TService service, string pipeName) where TService : INamedPipeService
public static TService Start<TService>(this TService service, string pipeName) where TService : INamedPipeServiceBase
{
TouchSocketConfig config;
if (service.Config == null)

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -144,7 +144,7 @@ namespace TouchSocket.SerialPorts
var byteBlock = new ByteBlock(this.ReceiveBufferSize);
try
{
var r = await Task<int>.Factory.FromAsync(this.m_serialPort.BaseStream.BeginRead, this.m_serialPort.BaseStream.EndRead, byteBlock.Buffer, 0, byteBlock.Capacity, default);
var r = await Task<int>.Factory.FromAsync(this.m_serialPort.BaseStream.BeginRead, this.m_serialPort.BaseStream.EndRead, byteBlock.Buffer, 0, byteBlock.Capacity, default).ConfigureFalseAwait();
if (r == 0)
{
this.PrivateBreakOut(false, m_msg1);

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -104,7 +104,7 @@ namespace TouchSocket.WebApi.Swagger
if (this.LaunchBrowser)
{
var iphost = (sender as ITcpService).Monitors.First().Option.IpHost;
var iphost = (sender as ITcpServiceBase).Monitors.First().Option.IpHost;
string host;
if (iphost.IsLoopback || iphost.DnsSafeHost == "127.0.0.1" || iphost.DnsSafeHost == "0.0.0.0")
{

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -618,22 +618,25 @@ namespace TouchSocket.Sockets
private void OnAccepted(SocketAsyncEventArgs e)
{
if (!this.DisposedValue)
if (this.DisposedValue)
{
if (e.SocketError == SocketError.Success && e.AcceptSocket != null)
return;
}
if (e.SocketError == SocketError.Success && e.AcceptSocket != null)
{
var socket = e.AcceptSocket;
if (this.SocketClients.Count < this.m_maxCount)
{
var socket = e.AcceptSocket;
if (this.SocketClients.Count < this.m_maxCount)
{
//this.OnClientSocketInit(Tuple.Create(socket, (TcpNetworkMonitor)e.UserToken));
Task.Factory.StartNew(this.OnClientSocketInit, Tuple.Create(socket, (TcpNetworkMonitor)e.UserToken));
}
else
{
socket.SafeDispose();
this.Logger.Warning(this, "连接客户端数量已达到设定最大值");
}
//this.OnClientSocketInit(Tuple.Create(socket, (TcpNetworkMonitor)e.UserToken));
Task.Factory.StartNew(this.OnClientSocketInit, Tuple.Create(socket, (TcpNetworkMonitor)e.UserToken));
}
else
{
socket.SafeDispose();
this.Logger.Warning(this, "连接客户端数量已达到设定最大值");
}
e.AcceptSocket = null;
try
@@ -752,7 +755,7 @@ namespace TouchSocket.Sockets
/// <summary>
/// Tcp服务器
/// </summary>
public class TcpService : TcpService<SocketClient>
public class TcpService : TcpService<SocketClient>,ITcpService
{
/// <summary>
/// 处理数据

View File

@@ -22,7 +22,7 @@ namespace TouchSocket.Sockets
/// <summary>
/// Tcp服务器基类
/// </summary>
public abstract class TcpServiceBase : ServiceBase, ITcpService
public abstract class TcpServiceBase : ServiceBase, ITcpServiceBase
{
private readonly ConcurrentStack<TcpCore> m_tcpCores = new ConcurrentStack<TcpCore>();

View File

@@ -45,7 +45,7 @@ namespace TouchSocket.Sockets
}
catch (Exception ex)
{
this.OnError(ex.Message);
this.OnError(ex,ex.Message, true, true);
}
}

View File

@@ -69,26 +69,6 @@ namespace TouchSocket.Sockets
return client.Service.GetIds().Where(id => id != client.Id);
}
/// <summary>
/// 安全性关闭。不会抛出异常。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="client"></param>
/// <param name="msg"></param>
public static void SafeClose<T>(this T client, string msg="") where T : ICloseObject,IOnlineClient
{
try
{
if (client.Online)
{
client.Close(msg);
}
}
catch
{
}
}
/// <summary>
/// 安全性发送关闭报文
/// </summary>

View File

@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TouchSocket.Sockets
{
/// <summary>
/// CloseObjectExtension
/// </summary>
public static class CloseObjectExtension
{
/// <summary>
/// <inheritdoc cref="ICloseObject.Close(string)"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="client"></param>
public static void Close<T>(this T client) where T : ICloseObject
{
client.Close(string.Empty);
}
/// <summary>
/// 安全性关闭。不会抛出异常。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="client"></param>
/// <param name="msg"></param>
public static void SafeClose<T>(this T client, string msg) where T : ICloseObject
{
try
{
if (client == null)
{
return;
}
if (client is IOnlineClient onlineClient)
{
if (onlineClient.Online)
{
client.Close(msg);
}
}
else if (client is IHandshakeObject handshakeObject)
{
if (handshakeObject.IsHandshaked)
{
client.Close(msg);
}
}
else
{
client.Close(msg);
}
}
catch
{
}
}
/// <summary>
/// 安全性关闭。不会抛出异常。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="client"></param>
public static void SafeClose<T>(this T client) where T : ICloseObject
{
SafeClose(client);
}
}
}

View File

@@ -23,7 +23,7 @@ namespace TouchSocket.Sockets
#region ITcpService
/// <inheritdoc cref="IService.Start"/>
public static void Start<TService>(this TService service, params IPHost[] iPHosts) where TService : ITcpService
public static void Start<TService>(this TService service, params IPHost[] iPHosts) where TService : ITcpServiceBase
{
TouchSocketConfig config;
if (service.Config == null)
@@ -42,7 +42,7 @@ namespace TouchSocket.Sockets
/// <inheritdoc cref="IService.StartAsync"/>
public static async Task StartAsync<TService>(this TService service, params IPHost[] iPHosts) where TService : ITcpService
public static async Task StartAsync<TService>(this TService service, params IPHost[] iPHosts) where TService : ITcpServiceBase
{
TouchSocketConfig config;
if (service.Config == null)

View File

@@ -502,7 +502,7 @@ namespace TouchSocket.Sockets
/// <typeparam name="TService"></typeparam>
/// <param name="config"></param>
/// <returns></returns>
public static TService BuildService<TService>(this TouchSocketConfig config) where TService : ITcpService, new()
public static TService BuildService<TService>(this TouchSocketConfig config) where TService : ITcpServiceBase, new()
{
var service = new TService();
service.Setup(config);

View File

@@ -18,6 +18,6 @@ namespace TouchSocket.Sockets
/// </summary>
/// <param name="msg"></param>
/// <exception cref="Exception"></exception>
void Close(string msg = TouchSocketCoreUtility.Empty);
void Close(string msg);
}
}

View File

@@ -1,25 +1,15 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
using System;
using System;
using System.Collections.Generic;
using TouchSocket.Core;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TouchSocket.Sockets
{
/// <summary>
/// Tcp系列服务器接口
/// </summary>
public interface ITcpService<TClient> : ITcpService where TClient : ISocketClient
public interface ITcpService<TClient> : ITcpServiceBase where TClient : ISocketClient
{
/// <summary>
/// 用户连接完成
@@ -36,6 +26,11 @@ namespace TouchSocket.Sockets
/// </summary>
DisconnectEventHandler<TClient> Disconnected { get; set; }
/// <summary>
/// 即将断开连接(仅主动断开时有效)。
/// </summary>
DisconnectEventHandler<TClient> Disconnecting { get; set; }
/// <summary>
/// 尝试获取TClient
/// </summary>
@@ -46,55 +41,10 @@ namespace TouchSocket.Sockets
}
/// <summary>
/// Tcp服务器接口
/// Tcp系列服务器接口
/// </summary>
public interface ITcpService : IService, IIdSender, IIdRequsetInfoSender, IPluginObject
public interface ITcpService : ITcpService<SocketClient>
{
/// <summary>
/// 当前在线客户端数量
/// </summary>
int Count { get; }
/// <summary>
/// 获取最大可连接数
/// </summary>
int MaxCount { get; }
/// <summary>
/// 网络监听集合
/// </summary>
IEnumerable<TcpNetworkMonitor> Monitors { get; }
/// <summary>
/// 获取当前连接的所有客户端
/// </summary>
ISocketClientCollection SocketClients { get; }
/// <summary>
/// 清理当前已连接的所有客户端
/// </summary>
void Clear();
/// <summary>
/// 获取当前在线的所有Id集合
/// </summary>
/// <returns></returns>
IEnumerable<string> GetIds();
/// <summary>
/// 重置Id
/// </summary>
/// <param name="oldId"></param>
/// <param name="newId"></param>
/// <exception cref="ClientNotFindException"></exception>
/// <exception cref="Exception"></exception>
void ResetId(string oldId, string newId);
/// <summary>
/// 根据Id判断SocketClient是否存在
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
bool SocketClientExist(string id);
}
}
}

View File

@@ -0,0 +1,72 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using TouchSocket.Core;
namespace TouchSocket.Sockets
{
/// <summary>
/// Tcp服务器接口
/// </summary>
public interface ITcpServiceBase : IService, IIdSender, IIdRequsetInfoSender, IPluginObject
{
/// <summary>
/// 当前在线客户端数量
/// </summary>
int Count { get; }
/// <summary>
/// 获取最大可连接数
/// </summary>
int MaxCount { get; }
/// <summary>
/// 网络监听集合
/// </summary>
IEnumerable<TcpNetworkMonitor> Monitors { get; }
/// <summary>
/// 获取当前连接的所有客户端
/// </summary>
ISocketClientCollection SocketClients { get; }
/// <summary>
/// 清理当前已连接的所有客户端
/// </summary>
void Clear();
/// <summary>
/// 获取当前在线的所有Id集合
/// </summary>
/// <returns></returns>
IEnumerable<string> GetIds();
/// <summary>
/// 重置Id
/// </summary>
/// <param name="oldId"></param>
/// <param name="newId"></param>
/// <exception cref="ClientNotFindException"></exception>
/// <exception cref="Exception"></exception>
void ResetId(string oldId, string newId);
/// <summary>
/// 根据Id判断SocketClient是否存在
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
bool SocketClientExist(string id);
}
}

View File

@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2020-2023 若汝棋茗
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.