Commit 2afb984e authored by 潘栩锋's avatar 潘栩锋 🚴

1.修复 WebSocketClient 的 IsConnected 与 Reflect_SeviceClient 的 IsConnected…

1.修复 WebSocketClient 的 IsConnected 与 Reflect_SeviceClient 的 IsConnected 不相同。导致关闭时,Reflect_SeviceClient.IsConnected 没有被设置=false
parent dd2729a2
......@@ -28,6 +28,7 @@
<Compile Include="..\WSCF\IReflectSeviceClientCore.cs" Link="IReflectSeviceClientCore.cs" />
<Compile Include="..\WSCF\WsServiceProxy.cs" Link="WsServiceProxy.cs" />
<Compile Include="..\WSCF\WsServiceClient.cs" Link="WsServiceClient.cs" />
<Compile Include="..\WSCF\ReflectSeviceClientAssistant.cs" Link="ReflectSeviceClientAssistant.cs" />
</ItemGroup>
<ItemGroup>
......
......@@ -27,460 +27,5 @@ namespace WSCF
bool IsInPushValue { get; set; }
}
class ReflectSeviceClientAssistant: IDisposable
{
public event PropertyChangedEventHandler PropertyChanged;
#region Core
/// <summary>
/// 忽略设置
/// </summary>
public bool ignoreSet;
/// <summary>
/// 对象的接口类型
/// </summary>
Type interfaceType;
/// <summary>
/// 代理对象
/// </summary>
IReflectSeviceClientCore obj;
class AnyEvent
{
public string name;
public string triggerName;
public Type retType;
}
class AnyCall
{
public string name;
public Type retType;
}
List<AnyEvent> anyEvents = new List<AnyEvent>();
List<AnyCall> anyCalls = new List<AnyCall>();
SubPropertyNode rootNode;
List<string> properties = new List<string>();
/// <summary>
/// 缓存 发出 CALL_GetAllProperties指令,到收到回复 之间时段的 全部推送
/// </summary>
List<PushInfoData> pushInfoList = new List<PushInfoData>();
class PushInfoData
{
public bool isPushPropertyChanged;
public ReflectData rData;
}
#endregion
/// <summary>
/// 服务名称
/// </summary>
string ServiceName;
/// <summary>
/// 发送 数据 到 服务
/// </summary>
Action<string> SendEx;
class AnyMethodInvoke
{
public string guid;
public AsyncCBHandler asyncDelegate;
public object asyncContext;
}
List<AnyMethodInvoke> anyMethodInvokes = new List<AnyMethodInvoke>();
public void SetSendEx(Action<string> sendEx, string serviceName)
{
this.ServiceName = serviceName;
this.SendEx = sendEx;
}
public ReflectSeviceClientAssistant()
{
}
public void Init(Type interfaceType, IReflectSeviceClientCore obj)
{
if (interfaceType == null)
throw new Exception($"ServiceClient 写错了, {obj.GetType()} 没有 赋值 InterfaceType");
this.interfaceType = interfaceType;
this.obj = obj;
init();
}
#region Core
void init()
{
rootNode = new SubPropertyNode
{
Obj = obj,
InterfaceType = interfaceType,
SubPropertyChanged = Sub_PropertyChanged
};
//注册 obj 的PropertyChanged 事件,获取 interfaceType 全部属性名称,包括它的父类的全部属性名称
COMMON.InitPropertyChanged(interfaceType, obj, rootNode, properties);
//处理[PropertyPush]
COMMON.InitPropertyPush(rootNode);
InitEventPush();
InitCall();
obj.PropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(obj.IsConnected))
{
if (obj.IsConnected == false)
{
obj.IsSynced = false;
pushInfoList.Clear();
}
}
};
}
void InitEventPush()
{
var interfaceTypes = new List<Type>();
interfaceTypes.Add(interfaceType);
interfaceTypes.AddRange(interfaceType.GetInterfaces());
var eventInfos = new List<EventInfo>();
foreach (var ifaceType in interfaceTypes)
{
eventInfos.AddRange(ifaceType.GetEvents());
}
foreach (var eventInfo in eventInfos)
{
var pushAttribute = eventInfo.GetCustomAttribute<PushAttribute>();
if (pushAttribute == null)
continue;
if (anyEvents.Any(ae => ae.name == eventInfo.Name))
continue;//已经添加了
string triggerName;
if (string.IsNullOrEmpty(pushAttribute.TriggerName))
{
triggerName = PushAttribute.DefaultTriggerNameHeader + eventInfo.Name;
}
else
{
triggerName = pushAttribute.TriggerName;
}
var anyEvent = new AnyEvent()
{
name = eventInfo.Name,
triggerName = triggerName,
retType = pushAttribute.EventArgsType
};
anyEvents.Add(anyEvent);
}
}
void InitCall()
{
var interfaceTypes = new List<Type>();
interfaceTypes.Add(interfaceType);
interfaceTypes.AddRange(interfaceType.GetInterfaces());
var methodInfos = new List<MethodInfo>();
foreach (var ifaceType in interfaceTypes)
{
methodInfos.AddRange(ifaceType.GetMethods());
}
foreach (var methodInfo in methodInfos)
{
var callAttribute = methodInfo.GetCustomAttribute<CallAttribute>();
if (callAttribute == null)
continue;
if (anyCalls.Any(ae => ae.name == methodInfo.Name))
continue;//已经添加了
var anyCall = new AnyCall()
{
name = methodInfo.Name,
retType = callAttribute.ReponseType
};
anyCalls.Add(anyCall);
}
}
private void Sub_PropertyChanged(SubPropertyNode node, PropertyChangedEventArgs e)
{
if (!obj.IsConnected)
return;
if (ignoreSet)//从服务器接收的数据,不用再推送给服务器
return;
var rData = COMMON.Sub_PropertyChanged(node, e, rootNode, properties);
if (rData == null)
return;
send_CALL_SetProperty(rData);
}
public void Dispose()
{
if (typeof(INotifyPropertyChanged).IsAssignableFrom(interfaceType))
{
//继承了INotifyPropertyChanged
obj.PropertyChanged -= rootNode.PropertyChanged;
}
//释放subProperties
COMMON.NodeDispose(rootNode);
}
public void Call(string methodName, object parameters, AsyncCBHandler asyncDelegate, object asyncContext)
{
var rData = new ReflectData()
{
name = methodName,
data = parameters == null ? null : JObject.FromObject(parameters)
};
send_CALL_MethodInvoke(rData, asyncDelegate, asyncContext);
}
/// <summary>
/// 处理 从服务器 回复的 CALL_GetAllProperties
/// </summary>
/// <param name="rData"></param>
void receive_CALL_GetAllProperties(ReflectData rData)
{
receive_PUSH_PropertyChanged(rData);
obj.IsSynced = true;
DealPushInfoList();
}
/// <summary>
/// 处理全部 缓存的推送数据
/// </summary>
void DealPushInfoList()
{
for (int i = 0; i < pushInfoList.Count(); i++)
{
var pushInfoData = pushInfoList[i];
if (pushInfoData.isPushPropertyChanged)
receive_PUSH_PropertyChanged(pushInfoData.rData);
else
receive_PUSH_Event(pushInfoData.rData);
}
pushInfoList.Clear();
}
/// <summary>
/// 处理 从服务器 回复的 PUSH_PropertyChanged
/// </summary>
/// <param name="rData"></param>
void receive_PUSH_PropertyChanged(ReflectData rData)
{
ignoreSet = true;
obj.IsInPushValue = true;
var node = COMMON.FindNode(rootNode, rData.name);
if (node == null)
{
//异常
//服务器乱发过来
return;
}
string json = rData.data.ToString();
JsonConvert.PopulateObject(json, node.Obj);
obj.IsInPushValue = false;
ignoreSet = false;
}
/// <summary>
/// 处理 从服务器 回复的 PUSH_Event
/// </summary>
/// <param name="rData"></param>
void receive_PUSH_Event(ReflectData rData)
{
var anyEvent = anyEvents.Find(ae => ae.name == rData.name);
if (anyEvent == null)
return;//异常!!!
//触发事件!!!
var methodInfo = this.obj.GetType().GetMethod(anyEvent.triggerName);
if (methodInfo == null)
{
throw new Exception($"客户端 {this.obj.GetType()} 忘记写 {anyEvent.triggerName}");
}
var obj = rData.data.ToObject(anyEvent.retType);
//出错,就提示,肯定是客户端忘记写 "Trigger_XXXX"
methodInfo.Invoke(this.obj, new object[] { obj });
}
/// <summary>
/// 处理 从服务器 回复的 CALL_MethodInvoke
/// </summary>
/// <param name="rData"></param>
/// <param name="asyncDelegate"></param>
/// <param name="asyncContext"></param>
void receive_CALL_MethodInvoke(ReflectData rData, AsyncCBHandler asyncDelegate, object asyncContext)
{
var anyCall = anyCalls.Find(ac => ac.name == rData.name);
if (anyCall == null)
{
//异常!!!应该有[Call]注明返回的类型
throw new Exception($"{rData.name} 异常!!!应该有[Call]注明返回的类型");
}
var retData = rData.data.ToObject(anyCall.retType);
asyncDelegate.Invoke(asyncContext, retData);
}
#endregion
/// <summary>
/// 发送 CALL_MethodInvoke 请求到服务
/// </summary>
/// <param name="rData"></param>
void send_CALL_MethodInvoke(ReflectData rData, AsyncCBHandler asyncDelegate, object asyncContext)
{
var pkgData = new PkgData(
ServiceName,
PkgName.CALL_MethodInvoke,
Guid.NewGuid().ToString(),
JToken.FromObject(rData)
);
anyMethodInvokes.Add(new AnyMethodInvoke()
{
guid = pkgData.guid,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
string json = JsonConvert.SerializeObject(pkgData);
SendEx(json);
}
/// <summary>
/// 发送 CALL_SetProperty 请求到服务
/// </summary>
/// <param name="rData"></param>
void send_CALL_SetProperty(ReflectData rData)
{
var pkgData = new PkgData(
ServiceName,
PkgName.CALL_SetProperty,
Guid.NewGuid().ToString(),
JToken.FromObject(rData)
);
string json = JsonConvert.SerializeObject(pkgData);
SendEx(json);
}
#region WsServiceSys 调用
/// <summary>
/// 第1次连接成功
/// </summary>
public void OnOpen()
{
obj.IsConnected = true;
//获取全部属性
var pkgData = new PkgData(
ServiceName,
PkgName.CALL_GetAllProperties,
Guid.NewGuid().ToString(),
null
);
string json = JsonConvert.SerializeObject(pkgData);
SendEx(json);
}
public void OnClose()
{
obj.IsConnected = false;
//Dispose();
}
public void OnMessage(PkgData pkgData)
{
var pkgName = (PkgName)Enum.Parse(typeof(PkgName), pkgData.name);
switch (pkgName)
{
case PkgName.PUSH_PropertyChanged:
case PkgName.PUSH_Event:
{
var rData = pkgData.data.ToObject<ReflectData>();
if (!obj.IsSynced)
{
//还没同步完成,先缓存
pushInfoList.Add(
new PushInfoData()
{
isPushPropertyChanged = pkgName == PkgName.PUSH_PropertyChanged,
rData = rData
});
return;
}
if (pkgName == PkgName.PUSH_PropertyChanged)
receive_PUSH_PropertyChanged(rData);
else
receive_PUSH_Event(rData);
}
break;
case PkgName.CALL_GetAllProperties:
{
var rData = pkgData.data.ToObject<ReflectData>();
receive_CALL_GetAllProperties(rData);
}
break;
case PkgName.CALL_MethodInvoke:
{
var reponse = pkgData.data.ToObject<ReflectData>();
var anyMethodInvoke = anyMethodInvokes.Find(ami => ami.guid == pkgData.guid);
if (anyMethodInvoke == null)
{
//异常!!!应该有对应的回调
throw new Exception($"{reponse.name} 异常!!!应该有回调");
}
receive_CALL_MethodInvoke(reponse, anyMethodInvoke.asyncDelegate, anyMethodInvoke.asyncContext);
anyMethodInvokes.Remove(anyMethodInvoke);
}
break;
}
}
#endregion
}
}
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using static WSCF.Reflect_OBJ_INTERFACE;
namespace WSCF
{
class ReflectSeviceClientAssistant : IDisposable
{
public event PropertyChangedEventHandler PropertyChanged;
#region Core
/// <summary>
/// 忽略设置
/// </summary>
public bool ignoreSet;
/// <summary>
/// 对象的接口类型
/// </summary>
Type interfaceType;
/// <summary>
/// 代理对象
/// </summary>
IReflectSeviceClientCore obj;
class AnyEvent
{
public string name;
public string triggerName;
public Type retType;
}
class AnyCall
{
public string name;
public Type retType;
}
List<AnyEvent> anyEvents = new List<AnyEvent>();
List<AnyCall> anyCalls = new List<AnyCall>();
SubPropertyNode rootNode;
List<string> properties = new List<string>();
/// <summary>
/// 缓存 发出 CALL_GetAllProperties指令,到收到回复 之间时段的 全部推送
/// </summary>
List<PushInfoData> pushInfoList = new List<PushInfoData>();
class PushInfoData
{
public bool isPushPropertyChanged;
public ReflectData rData;
}
#endregion
/// <summary>
/// 服务名称
/// </summary>
string ServiceName;
/// <summary>
/// 发送 数据 到 服务
/// </summary>
Action<string> SendEx;
class AnyMethodInvoke
{
public string guid;
public AsyncCBHandler asyncDelegate;
public object asyncContext;
}
List<AnyMethodInvoke> anyMethodInvokes = new List<AnyMethodInvoke>();
public void SetSendEx(Action<string> sendEx, string serviceName)
{
this.ServiceName = serviceName;
this.SendEx = sendEx;
}
public ReflectSeviceClientAssistant()
{
}
public void Init(Type interfaceType, IReflectSeviceClientCore obj)
{
if (interfaceType == null)
throw new Exception($"ServiceClient 写错了, {obj.GetType()} 没有 赋值 InterfaceType");
this.interfaceType = interfaceType;
this.obj = obj;
init();
}
#region Core
void init()
{
rootNode = new SubPropertyNode
{
Obj = obj,
InterfaceType = interfaceType,
SubPropertyChanged = Sub_PropertyChanged
};
//注册 obj 的PropertyChanged 事件,获取 interfaceType 全部属性名称,包括它的父类的全部属性名称
COMMON.InitPropertyChanged(interfaceType, obj, rootNode, properties);
//处理[PropertyPush]
COMMON.InitPropertyPush(rootNode);
InitEventPush();
InitCall();
obj.PropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(obj.IsConnected))
{
if (obj.IsConnected == false)
{
obj.IsSynced = false;
pushInfoList.Clear();
}
}
};
}
void InitEventPush()
{
var interfaceTypes = new List<Type>();
interfaceTypes.Add(interfaceType);
interfaceTypes.AddRange(interfaceType.GetInterfaces());
var eventInfos = new List<EventInfo>();
foreach (var ifaceType in interfaceTypes)
{
eventInfos.AddRange(ifaceType.GetEvents());
}
foreach (var eventInfo in eventInfos)
{
var pushAttribute = eventInfo.GetCustomAttribute<PushAttribute>();
if (pushAttribute == null)
continue;
if (anyEvents.Any(ae => ae.name == eventInfo.Name))
continue;//已经添加了
string triggerName;
if (string.IsNullOrEmpty(pushAttribute.TriggerName))
{
triggerName = PushAttribute.DefaultTriggerNameHeader + eventInfo.Name;
}
else
{
triggerName = pushAttribute.TriggerName;
}
var anyEvent = new AnyEvent()
{
name = eventInfo.Name,
triggerName = triggerName,
retType = pushAttribute.EventArgsType
};
anyEvents.Add(anyEvent);
}
}
void InitCall()
{
var interfaceTypes = new List<Type>();
interfaceTypes.Add(interfaceType);
interfaceTypes.AddRange(interfaceType.GetInterfaces());
var methodInfos = new List<MethodInfo>();
foreach (var ifaceType in interfaceTypes)
{
methodInfos.AddRange(ifaceType.GetMethods());
}
foreach (var methodInfo in methodInfos)
{
var callAttribute = methodInfo.GetCustomAttribute<CallAttribute>();
if (callAttribute == null)
continue;
if (anyCalls.Any(ae => ae.name == methodInfo.Name))
continue;//已经添加了
var anyCall = new AnyCall()
{
name = methodInfo.Name,
retType = callAttribute.ReponseType
};
anyCalls.Add(anyCall);
}
}
private void Sub_PropertyChanged(SubPropertyNode node, PropertyChangedEventArgs e)
{
if (!obj.IsConnected)
return;
if (ignoreSet)//从服务器接收的数据,不用再推送给服务器
return;
var rData = COMMON.Sub_PropertyChanged(node, e, rootNode, properties);
if (rData == null)
return;
send_CALL_SetProperty(rData);
}
public void Dispose()
{
if (typeof(INotifyPropertyChanged).IsAssignableFrom(interfaceType))
{
//继承了INotifyPropertyChanged
obj.PropertyChanged -= rootNode.PropertyChanged;
}
//释放subProperties
COMMON.NodeDispose(rootNode);
}
public void Call(string methodName, object parameters, AsyncCBHandler asyncDelegate, object asyncContext)
{
var rData = new ReflectData()
{
name = methodName,
data = parameters == null ? null : JObject.FromObject(parameters)
};
send_CALL_MethodInvoke(rData, asyncDelegate, asyncContext);
}
/// <summary>
/// 处理 从服务器 回复的 CALL_GetAllProperties
/// </summary>
/// <param name="rData"></param>
void receive_CALL_GetAllProperties(ReflectData rData)
{
receive_PUSH_PropertyChanged(rData);
obj.IsSynced = true;
DealPushInfoList();
}
/// <summary>
/// 处理全部 缓存的推送数据
/// </summary>
void DealPushInfoList()
{
for (int i = 0; i < pushInfoList.Count(); i++)
{
var pushInfoData = pushInfoList[i];
if (pushInfoData.isPushPropertyChanged)
receive_PUSH_PropertyChanged(pushInfoData.rData);
else
receive_PUSH_Event(pushInfoData.rData);
}
pushInfoList.Clear();
}
/// <summary>
/// 处理 从服务器 回复的 PUSH_PropertyChanged
/// </summary>
/// <param name="rData"></param>
void receive_PUSH_PropertyChanged(ReflectData rData)
{
ignoreSet = true;
obj.IsInPushValue = true;
var node = COMMON.FindNode(rootNode, rData.name);
if (node == null)
{
//异常
//服务器乱发过来
return;
}
string json = rData.data.ToString();
JsonConvert.PopulateObject(json, node.Obj);
obj.IsInPushValue = false;
ignoreSet = false;
}
/// <summary>
/// 处理 从服务器 回复的 PUSH_Event
/// </summary>
/// <param name="rData"></param>
void receive_PUSH_Event(ReflectData rData)
{
var anyEvent = anyEvents.Find(ae => ae.name == rData.name);
if (anyEvent == null)
return;//异常!!!
//触发事件!!!
var methodInfo = this.obj.GetType().GetMethod(anyEvent.triggerName);
if (methodInfo == null)
{
throw new Exception($"客户端 {this.obj.GetType()} 忘记写 {anyEvent.triggerName}");
}
var obj = rData.data.ToObject(anyEvent.retType);
//出错,就提示,肯定是客户端忘记写 "Trigger_XXXX"
methodInfo.Invoke(this.obj, new object[] { obj });
}
/// <summary>
/// 处理 从服务器 回复的 CALL_MethodInvoke
/// </summary>
/// <param name="rData"></param>
/// <param name="asyncDelegate"></param>
/// <param name="asyncContext"></param>
void receive_CALL_MethodInvoke(ReflectData rData, AsyncCBHandler asyncDelegate, object asyncContext)
{
var anyCall = anyCalls.Find(ac => ac.name == rData.name);
if (anyCall == null)
{
//异常!!!应该有[Call]注明返回的类型
throw new Exception($"{rData.name} 异常!!!应该有[Call]注明返回的类型");
}
var retData = rData.data.ToObject(anyCall.retType);
asyncDelegate.Invoke(asyncContext, retData);
}
#endregion
/// <summary>
/// 发送 CALL_MethodInvoke 请求到服务
/// </summary>
/// <param name="rData"></param>
void send_CALL_MethodInvoke(ReflectData rData, AsyncCBHandler asyncDelegate, object asyncContext)
{
var pkgData = new PkgData(
ServiceName,
PkgName.CALL_MethodInvoke,
Guid.NewGuid().ToString(),
JToken.FromObject(rData)
);
anyMethodInvokes.Add(new AnyMethodInvoke()
{
guid = pkgData.guid,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
string json = JsonConvert.SerializeObject(pkgData);
SendEx(json);
}
/// <summary>
/// 发送 CALL_SetProperty 请求到服务
/// </summary>
/// <param name="rData"></param>
void send_CALL_SetProperty(ReflectData rData)
{
var pkgData = new PkgData(
ServiceName,
PkgName.CALL_SetProperty,
Guid.NewGuid().ToString(),
JToken.FromObject(rData)
);
string json = JsonConvert.SerializeObject(pkgData);
SendEx(json);
}
#region WsServiceSys 调用
/// <summary>
/// 第1次连接成功
/// </summary>
public void OnOpen()
{
obj.IsConnected = true;
//获取全部属性
var pkgData = new PkgData(
ServiceName,
PkgName.CALL_GetAllProperties,
Guid.NewGuid().ToString(),
null
);
string json = JsonConvert.SerializeObject(pkgData);
SendEx(json);
}
public void OnClose()
{
obj.IsConnected = false;
//Dispose();
}
public void OnMessage(PkgData pkgData)
{
var pkgName = (PkgName)Enum.Parse(typeof(PkgName), pkgData.name);
switch (pkgName)
{
case PkgName.PUSH_PropertyChanged:
case PkgName.PUSH_Event:
{
var rData = pkgData.data.ToObject<ReflectData>();
if (!obj.IsSynced)
{
//还没同步完成,先缓存
pushInfoList.Add(
new PushInfoData()
{
isPushPropertyChanged = pkgName == PkgName.PUSH_PropertyChanged,
rData = rData
});
return;
}
if (pkgName == PkgName.PUSH_PropertyChanged)
receive_PUSH_PropertyChanged(rData);
else
receive_PUSH_Event(rData);
}
break;
case PkgName.CALL_GetAllProperties:
{
var rData = pkgData.data.ToObject<ReflectData>();
receive_CALL_GetAllProperties(rData);
}
break;
case PkgName.CALL_MethodInvoke:
{
var reponse = pkgData.data.ToObject<ReflectData>();
var anyMethodInvoke = anyMethodInvokes.Find(ami => ami.guid == pkgData.guid);
if (anyMethodInvoke == null)
{
//异常!!!应该有对应的回调
throw new Exception($"{reponse.name} 异常!!!应该有回调");
}
receive_CALL_MethodInvoke(reponse, anyMethodInvoke.asyncDelegate, anyMethodInvoke.asyncContext);
anyMethodInvokes.Remove(anyMethodInvoke);
}
break;
}
}
#endregion
}
}
......@@ -19,11 +19,6 @@ namespace WSCF
/// </summary>
protected abstract Type InterfaceType { get; }
/// <summary>
/// 连接成功
/// </summary>
public new bool IsConnected { get; set; }
/// <summary>
/// 已经同步完成;
/// 已经收到了 CALL_GetAllProperties, 全部属性都与服务器一致
......
......@@ -45,6 +45,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AsyncCBHandler.cs" />
<Compile Include="ReflectSeviceClientAssistant.cs" />
<Compile Include="RevCtrl\RevCtrl_ServiceClient.cs" />
<Compile Include="RevCtrl\RevCtrl_Proxy.cs" />
<Compile Include="RevCtrl\IRevCtrlAdmin.cs" />
......
......@@ -13,7 +13,7 @@ namespace WSCF
{
public event PropertyChangedEventHandler PropertyChanged;
public bool IsConnected { get; private set; }
public bool IsConnected { get; set; }
/// <summary>
/// 重连剩余秒数
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment