提交 0d993375 编写于 作者: 若汝棋茗

优化 优化IOC容器。

优化Metadata的写入方式。
FileLogger,当日志文件达到1Mb时,会再新增文件序号。
新增 Mapper类,支持简单类型映射
修改 RRQM二进制序列化,改名为Fast。
TouchRpcClient连接时的Metadata,改为由Config配置注入。
FilePool,取消延迟释放机制。
修复 无
删除 客户端直接调用的短线重连方式。仅保留在Config注入的功能。
上级 706650b9
......@@ -548,7 +548,7 @@ namespace TouchSocket.Core.ByteManager
/// <param name="byteBlock"></param>
/// <param name="serializationType"></param>
/// <returns></returns>
public static T ReadObject<T>(this IByteBlock byteBlock, SerializationType serializationType = SerializationType.RRQMBinary)
public static T ReadObject<T>(this IByteBlock byteBlock, SerializationType serializationType = SerializationType.FastBinary)
{
int length = byteBlock.ReadInt32();
......@@ -561,9 +561,9 @@ namespace TouchSocket.Core.ByteManager
switch (serializationType)
{
case SerializationType.RRQMBinary:
case SerializationType.FastBinary:
{
obj = SerializeConvert.RRQMBinaryDeserialize<T>(byteBlock.Buffer, byteBlock.Pos);
obj = SerializeConvert.FastBinaryDeserialize<T>(byteBlock.Buffer, byteBlock.Pos);
}
break;
......@@ -588,7 +588,7 @@ namespace TouchSocket.Core.ByteManager
/// <param name="byteBlock"></param>
/// <param name="value"></param>
/// <param name="serializationType"></param>
public static TByteBlock WriteObject<TByteBlock>(this TByteBlock byteBlock, object value, SerializationType serializationType = SerializationType.RRQMBinary)
public static TByteBlock WriteObject<TByteBlock>(this TByteBlock byteBlock, object value, SerializationType serializationType = SerializationType.FastBinary)
where TByteBlock : IByteBlock
{
if (value == null)
......@@ -599,9 +599,9 @@ namespace TouchSocket.Core.ByteManager
byte[] data;
switch (serializationType)
{
case SerializationType.RRQMBinary:
case SerializationType.FastBinary:
{
data = SerializeConvert.RRQMBinarySerialize(value);
data = SerializeConvert.FastBinarySerialize(value);
}
break;
......
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
//namespace TouchSocket.Core.ByteManager
//{
// /// <summary>
// /// 字节块流
// /// </summary>
// [System.Diagnostics.DebuggerDisplay("Len={Len}")]
// public ref struct ValueByteBlock /*: IByteBlock*/
// {
// internal long m_length;
// internal bool m_using;
// private static float m_ratio = 1.5f;
// private byte[] m_buffer;
// private bool m_holding;
// private object m_locker;
// private bool m_needDis;
// private long m_position;
// /// <summary>
// /// 构造函数
// /// </summary>
// /// <param name="byteSize"></param>
// /// <param name="equalSize"></param>
// public ValueByteBlock(int byteSize = 1024 * 64, bool equalSize = false)
// {
// this.m_needDis = true;
// this.m_buffer = BytePool.GetByteCore(byteSize, equalSize);
// this.m_using = true;
// this.m_length = 0;
// this.m_holding = false;
// this.m_position = 0;
// this.m_locker = new object();
// }
// /// <summary>
// /// 构造函数
// /// </summary>
// /// <param name="bytes"></param>
// public ValueByteBlock(byte[] bytes)
// {
// this.m_buffer = bytes ?? throw new ArgumentNullException(nameof(bytes));
// this.m_length = bytes.Length;
// this.m_using = true;
// this.m_needDis = false;
// this.m_length = 0;
// this.m_holding = false;
// this.m_position = 0;
// this.m_locker = new object();
// }
// /// <summary>
// /// 扩容增长比,默认为1.5,
// /// min:1.5
// /// </summary>
// public static float Ratio
// {
// get => m_ratio;
// set
// {
// if (value < 1.5)
// {
// value = 1.5f;
// }
// m_ratio = value;
// }
// }
// /// <summary>
// /// 字节实例
// /// </summary>
// public byte[] Buffer => this.m_buffer;
// /// <summary>
// /// 仅当内存块可用,且<see cref="CanReadLen"/>>0时为True。
// /// </summary>
// public bool CanRead => this.m_using && this.CanReadLen > 0;
// /// <summary>
// /// 还能读取的长度,计算为<see cref="Len"/>与<see cref="Pos"/>的差值。
// /// </summary>
// public int CanReadLen => this.Len - this.Pos;
// /// <summary>
// /// 还能读取的长度,计算为<see cref="Len"/>与<see cref="Pos"/>的差值。
// /// </summary>
// public long CanReadLength => this.m_length - this.m_position;
// /// <summary>
// /// 容量
// /// </summary>
// public int Capacity => this.m_buffer.Length;
// /// <summary>
// /// 表示持续性持有,为True时,Dispose将调用无效。
// /// </summary>
// public bool Holding => this.m_holding;
// /// <summary>
// /// Int真实长度
// /// </summary>
// public int Len => (int)this.m_length;
// /// <summary>
// /// 真实长度
// /// </summary>
// public long Length => this.m_length;
// /// <summary>
// /// int型流位置
// /// </summary>
// public int Pos
// {
// get => (int)this.m_position;
// set => this.m_position = value;
// }
// /// <summary>
// /// 流位置
// /// </summary>
// public long Position
// {
// get => this.m_position;
// set => this.m_position = value;
// }
// /// <summary>
// /// 使用状态
// /// </summary>
// public bool Using => this.m_using;
// /// <summary>
// /// <inheritdoc/>
// /// </summary>
// public int FreeLength => this.Capacity - this.Pos;
// /// <summary>
// /// 直接完全释放,游离该对象,然后等待GC
// /// </summary>
// public void AbsoluteDispose()
// {
// this.m_holding = false;
// this.m_using = false;
// this.m_position = 0;
// this.m_length = 0;
// this.m_buffer = null;
// }
// /// <summary>
// /// 清空所有内存数据
// /// </summary>
// /// <exception cref="ObjectDisposedException">内存块已释放</exception>
// public void Clear()
// {
// if (!this.m_using)
// {
// throw new ObjectDisposedException(this.GetType().FullName);
// }
// Array.Clear(this.m_buffer, 0, this.m_buffer.Length);
// }
// /// <summary>
// /// 释放
// /// </summary>
// public void Dispose()
// {
// if (this.m_holding)
// {
// return;
// }
// if (this.m_needDis)
// {
// lock (m_locker)
// {
// if (this.m_using)
// {
// GC.SuppressFinalize(this);
// BytePool.Recycle(this.m_buffer);
// this.AbsoluteDispose();
// }
// }
// }
// }
// /// <summary>
// /// 读取数据,然后递增Pos
// /// </summary>
// /// <param name="buffer"></param>
// /// <param name="offset"></param>
// /// <param name="length"></param>
// /// <returns></returns>
// /// <exception cref="ObjectDisposedException"></exception>
// public int Read(byte[] buffer, int offset, int length)
// {
// if (!this.m_using)
// {
// throw new ObjectDisposedException(this.GetType().FullName);
// }
// int len = this.m_length - this.m_position > length ? length : this.CanReadLen;
// Array.Copy(this.m_buffer, this.m_position, buffer, offset, len);
// this.m_position += len;
// return len;
// }
// /// <summary>
// /// 读取数据,然后递增Pos
// /// </summary>
// /// <param name="buffer"></param>
// /// <returns></returns>
// public int Read(byte[] buffer)
// {
// return this.Read(buffer, 0, buffer.Length);
// }
// /// <summary>
// /// 读取数据,然后递增Pos
// /// </summary>
// /// <param name="buffer"></param>
// /// <param name="length"></param>
// /// <returns></returns>
// public int Read(out byte[] buffer, int length)
// {
// buffer = new byte[length];
// return this.Read(buffer, 0, buffer.Length);
// }
// /// <summary>
// /// <inheritdoc/>
// /// </summary>
// /// <returns></returns>
// public int ReadByte()
// {
// byte value = this.m_buffer[this.m_position];
// this.m_position++;
// return value;
// }
// /// <summary>
// /// 将内存块初始化到刚申请的状态。
// /// <para>仅仅重置<see cref="Position"/>和<see cref="Length"/>属性。</para>
// /// </summary>
// /// <exception cref="ObjectDisposedException">内存块已释放</exception>
// public void Reset()
// {
// if (!this.m_using)
// {
// throw new ObjectDisposedException(this.GetType().FullName);
// }
// this.m_position = 0;
// this.m_length = 0;
// }
// /// <summary>
// /// 重新设置容量
// /// </summary>
// /// <param name="size">新尺寸</param>
// /// <param name="retainedData">是否保留元数据</param>
// /// <exception cref="ObjectDisposedException"></exception>
// public void SetCapacity(int size, bool retainedData = false)
// {
// if (!this.m_using)
// {
// throw new ObjectDisposedException(this.GetType().FullName);
// }
// byte[] bytes = new byte[size];
// if (retainedData)
// {
// Array.Copy(this.m_buffer, 0, bytes, 0, this.m_buffer.Length);
// }
// BytePool.Recycle(this.m_buffer);
// this.m_buffer = bytes;
// }
// /// <summary>
// /// 设置持续持有属性,当为True时,调用Dispose会失效,表示该对象将长期持有,直至设置为False。
// /// 当为False时,会自动调用Dispose。
// /// </summary>
// /// <param name="holding"></param>
// /// <exception cref="ObjectDisposedException"></exception>
// public void SetHolding(bool holding)
// {
// if (!this.m_using)
// {
// throw new ObjectDisposedException(this.GetType().FullName);
// }
// this.m_holding = holding;
// if (!holding)
// {
// this.Dispose();
// }
// }
// /// <summary>
// /// 设置实际长度
// /// </summary>
// /// <param name="value"></param>
// /// <exception cref="ObjectDisposedException"></exception>
// public void SetLength(long value)
// {
// if (!this.m_using)
// {
// throw new ObjectDisposedException(this.GetType().FullName);
// }
// if (value > this.m_buffer.Length)
// {
// throw new Exception("设置值超出容量");
// }
// this.m_length = value;
// }
// /// <summary>
// /// 从指定位置转化到指定长度的有效内存
// /// </summary>
// /// <param name="offset"></param>
// /// <param name="length"></param>
// /// <returns></returns>
// public byte[] ToArray(int offset, int length)
// {
// if (!this.m_using)
// {
// throw new ObjectDisposedException(this.GetType().FullName);
// }
// byte[] buffer = new byte[length];
// Array.Copy(this.m_buffer, offset, buffer, 0, buffer.Length);
// return buffer;
// }
// /// <summary>
// /// 转换为UTF-8字符
// /// </summary>
// /// <returns></returns>
// public override string ToString()
// {
// return this.ToString(0, this.Len);
// }
// /// <summary>
// /// 转换为UTF-8字符
// /// </summary>
// /// <param name="offset">偏移量</param>
// /// <param name="length">长度</param>
// /// <returns></returns>
// public string ToString(int offset, int length)
// {
// if (!this.m_using)
// {
// throw new ObjectDisposedException(this.GetType().FullName);
// }
// return Encoding.UTF8.GetString(this.m_buffer, offset, length);
// }
// /// <summary>
// /// 转换为UTF-8字符
// /// </summary>
// /// <param name="offset">偏移量</param>
// /// <returns></returns>
// public string ToString(int offset)
// {
// if (!this.m_using)
// {
// throw new ObjectDisposedException(this.GetType().FullName);
// }
// return Encoding.UTF8.GetString(this.m_buffer, offset, this.Len - offset);
// }
// /// <summary>
// /// 写入
// /// </summary>
// /// <param name="buffer"></param>
// /// <param name="offset"></param>
// /// <param name="count"></param>
// /// <exception cref="ObjectDisposedException"></exception>
// public void Write(byte[] buffer, int offset, int count)
// {
// if (count == 0)
// {
// return;
// }
// if (!this.m_using)
// {
// throw new ObjectDisposedException(this.GetType().FullName);
// }
// if (this.m_buffer.Length - this.m_position < count)
// {
// int need = this.m_buffer.Length + count - ((int)(this.m_buffer.Length - this.m_position));
// int lend = this.m_buffer.Length;
// while (need > lend)
// {
// lend = (int)(lend * m_ratio);
// }
// this.SetCapacity(lend, true);
// }
// Array.Copy(buffer, offset, this.m_buffer, this.m_position, count);
// this.m_position += count;
// this.m_length = Math.Max(this.m_position, this.m_length);
// }
// }
//}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TouchSocketPro
{
/// <summary>
/// 映射数据
/// </summary>
public static class Mapper
{
/// <summary>
/// 简单映射
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="T1"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
public static T1 Map<T, T1>(T t)where T:class where T1:class,new ()
{
if (t is null)
{
return default;
}
var source = Activator.CreateInstance(typeof(T));
var result = Activator.CreateInstance(typeof(T1));
if (source.GetType().Name == "List`1" || result.GetType().Name == "List`1")
{
throw new Exception("形参有误!,请使用对象。");
}
var tpropertyInfos = source.GetType().GetProperties();
var t1propertyInfos = result.GetType().GetProperties();
foreach (var tinfo in tpropertyInfos)
{
foreach (var t1info in t1propertyInfos)
{
if (t1info.PropertyType.IsValueType || t1info.PropertyType.Name.StartsWith("String"))
{
if (tinfo.Name == t1info.Name)
{
try
{
object value = tinfo.GetValue(t, null);
var property = typeof(T1).GetProperty(tinfo.Name);
if (property != null && property.CanWrite && !(value is DBNull))
{
property.SetValue(result, value, null);
}
}
catch
{
}
}
}
}
}
return (T1)result;
}
/// <summary>
/// 简单映射
/// </summary>
/// <typeparam name="T1"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
public static T1 Map<T1>(object t) where T1 : class, new()
{
if (t is null)
{
return default;
}
var result = Activator.CreateInstance(typeof(T1));
if (t.GetType().Name == "List`1" || result.GetType().Name == "List`1")
{
throw new Exception("形参有误!,请使用对象。");
}
var tpropertyInfos = t.GetType().GetProperties();
var t1propertyInfos = result.GetType().GetProperties();
foreach (var tinfo in tpropertyInfos)
{
foreach (var t1info in t1propertyInfos)
{
if (t1info.PropertyType.IsValueType || t1info.PropertyType.Name.StartsWith("String"))
{
if (tinfo.Name == t1info.Name)
{
try
{
object value = tinfo.GetValue(t, null);
var property = typeof(T1).GetProperty(tinfo.Name);
if (property != null && property.CanWrite && !(value is DBNull))
{
property.SetValue(result, value, null);
}
}
catch
{
}
}
}
}
}
return (T1)result;
}
/// <summary>
/// 映射List
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="T1"></typeparam>
/// <param name="list"></param>
/// <returns></returns>
public static IEnumerable<T1> MapList<T, T1>(IEnumerable<T> list) where T : class where T1 : class, new()
{
if (list is null)
{
throw new ArgumentNullException(nameof(list));
}
List<T1> result = new List<T1>();
foreach (var item in list)
{
result.Add(Map<T, T1>(item));
}
return result;
}
}
}
......@@ -24,7 +24,7 @@ namespace TouchSocket.Core
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void AddOrUpdate(string key, string value)
public Metadata AddOrUpdate(string key, string value)
{
if (this.ContainsKey(key))
{
......@@ -34,6 +34,7 @@ namespace TouchSocket.Core
{
this.Add(key, value);
}
return this;
}
}
}
\ No newline at end of file
......@@ -213,9 +213,8 @@ namespace TouchSocket.Core.IO
/// 减少引用次数,并尝试释放流。
/// </summary>
/// <param name="path"></param>
/// <param name="delayTime">延迟释放时间,默认5000ms。当设置为0时,立即释放。</param>
/// <returns></returns>
public static Result TryReleaseFile(string path, int delayTime = 5000)
public static Result TryReleaseFile(string path)
{
if (string.IsNullOrEmpty(path))
{
......@@ -227,28 +226,11 @@ namespace TouchSocket.Core.IO
Interlocked.Decrement(ref fileStorage.reference);
if (fileStorage.reference <= 0)
{
if (delayTime > 0)
if (pathStream.TryRemove(path, out fileStorage))
{
Run.EasyAction.DelayRun(delayTime, path, (p) =>
{
if (GetReferenceCount(p) == 0)
{
if (pathStream.TryRemove(p, out fileStorage))
{
fileStorage.Dispose();
}
}
});
return new Result(ResultCode.Success, $"如果在{delayTime}ms后引用仍然为0的话,即被释放。");
}
else
{
if (pathStream.TryRemove(path, out fileStorage))
{
fileStorage.Dispose();
}
return new Result(ResultCode.Success, "流成功释放。");
fileStorage.Dispose();
}
return new Result(ResultCode.Success, "流成功释放。");
}
else
{
......@@ -257,7 +239,7 @@ namespace TouchSocket.Core.IO
}
else
{
return new Result(ResultCode.Error, ResType.StreamNotFind.GetDescription(path));
return new Result(ResultCode.Success, ResType.StreamNotFind.GetDescription(path));
}
}
}
......
......@@ -17,7 +17,7 @@ namespace TouchSocket.Core.IO
/// <summary>
/// 文件读取器
/// </summary>
public class FileStorageReader : IDisposable
public class FileStorageReader : DisposableObject
{
private FileStorage m_fileStorage;
......@@ -36,7 +36,6 @@ namespace TouchSocket.Core.IO
public FileStorage FileStorage => this.m_fileStorage;
private long m_position;
private bool m_disposedValue;
/// <summary>
/// 游标位置
......@@ -71,22 +70,14 @@ namespace TouchSocket.Core.IO
}
/// <summary>
/// 释放资源
/// <inheritdoc/>
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
protected override void Dispose(bool disposing)
{
if (!this.m_disposedValue)
{
if (disposing)
{
// TODO: 释放托管状态(托管对象)
}
FilePool.TryReleaseFile(this.m_fileStorage?.Path);
this.m_fileStorage = null;
this.m_disposedValue = true;
}
FilePool.TryReleaseFile(this.m_fileStorage?.Path);
this.m_fileStorage = null;
base.Dispose(disposing);
}
/// <summary>
......@@ -97,26 +88,5 @@ namespace TouchSocket.Core.IO
// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
this.Dispose(disposing: false);
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
this.Dispose(disposing: true);
GC.SuppressFinalize(this);
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose(int delayTime)
{
FilePool.TryReleaseFile(this.m_fileStorage?.Path, delayTime);
// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
this.Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}
\ No newline at end of file
......@@ -17,9 +17,8 @@ namespace TouchSocket.Core.IO
/// <summary>
/// 文件写入器。
/// </summary>
public class FileStorageWriter : IDisposable
public class FileStorageWriter : DisposableObject
{
private bool m_disposedValue;
private FileStorage m_fileStorage;
private readonly bool m_singleRef;
private long m_position;
......@@ -44,6 +43,16 @@ namespace TouchSocket.Core.IO
this.Dispose(disposing: false);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
FilePool.TryReleaseFile(this.m_fileStorage?.Path);
base.Dispose(disposing);
}
/// <summary>
/// 文件存储器
/// </summary>
......@@ -67,16 +76,7 @@ namespace TouchSocket.Core.IO
set => this.m_position = value;
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
this.Dispose(disposing: true);
GC.SuppressFinalize(this);
}
/// <summary>
/// 读取数据到缓存区
/// </summary>
......@@ -90,23 +90,6 @@ namespace TouchSocket.Core.IO
this.m_position += length;
}
/// <summary>
/// 释放资源
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (!this.m_disposedValue)
{
if (disposing)
{
// TODO: 释放托管状态(托管对象)
}
FilePool.TryReleaseFile(this.m_fileStorage?.Path, this.m_singleRef ? 0 : 5000);
this.m_fileStorage = null;
this.m_disposedValue = true;
}
}
}
}
\ No newline at end of file
......@@ -74,13 +74,27 @@ namespace TouchSocket.Core.Log
this.Print(stringBuilder.ToString());
}
int m_day=-1;
int m_count;
private void Print(string logString)
{
try
{
lock (typeof(FileLogger))
{
string path = Path.Combine(this.rootPath, DateTime.Now.ToString("[yyyy-MM-dd]") + ".log");
if (m_day != DateTime.Now.DayOfYear)
{
m_day = DateTime.Now.DayOfYear;
m_count = 0;
}
else
{
if (new FileInfo(Path.Combine(this.rootPath, $"{DateTime.Now:[yyyy-MM-dd]}-{m_count:00}" + ".log")).Length>1024*1024 )
{
m_count++;
}
}
string path = Path.Combine(this.rootPath, $"{DateTime.Now:[yyyy-MM-dd]}-{m_count:00}" + ".log");
File.AppendAllText(path, logString);
}
}
......
......@@ -133,17 +133,17 @@ namespace TouchSocket.Core.Plugins
{
if (value.TryGetValue(name, out PluginMethod pluginMethod))
{
foreach (var item in this.m_plugins)
for (int i = 0; i < this.m_plugins.Count; i++)
{
if (args.Handled)
{
return true;
}
if (pluginMethod.type.IsAssignableFrom(item.GetType()))
if (pluginMethod.type.IsAssignableFrom(this.m_plugins[i].GetType()))
{
try
{
pluginMethod.Invoke(item, @params);
pluginMethod.Invoke(this.m_plugins[i], @params);
}
catch
{
......
......@@ -18,7 +18,7 @@ namespace TouchSocket.Core.Serialization
/// 忽略的RRQM序列化
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class TouchSocketNonSerializedAttribute : Attribute
public class FastNonSerializedAttribute : Attribute
{
}
}
\ No newline at end of file
......@@ -25,7 +25,7 @@ namespace TouchSocket.Core.Serialization
/// <summary>
/// 该序列化以二进制方式进行,但是不支持接口、抽象类、继承类等成员的序列化。
/// </summary>
public class TouchSocketBinaryFormatter
public class FastBinaryFormatter
{
#region Serialize
......@@ -182,7 +182,7 @@ namespace TouchSocket.Core.Serialization
PropertyInfo[] propertyInfos = GetProperties(type);
foreach (PropertyInfo property in propertyInfos)
{
if (property.GetCustomAttribute<TouchSocketNonSerializedAttribute>() != null)
if (property.GetCustomAttribute<FastNonSerializedAttribute>() != null)
{
continue;
}
......
......@@ -19,9 +19,9 @@ namespace TouchSocket.Core.Serialization
public enum SerializationType : byte
{
/// <summary>
/// 若汝棋茗内置
/// 内置快速二进制
/// </summary>
RRQMBinary,
FastBinary,
/// <summary>
/// Json
......
......@@ -178,61 +178,61 @@ namespace TouchSocket.Core.Serialization
#endif
#region RRQM二进制序列化
#region Fast二进制序列化
/// <summary>
/// RRQM二进制序列化对象
/// Fast二进制序列化对象
/// </summary>
/// <param name="stream"></param>
/// <param name="obj"></param>
/// <returns></returns>
public static void RRQMBinarySerialize(ByteBlock stream, object obj)
public static void FastBinarySerialize(ByteBlock stream, object obj)
{
TouchSocketBinaryFormatter bf = new TouchSocketBinaryFormatter();
FastBinaryFormatter bf = new FastBinaryFormatter();
bf.Serialize(stream, obj);
}
/// <summary>
/// RRQM二进制序列化对象
/// Fast二进制序列化对象
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static byte[] RRQMBinarySerialize(object obj)
public static byte[] FastBinarySerialize(object obj)
{
using (ByteBlock byteBlock = new ByteBlock())
{
RRQMBinarySerialize(byteBlock, obj);
FastBinarySerialize(byteBlock, obj);
return byteBlock.ToArray();
}
}
#endregion RRQM二进制序列化
#endregion Fast二进制序列化
#region RRQM二进制反序列化
#region Fast二进制反序列化
/// <summary>
/// 反序列化
/// Fast反序列化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
/// <param name="offset"></param>
/// <returns></returns>
public static T RRQMBinaryDeserialize<T>(byte[] data, int offset)
public static T FastBinaryDeserialize<T>(byte[] data, int offset)
{
TouchSocketBinaryFormatter bf = new TouchSocketBinaryFormatter();
FastBinaryFormatter bf = new FastBinaryFormatter();
return (T)bf.Deserialize(data, offset, typeof(T));
}
/// <summary>
/// 反序列化
/// Fast反序列化
/// </summary>
/// <param name="data"></param>
/// <param name="offset"></param>
/// <param name="type"></param>
/// <returns></returns>
public static object RRQMBinaryDeserialize(byte[] data, int offset, Type type)
public static object FastBinaryDeserialize(byte[] data, int offset, Type type)
{
TouchSocketBinaryFormatter bf = new TouchSocketBinaryFormatter();
FastBinaryFormatter bf = new FastBinaryFormatter();
return bf.Deserialize(data, offset, type);
}
......@@ -242,12 +242,12 @@ namespace TouchSocket.Core.Serialization
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
/// <returns></returns>
public static T RRQMBinaryDeserialize<T>(byte[] data)
public static T FastBinaryDeserialize<T>(byte[] data)
{
return RRQMBinaryDeserialize<T>(data, 0);
return FastBinaryDeserialize<T>(data, 0);
}
#endregion RRQM二进制反序列化
#endregion Fast二进制反序列化
#region Xml序列化和反序列化
......
......@@ -456,7 +456,6 @@ namespace TouchSocket.Http
}
reader.Position = httpRange.Start;
long surLen = httpRange.Length;
using (ByteBlock block = new ByteBlock(bufferLen))
{
while (surLen > 0)
......
......@@ -34,9 +34,9 @@ namespace TouchSocket.Core.Config
/// <param name="config"></param>
/// <param name="action">当RpcStore完成配置时回调</param>
/// <param name="value">可以使用现有的值,如果赋值为null,则会重新创建。</param>
public static TouchSocketConfig ConfigureRpcStore(this TouchSocketConfig config, Action<RpcStore> action, RpcStore value = default)
public static TouchSocketConfig ConfigureRpcStore(this TouchSocketConfig config, Action<RpcStore> action, RpcStore value=default)
{
if (value == default)
if (value==default)
{
value = new RpcStore(config.Container);
}
......
......@@ -42,7 +42,7 @@ namespace TouchSocket.Rpc.TouchRpc
/// <param name="feedbackType"></param>
/// <param name="serializationType"></param>
/// <param name="cancellationToken"></param>
public InvokeOption(int timeout = 5000, FeedbackType feedbackType = FeedbackType.WaitInvoke, SerializationType serializationType = SerializationType.RRQMBinary,
public InvokeOption(int timeout = 5000, FeedbackType feedbackType = FeedbackType.WaitInvoke, SerializationType serializationType = SerializationType.FastBinary,
CancellationToken cancellationToken = default) : this()
{
this.Timeout = timeout;
......
......@@ -30,11 +30,11 @@ namespace TouchSocket.Rpc.TouchRpc
/// </summary>
public class HttpTouchRpcClient : HttpClientBase, IHttpTouchRpcClient
{
private readonly ActionMap m_actionMap;
private int m_failCount = 0;
private RpcActor m_rpcActor;
private readonly RpcActor m_rpcActor;
private RpcStore m_rpcStore;
private Timer m_timer;
private ActionMap m_actionMap;
/// <summary>
/// 创建一个HttpTouchRpcClient实例。
......@@ -58,19 +58,19 @@ namespace TouchSocket.Rpc.TouchRpc
}
/// <summary>
/// <inheritdoc/>
/// 服务器映射
/// </summary>
public string ID => this.m_rpcActor.ID;
public ActionMap ActionMap { get => m_actionMap; }
/// <summary>
/// <inheritdoc/>
/// </summary>
public bool IsHandshaked => this.m_rpcActor != null && this.m_rpcActor.IsHandshaked;
public string ID => this.m_rpcActor.ID;
/// <summary>
/// 服务器映射
/// <inheritdoc/>
/// </summary>
public ActionMap ActionMap { get => m_actionMap; }
public bool IsHandshaked => this.m_rpcActor != null && this.m_rpcActor.IsHandshaked;
/// <summary>
/// <inheritdoc/>
......@@ -118,18 +118,6 @@ namespace TouchSocket.Rpc.TouchRpc
/// <param name="timeout"></param>
/// <returns></returns>
public override ITcpClient Connect(int timeout = 5000)
{
return this.Connect(null, default, timeout);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="metadata"></param>
/// <param name="token"></param>
/// <param name="timeout"></param>
/// <returns></returns>
public virtual ITcpClient Connect(Metadata metadata = null, CancellationToken token = default, int timeout = 5000)
{
if (this.IsHandshaked)
{
......@@ -146,7 +134,8 @@ namespace TouchSocket.Rpc.TouchRpc
if (response.StatusCode == "200")
{
this.SwitchProtocolToTouchRpc();
this.m_rpcActor.Handshake(this.Config.GetValue<string>(TouchRpcConfigExtensions.VerifyTokenProperty), token, timeout, metadata);
this.m_rpcActor.Handshake(this.Config.GetValue<string>(TouchRpcConfigExtensions.VerifyTokenProperty), default,
timeout, this.Config.GetValue<Metadata>(TouchRpcConfigExtensions.MetadataProperty));
return this;
}
else
......@@ -155,21 +144,6 @@ namespace TouchSocket.Rpc.TouchRpc
}
}
/// <summary>
/// 异步连接
/// </summary>
/// <param name="metadata"></param>
/// <param name="token"></param>
/// <param name="timeout"></param>
/// <returns></returns>
public virtual Task<ITcpClient> ConnectAsync(Metadata metadata = null, CancellationToken token = default, int timeout = 5000)
{
return Task.Run(() =>
{
return this.Connect(metadata, token, timeout);
});
}
/// <summary>
/// <inheritdoc/>
/// </summary>
......@@ -510,6 +484,17 @@ namespace TouchSocket.Rpc.TouchRpc
return this.m_rpcActor.SendStreamAsync(stream, streamOperator, metadata);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="id"></param>
/// <param name="channel"></param>
/// <returns></returns>
public bool TrySubscribeChannel(int id, out Channel channel)
{
return this.m_rpcActor.TrySubscribeChannel(id, out channel);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
......@@ -694,17 +679,6 @@ namespace TouchSocket.Rpc.TouchRpc
base.OnDisconnected(e);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="id"></param>
/// <param name="channel"></param>
/// <returns></returns>
public bool TrySubscribeChannel(int id, out Channel channel)
{
return this.m_rpcActor.TrySubscribeChannel(id, out channel);
}
#region 内部委托绑定
private MethodInstance GetInvokeMethod(string arg)
......
......@@ -55,13 +55,11 @@ namespace TouchSocket.Rpc.TouchRpc
this.m_rpcActorGroup.OutputSend = this.RpcServiceOutputSend;
}
#region 字段
private readonly ActionMap m_actionMap;
private RpcActorGroup m_rpcActorGroup;
private RpcStore m_rpcStore;
private readonly ActionMap m_actionMap;
#endregion 字段
......@@ -91,17 +89,6 @@ namespace TouchSocket.Rpc.TouchRpc
base.ResetID(oldID, newID);
}
/// <summary>
/// 客户端请求连接
/// </summary>
/// <param name="socketClient"></param>
/// <param name="e"></param>
protected override void OnConnecting(TClient socketClient, ClientOperationEventArgs e)
{
socketClient.internalOnRpcActorInit = this.PrivateOnRpcActorInit;
base.OnConnecting(socketClient, e);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
......@@ -120,6 +107,17 @@ namespace TouchSocket.Rpc.TouchRpc
}
}
/// <summary>
/// 客户端请求连接
/// </summary>
/// <param name="socketClient"></param>
/// <param name="e"></param>
protected override void OnConnecting(TClient socketClient, ClientOperationEventArgs e)
{
socketClient.internalOnRpcActorInit = this.PrivateOnRpcActorInit;
base.OnConnecting(socketClient, e);
}
#region 事件
/// <summary>
......
......@@ -118,18 +118,6 @@ namespace TouchSocket.Rpc.TouchRpc
/// <param name="timeout"></param>
/// <returns></returns>
public override ITcpClient Connect(int timeout = 5000)
{
return this.Connect(null, default, timeout);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="metadata"></param>
/// <param name="token"></param>
/// <param name="timeout"></param>
/// <returns></returns>
public virtual ITcpClient Connect(Metadata metadata = null, CancellationToken token = default, int timeout = 5000)
{
if (this.IsHandshaked)
{
......@@ -140,25 +128,11 @@ namespace TouchSocket.Rpc.TouchRpc
base.Connect(timeout);
}
this.m_rpcActor.Handshake(this.Config.GetValue<string>(TouchRpcConfigExtensions.VerifyTokenProperty), token, timeout, metadata);
this.m_rpcActor.Handshake(this.Config.GetValue<string>(TouchRpcConfigExtensions.VerifyTokenProperty), default,
timeout, this.Config.GetValue<Metadata>(TouchRpcConfigExtensions.MetadataProperty));
return this;
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="metadata"></param>
/// <param name="token"></param>
/// <param name="timeout"></param>
/// <returns></returns>
public virtual Task<ITcpClient> ConnectAsync(Metadata metadata = null, CancellationToken token = default, int timeout = 5000)
{
return Task.Run(() =>
{
return this.Connect(metadata, token, timeout);
});
}
/// <summary>
/// <inheritdoc/>
/// </summary>
......
......@@ -54,12 +54,11 @@ namespace TouchSocket.Rpc.TouchRpc
this.m_rpcActorGroup.OutputSend = this.RpcServiceOutputSend;
}
#region 字段
private readonly ActionMap m_actionMap;
private RpcActorGroup m_rpcActorGroup;
private RpcStore m_rpcStore;
private readonly ActionMap m_actionMap;
#endregion 字段
......@@ -68,7 +67,6 @@ namespace TouchSocket.Rpc.TouchRpc
/// </summary>
public ActionMap ActionMap { get => m_actionMap; }
/// <summary>
/// <inheritdoc/>
/// </summary>
......@@ -90,17 +88,6 @@ namespace TouchSocket.Rpc.TouchRpc
base.ResetID(oldID, newID);
}
/// <summary>
/// 客户端请求连接
/// </summary>
/// <param name="socketClient"></param>
/// <param name="e"></param>
protected override void OnConnecting(TClient socketClient, ClientOperationEventArgs e)
{
socketClient.m_rpcActor = this.m_rpcActorGroup.CreateRpcActor(socketClient);
base.OnConnecting(socketClient, e);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
......@@ -119,6 +106,17 @@ namespace TouchSocket.Rpc.TouchRpc
}
}
/// <summary>
/// 客户端请求连接
/// </summary>
/// <param name="socketClient"></param>
/// <param name="e"></param>
protected override void OnConnecting(TClient socketClient, ClientOperationEventArgs e)
{
socketClient.m_rpcActor = this.m_rpcActorGroup.CreateRpcActor(socketClient);
base.OnConnecting(socketClient, e);
}
#region 事件
/// <summary>
......
......@@ -10,6 +10,7 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using TouchSocket.Core;
using TouchSocket.Core.Config;
using TouchSocket.Core.Dependency;
......@@ -45,9 +46,15 @@ namespace TouchSocket.Rpc.TouchRpc
public static readonly DependencyProperty VerifyTokenProperty =
DependencyProperty.Register("VerifyToken", typeof(string), typeof(TouchRpcConfigExtensions), "rrqm");
/// <summary>
/// TouchClient连接时的元数据, 所需类型<see cref="Metadata"/>
/// </summary>
public static readonly DependencyProperty MetadataProperty =
DependencyProperty.Register("Metadata", typeof(Metadata), typeof(TouchRpcConfigExtensions), null);
/// <summary>
/// 心跳频率,默认为间隔2000ms,3次。(设置为null时禁止心跳)
/// <para>仅适用于<see cref="TcpTouchRpcClient"/>及派生类</para>
/// <para>仅适用于TouchRpcClient系类</para>
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
......@@ -58,6 +65,19 @@ namespace TouchSocket.Rpc.TouchRpc
return config;
}
/// <summary>
/// 设置TouchClient连接时的元数据
/// <para>仅适用于TouchRpcClient系类</para>
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig SetMetadata(this TouchSocketConfig config, Metadata value)
{
config.SetValue(MetadataProperty, value);
return config;
}
/// <summary>
/// 设置序列化转换器
/// </summary>
......@@ -71,7 +91,8 @@ namespace TouchSocket.Rpc.TouchRpc
}
/// <summary>
/// 验证超时时间,默认为3000ms
/// 验证超时时间,默认为3000ms.
/// <para>该配置仅<see cref="TcpTouchRpcService"/>有效</para>
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
......
......@@ -13,6 +13,7 @@
using System.IO;
using TouchSocket.Core.IO;
using TouchSocket.Core.Serialization;
using TouchSocket.Core.XREF.Newtonsoft.Json;
namespace TouchSocket.Rpc.TouchRpc
{
......@@ -60,7 +61,7 @@ namespace TouchSocket.Rpc.TouchRpc
try
{
FileInfo fileInfo = new FileInfo(filePath);
TouchRpcFileInfo tempInfo = SerializeConvert.XmlDeserializeFromFile<TouchRpcFileInfo>(tempPath);
TouchRpcFileInfo tempInfo = JsonConvert.DeserializeObject<TouchRpcFileInfo>(File.ReadAllText(tempPath));
if (tempInfo.MD5 == info.MD5 && tempInfo.FileLength == info.FileLength)
{
info.Position = tempInfo.Position;
......
......@@ -13,44 +13,18 @@
using System;
using System.IO;
using System.Threading;
/* 项目“TouchSocketPro (net5)”的未合并的更改
在此之前:
using System;
using System.IO;
在此之后:
using TouchSocket.Core;
using TouchSocket.Core.IO;
*/
/* 项目“TouchSocketPro (netcoreapp3.1)”的未合并的更改
在此之前:
using System;
using System.IO;
在此之后:
using TouchSocket.Core;
using TouchSocket.Core.Extensions;
using TouchSocket.Core.IO;
*/
/* 项目“TouchSocketPro (netstandard2.0)”的未合并的更改
在此之前:
using System;
using System.IO;
在此之后:
using TouchSocket.Core;
using TouchSocket.Core.IO;
*/
using TouchSocket.Core.IO;
using TouchSocket.Core.Serialization;
namespace TouchSocket.Rpc.TouchRpc
{
/// <summary>
/// 文件流
/// </summary>
internal class TouchRpcFileStream : TouchSocket.Core.DisposableObject
internal class TouchRpcFileStream : DisposableObject
{
private static int saveInterval = 1000;
private static int m_saveInterval = 1000;
private TouchRpcFileInfo m_fileInfo;
......@@ -60,11 +34,11 @@ namespace TouchSocket.Rpc.TouchRpc
private bool m_resume;
private FileStorageWriter fileWriter;
private FileStorageWriter m_fileWriter;
protected override void Dispose(bool disposing)
{
this.fileWriter.SafeDispose();
this.m_fileWriter.SafeDispose();
base.Dispose(disposing);
}
......@@ -73,25 +47,25 @@ namespace TouchSocket.Rpc.TouchRpc
/// </summary>
public static int SaveInterval
{
get => saveInterval;
get => m_saveInterval;
set
{
if (value < 0)
{
value = 0;
}
saveInterval = value;
m_saveInterval = value;
}
}
public FileStorageWriter FileWriter => this.fileWriter;
public FileStorageWriter FileWriter => this.m_fileWriter;
public static TouchRpcFileStream Create(string path, ref TouchRpcFileInfo fileInfo, bool resume)
{
TouchRpcFileStream stream = new TouchRpcFileStream();
FileTool.TryReadTempInfo(path, ref fileInfo);
stream.fileWriter = FilePool.GetWriter(path + ".rrqm", true);
stream.fileWriter.Position = fileInfo.Position;
stream.m_fileWriter = FilePool.GetWriter(path + ".rrqm", true);
stream.m_fileWriter.Position = fileInfo.Position;
stream.m_fileInfo = fileInfo;
stream.m_path = path;
stream.m_resume = resume;
......@@ -100,13 +74,13 @@ namespace TouchSocket.Rpc.TouchRpc
public void Write(byte[] buffer, int offset, int length)
{
this.fileWriter.Write(buffer, offset, length);
this.m_fileWriter.Write(buffer, offset, length);
this.SaveProgress();
}
public void FinishStream()
{
if (this.fileWriter.Position != this.m_fileInfo.FileLength)
if (this.m_fileWriter.Position != this.m_fileInfo.FileLength)
{
throw new Exception("已完成传输,但是文件长度不对。");
}
......@@ -114,7 +88,7 @@ namespace TouchSocket.Rpc.TouchRpc
{
File.Delete(this.m_path);
}
this.fileWriter.SafeDispose();
this.m_fileWriter.SafeDispose();
string rrqmPath = this.m_path + ".rrqm";
string tempPath = this.m_path + ".temp";
......@@ -145,11 +119,11 @@ namespace TouchSocket.Rpc.TouchRpc
{
if (this.m_resume)
{
if (DateTime.Now.TimeOfDay - this.m_lastTime > TimeSpan.FromMilliseconds(saveInterval))
if (DateTime.Now.TimeOfDay - this.m_lastTime > TimeSpan.FromMilliseconds(m_saveInterval))
{
try
{
SerializeConvert.XmlSerializeToFile(this.m_fileInfo, this.m_path + ".temp");
File.WriteAllText(this.m_path + ".temp", this.m_fileInfo.ToJsonString());
this.m_lastTime = DateTime.Now.TimeOfDay;
}
catch
......
......@@ -23,23 +23,6 @@ namespace TouchSocket.Rpc.TouchRpc
/// </summary>
public interface IHttpTouchRpcClient : IHttpClient, IHttpRpcClientBase, IRpcParser
{
/// <summary>
/// 连接
/// </summary>
/// <param name="metadata">元数据</param>
/// <param name="token">可取消操作令箭</param>
/// <param name="timeout">验证超时时间</param>
/// <returns></returns>
ITcpClient Connect(Metadata metadata = null, CancellationToken token = default, int timeout = 5000);
/// <summary>
/// 异步连接
/// </summary>
/// <param name="metadata">元数据</param>
/// <param name="token">可取消操作令箭</param>
/// <param name="timeout">验证超时时间</param>
/// <returns></returns>
Task<ITcpClient> ConnectAsync(Metadata metadata = null, CancellationToken token = default, int timeout = 5000);
}
/// <summary>
......
......@@ -23,23 +23,6 @@ namespace TouchSocket.Rpc.TouchRpc
/// </summary>
public interface ITcpTouchRpcClient : ITcpRpcClientBase, ITcpClient, IRpcParser
{
/// <summary>
/// 连接
/// </summary>
/// <param name="metadata">元数据</param>
/// <param name="token">可取消操作令箭</param>
/// <param name="timeout">验证超时时间</param>
/// <returns></returns>
ITcpClient Connect(Metadata metadata = null, CancellationToken token = default, int timeout = 5000);
/// <summary>
/// 异步连接
/// </summary>
/// <param name="metadata">元数据</param>
/// <param name="token">可取消操作令箭</param>
/// <param name="timeout">验证超时时间</param>
/// <returns></returns>
Task<ITcpClient> ConnectAsync(Metadata metadata = null, CancellationToken token = default, int timeout = 5000);
}
/// <summary>
......
......@@ -38,9 +38,9 @@ namespace TouchSocket.Rpc.TouchRpc
}
switch (serializationType)
{
case SerializationType.RRQMBinary:
case SerializationType.FastBinary:
{
return SerializeConvert.RRQMBinaryDeserialize(parameterBytes, 0, parameterType);
return SerializeConvert.FastBinaryDeserialize(parameterBytes, 0, parameterType);
}
case SerializationType.Json:
{
......@@ -69,9 +69,9 @@ namespace TouchSocket.Rpc.TouchRpc
}
switch (serializationType)
{
case SerializationType.RRQMBinary:
case SerializationType.FastBinary:
{
return SerializeConvert.RRQMBinarySerialize(parameter);
return SerializeConvert.FastBinarySerialize(parameter);
}
case SerializationType.Json:
{
......
......@@ -52,7 +52,7 @@ namespace TouchSocket.Rpc.TouchRpc
/// <summary>
/// 最大传输速度(企业版默认1024*1024字节,开源版不限速,所以此值无效。)
/// </summary>
public int MaxSpeed => int.MaxValue;
public int MaxSpeed =>int.MaxValue;
/// <summary>
/// 超时时间,默认10*1000ms。
......
......@@ -27,9 +27,10 @@ namespace TouchSocket.Rpc.WebApi
/// </summary>
public class WebApiParserPlugin : HttpPluginBase, IRpcParser
{
private readonly StringConverter m_converter;
private readonly ActionMap m_actionMap;
private readonly StringConverter m_converter;
private RpcStore m_rpcStore;
/// <summary>
/// 构造函数
/// </summary>
......@@ -326,6 +327,7 @@ namespace TouchSocket.Rpc.WebApi
{
this.m_rpcStore = rpcService;
}
#endregion RPC解析器
}
}
\ No newline at end of file
......@@ -335,6 +335,10 @@ namespace TouchSocket.Sockets
/// <param name="how"></param>
public void Shutdown(SocketShutdown how)
{
if (this.m_mainSocket == null)
{
return;
}
this.m_mainSocket.Shutdown(how);
}
......
......@@ -44,7 +44,7 @@ public delegate void ClientConnectingEventHandler<TClient>(TClient client, Clien
/// <typeparam name="TClient"></typeparam>
/// <param name="client"></param>
/// <param name="e"></param>
public delegate void ClientDisconnectedEventHandler<TClient>(TClient client, ClientDisconnectedEventArgs e);
public delegate void ClientDisconnectedEventHandler<TClient>(TClient client, ClientDisconnectedEventArgs e);
/// <summary>
/// 正在连接事件
......
......@@ -24,20 +24,6 @@ namespace TouchSocket.Sockets
/// </summary>
public static class ClientExtension
{
/// <summary>
/// 使用断线重连。
/// </summary>
/// <param name="client">客户端</param>
/// <param name="successCallback">成功回调函数</param>
/// <param name="tryCount">尝试重连次数,设为-1时则永远尝试连接</param>
/// <param name="printLog">是否输出日志。</param>
/// <param name="sleepTime">失败时,停留时间</param>
public static T UseReconnection<T>(this T client, int tryCount = 10, bool printLog = false, int sleepTime = 1000, Action<T> successCallback = null) where T : ITcpClient, IPlguinObject
{
client.PluginsManager.Add(new ReconnectionPlugin<T>(tryCount, printLog, sleepTime, successCallback));
return client;
}
/// <summary>
/// 获取相关信息。格式:
///<para>IPPort=IP:Port,ID=id,Protocol=Protocol</para>
......@@ -60,6 +46,10 @@ namespace TouchSocket.Sockets
{
try
{
if (client==null||!client.Online)
{
return;
}
client.Shutdown(how);
}
catch
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace TouchSocket.Sockets
{
/// <summary>
/// 客户端发送接口
/// </summary>
public interface IClientSender : ISend
{
/// <summary>
/// 同步组合发送数据。
/// <para>内部已经封装Ssl和发送长度检测,即:调用完成即表示数据全部发送完毕。</para>
/// <para>该发送会经过适配器封装,具体封装内容由适配器决定。</para>
/// </summary>
/// <param name="transferBytes">组合数据</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void Send(IList<TransferByte> transferBytes);
/// <summary>
/// 异步组合发送数据。
/// <para>在<see cref="ITcpClient"/>时,如果使用独立线程发送,则不会触发异常。</para>
/// <para>在<see cref="ITcpClientBase"/>时,相当于<see cref="Socket.BeginSend(byte[], int, int, SocketFlags, out SocketError, System.AsyncCallback, object)"/>。</para>
/// <para>该发送会经过适配器封装,具体封装内容由适配器决定。</para>
/// </summary>
/// <param name="transferBytes">组合数据</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void SendAsync(IList<TransferByte> transferBytes);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core.ByteManager;
namespace TouchSocket.Sockets
{
/// <summary>
/// 具有直接发送功能
/// </summary>
public interface IDefaultSender : ISendBase
{
#region 默认发送
/// <summary>
/// 绕过适配器,直接发送字节流
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <param name="offset">偏移量</param>
/// <param name="length">数据长度</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void DefaultSend(byte[] buffer, int offset, int length);
/// <summary>
/// 绕过适配器,直接发送字节流
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void DefaultSend(byte[] buffer);
/// <summary>
/// 绕过适配器,直接发送字节流
/// </summary>
/// <param name="byteBlock">数据块载体</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void DefaultSend(ByteBlock byteBlock);
#endregion
#region 默认发送
/// <summary>
/// 绕过适配器,直接发送字节流
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <param name="offset">偏移量</param>
/// <param name="length">数据长度</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void DefaultSendAsync(byte[] buffer, int offset, int length);
/// <summary>
/// 绕过适配器,直接发送字节流
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void DefaultSendAsync(byte[] buffer);
/// <summary>
/// 绕过适配器,直接发送字节流
/// </summary>
/// <param name="byteBlock">数据块载体</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void DefaultSendAsync(ByteBlock byteBlock);
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core.ByteManager;
namespace TouchSocket.Sockets
{
/// <summary>
/// 通过ID发送
/// </summary>
public interface IIDSender
{
/// <summary>
/// 向对应ID的客户端发送
/// </summary>
/// <param name="id">目标ID</param>
/// <param name="buffer">数据</param>
/// <param name="offset">偏移</param>
/// <param name="length">长度</param>
/// <exception cref="NotConnectedException">未连接异常</exception>
/// <exception cref="ClientNotFindException">未找到ID对应的客户端</exception>
/// <exception cref="Exception">其他异常</exception>
void Send(string id, byte[] buffer, int offset, int length);
/// <summary>
/// 向对应ID的客户端发送
/// </summary>
/// <param name="id">目标ID</param>
/// <param name="buffer">数据</param>
/// <exception cref="NotConnectedException">未连接异常</exception>
/// <exception cref="ClientNotFindException">未找到ID对应的客户端</exception>
/// <exception cref="Exception">其他异常</exception>
void Send(string id, byte[] buffer);
/// <summary>
/// 向对应ID的客户端发送
/// </summary>
/// <param name="id">目标ID</param>
/// <param name="byteBlock">数据</param>
/// <exception cref="NotConnectedException">未连接异常</exception>
/// <exception cref="ClientNotFindException">未找到ID对应的客户端</exception>
/// <exception cref="Exception">其他异常</exception>
void Send(string id, ByteBlock byteBlock);
/// <summary>
/// 向对应ID的客户端发送
/// </summary>
/// <param name="id">目标ID</param>
/// <param name="buffer">数据</param>
/// <param name="offset">偏移</param>
/// <param name="length">长度</param>
/// <exception cref="NotConnectedException">未连接异常</exception>
/// <exception cref="ClientNotFindException">未找到ID对应的客户端</exception>
/// <exception cref="Exception">其他异常</exception>
void SendAsync(string id, byte[] buffer, int offset, int length);
/// <summary>
/// 向对应ID的客户端发送
/// </summary>
/// <param name="id">目标ID</param>
/// <param name="buffer">数据</param>
/// <exception cref="NotConnectedException">未连接异常</exception>
/// <exception cref="ClientNotFindException">未找到ID对应的客户端</exception>
/// <exception cref="Exception">其他异常</exception>
void SendAsync(string id, byte[] buffer);
/// <summary>
/// 向对应ID的客户端发送
/// </summary>
/// <param name="id">目标ID</param>
/// <param name="byteBlock">数据</param>
/// <exception cref="NotConnectedException">未连接异常</exception>
/// <exception cref="ClientNotFindException">未找到ID对应的客户端</exception>
/// <exception cref="Exception">其他异常</exception>
void SendAsync(string id, ByteBlock byteBlock);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core.ByteManager;
namespace TouchSocket.Sockets
{
/// <summary>
/// 具有发送功能的接口
/// </summary>
public interface ISend : ISendBase
{
/// <summary>
/// 同步发送数据。
/// <para>内部已经封装Ssl和发送长度检测,即:调用完成即表示数据全部发送完毕。</para>
/// <para>该发送会经过适配器封装,具体封装内容由适配器决定。</para>
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <param name="offset">偏移量</param>
/// <param name="length">数据长度</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void Send(byte[] buffer, int offset, int length);
/// <summary>
/// 同步发送数据。
/// <para>内部已经封装Ssl和发送长度检测,即:调用完成即表示数据全部发送完毕。</para>
/// <para>该发送会经过适配器封装,具体封装内容由适配器决定。</para>
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void Send(byte[] buffer);
/// <summary>
/// 同步发送数据。
/// <para>内部已经封装Ssl和发送长度检测,即:调用完成即表示数据全部发送完毕。</para>
/// <para>该发送会经过适配器封装,具体封装内容由适配器决定。</para>
/// </summary>
/// <param name="byteBlock">数据块</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void Send(ByteBlock byteBlock);
/// <summary>
/// 异步发送数据。
/// <para>在<see cref="ITcpClient"/>时,如果使用独立线程发送,则不会触发异常。</para>
/// <para>在<see cref="ITcpClientBase"/>时,相当于<see cref="Socket.BeginSend(byte[], int, int, SocketFlags, out SocketError, System.AsyncCallback, object)"/>。</para>
/// <para>该发送会经过适配器封装,具体封装内容由适配器决定。</para>
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <param name="offset">偏移量</param>
/// <param name="length">数据长度</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void SendAsync(byte[] buffer, int offset, int length);
/// <summary>
/// 异步发送数据。
/// <para>在<see cref="ITcpClient"/>时,如果使用独立线程发送,则不会触发异常。</para>
/// <para>在<see cref="ITcpClientBase"/>时,相当于<see cref="Socket.BeginSend(byte[], int, int, SocketFlags, out SocketError, System.AsyncCallback, object)"/>。</para>
/// <para>该发送会经过适配器封装,具体封装内容由适配器决定。</para>
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void SendAsync(byte[] buffer);
/// <summary>
/// 异步发送数据。
/// <para>在<see cref="ITcpClient"/>时,如果使用独立线程发送,则不会触发异常。</para>
/// <para>在<see cref="ITcpClientBase"/>时,相当于<see cref="Socket.BeginSend(byte[], int, int, SocketFlags, out SocketError, System.AsyncCallback, object)"/>。</para>
/// <para>该发送会经过适配器封装,具体封装内容由适配器决定。</para>
/// </summary>
/// <param name="byteBlock">数据块</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void SendAsync(ByteBlock byteBlock);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TouchSocket.Sockets
{
/// <summary>
/// 具有发送动作的基类。
/// </summary>
public interface ISendBase
{
/// <summary>
/// 表示对象能否顺利执行发送操作。
/// <para>由于高并发,当改值为Tru时,也不一定完全能执行。</para>
/// </summary>
bool CanSend { get; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace TouchSocket.Sockets
{
/// <summary>
/// 具有Udp终结点的发送
/// </summary>
public interface IUdpClientSender : ISend
{
/// <summary>
/// 同步组合发送数据。
/// <para>内部已经封装Ssl和发送长度检测,即:调用完成即表示数据全部发送完毕。</para>
/// <para>该发送会经过适配器封装,具体封装内容由适配器决定。</para>
/// </summary>
/// <param name="endPoint">远程终结点</param>
/// <param name="transferBytes">组合数据</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void Send(EndPoint endPoint, IList<TransferByte> transferBytes);
/// <summary>
/// 异步组合发送数据。
/// <para>在<see cref="ITcpClient"/>时,如果使用独立线程发送,则不会触发异常。</para>
/// <para>在<see cref="ITcpClientBase"/>时,相当于<see cref="Socket.BeginSend(byte[], int, int, SocketFlags, out SocketError, System.AsyncCallback, object)"/>。</para>
/// <para>该发送会经过适配器封装,具体封装内容由适配器决定。</para>
/// </summary>
/// <param name="endPoint">远程终结点</param>
/// <param name="transferBytes">组合数据</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void SendAsync(EndPoint endPoint, IList<TransferByte> transferBytes);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core.ByteManager;
namespace TouchSocket.Sockets
{
/// <summary>
/// 具有直接发送功能
/// </summary>
public interface IUdpDefaultSender : ISendBase
{
#region 默认发送
/// <summary>
/// 绕过适配器,直接发送字节流
/// </summary>
/// <param name="endPoint">目的终结点</param>
/// <param name="buffer">数据缓存区</param>
/// <param name="offset">偏移量</param>
/// <param name="length">数据长度</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void DefaultSend(EndPoint endPoint, byte[] buffer, int offset, int length);
/// <summary>
/// 绕过适配器,直接发送字节流
/// </summary>
/// <param name="endPoint">目的终结点</param>
/// <param name="buffer">数据缓存区</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void DefaultSend(EndPoint endPoint, byte[] buffer);
/// <summary>
/// 绕过适配器,直接发送字节流
/// </summary>
/// <param name="endPoint">目的终结点</param>
/// <param name="byteBlock">数据块载体</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void DefaultSend(EndPoint endPoint, ByteBlock byteBlock);
#endregion
#region 默认发送
/// <summary>
/// 绕过适配器,直接发送字节流
/// </summary>
/// <param name="endPoint">目的终结点</param>
/// <param name="buffer">数据缓存区</param>
/// <param name="offset">偏移量</param>
/// <param name="length">数据长度</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void DefaultSendAsync(EndPoint endPoint, byte[] buffer, int offset, int length);
/// <summary>
/// 绕过适配器,直接发送字节流
/// </summary>
/// <param name="endPoint">目的终结点</param>
/// <param name="buffer">数据缓存区</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void DefaultSendAsync(EndPoint endPoint, byte[] buffer);
/// <summary>
/// 绕过适配器,直接发送字节流
/// </summary>
/// <param name="endPoint">目的终结点</param>
/// <param name="byteBlock">数据块载体</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
void DefaultSendAsync(EndPoint endPoint, ByteBlock byteBlock);
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TouchSocket.Core.ByteManager;
namespace TouchSocket.Sockets
{
/// <summary>
/// 发送等待接口
/// </summary>
public interface IWaitSender : ISendBase
{
/// <summary>
/// 发送字节流
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <param name="offset">偏移</param>
/// <param name="length">长度</param>
/// <param name="timeout">超时时间</param>
/// <param name="token">取消令箭</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
/// <returns>返回的数据</returns>
byte[] SendThenReturn(byte[] buffer, int offset, int length, int timeout = 1000 * 5, CancellationToken token = default);
/// <summary>
/// 发送字节流
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <param name="timeout">超时时间</param>
/// <param name="token">取消令箭</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
/// <returns>返回的数据</returns>
byte[] SendThenReturn(byte[] buffer, int timeout = 1000 * 5, CancellationToken token = default);
/// <summary>
/// 发送流中的有效数据
/// </summary>
/// <param name="byteBlock">数据块载体</param>
/// <param name="timeout">超时时间</param>
/// <param name="token">取消令箭</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
/// <returns>返回的数据</returns>
byte[] SendThenReturn(ByteBlock byteBlock, int timeout = 1000 * 5, CancellationToken token = default);
/// <summary>
/// 异步发送
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <param name="offset">偏移</param>
/// <param name="length">长度</param>
/// <param name="timeout">超时时间</param>
/// <param name="token">取消令箭</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
/// <returns>返回的数据</returns>
Task<byte[]> SendThenReturnAsync(byte[] buffer, int offset, int length, int timeout = 1000 * 5, CancellationToken token = default);
/// <summary>
/// 异步发送
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <param name="timeout">超时时间</param>
/// <param name="token">取消令箭</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
/// <returns>返回的数据</returns>
Task<byte[]> SendThenReturnAsync(byte[] buffer, int timeout = 1000 * 5, CancellationToken token = default);
/// <summary>
/// 异步发送
/// </summary>
/// <param name="byteBlock">数据块载体</param>
/// <param name="timeout">超时时间</param>
/// <param name="token">取消令箭</param>
/// <exception cref="NotConnectedException">客户端没有连接</exception>
/// <exception cref="OverlengthException">发送数据超长</exception>
/// <exception cref="Exception">其他异常</exception>
/// <returns>返回的数据</returns>
Task<byte[]> SendThenReturnAsync(ByteBlock byteBlock, int timeout = 1000 * 5, CancellationToken token = default);
}
}
......@@ -4,7 +4,7 @@
<ApplicationIcon>logo.ico</ApplicationIcon>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>RRQM.pfx</AssemblyOriginatorKeyFile>
<Version>0.1.4</Version>
<Version>0.2.0</Version>
<LangVersion>8.0</LangVersion>
<Company>若汝棋茗</Company>
<Copyright>Copyright © 2022 若汝棋茗</Copyright>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册