mirror of
https://github.com/RRQM/TouchSocket.git
synced 2025-12-18 09:26:42 +08:00
优化适配器纠错能力
优化TcpService接口继承 优化DmtpService接口继承 优化协议文件
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
/// 连接令箭
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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)))
|
||||
{
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
/// 泛型命名管道服务器
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace TouchSocket.NamedPipe
|
||||
/// <summary>
|
||||
/// 命名管道服务器基类
|
||||
/// </summary>
|
||||
public abstract class NamedPipeServiceBase : ServiceBase, INamedPipeService
|
||||
public abstract class NamedPipeServiceBase : ServiceBase, INamedPipeServiceBase
|
||||
{
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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")
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
/// 处理数据
|
||||
|
||||
@@ -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>();
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace TouchSocket.Sockets
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.OnError(ex.Message);
|
||||
this.OnError(ex,ex.Message, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
72
src/TouchSocket/Extensions/CloseObjectExtension.cs
Normal file
72
src/TouchSocket/Extensions/CloseObjectExtension.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
72
src/TouchSocket/Interface/ITcpServiceBase.cs
Normal file
72
src/TouchSocket/Interface/ITcpServiceBase.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user