Commit d3e677c0 authored by 潘栩锋's avatar 潘栩锋 🚴

1. 修复 COMMON.NodeDispose 当子property不是INotifyProperty 会出错

2. 修复 刚连接成功,当全部properties 太多,导致下载慢,此时服务器有属性改变了,新改变很快的到达客户端,但之前的 GetProperty 后来才到达。 数据都不同步了。
parent 1b294c14
......@@ -53,14 +53,14 @@ namespace WSCF
continue;//必须是[PropertyPush]
SubPropertyNode node = new SubPropertyNode();
if (ReInitPropertyPush(node, rootNode.Obj, propertyInfo, rootNode.SubPropertyChanged))
if (ReInitPropertyPush(node, rootNode.Obj, propertyInfo, rootNode.SubPropertyChanged))
{
node.Parent = rootNode;
rootNode.Children.Add(node);
}
}
}
public static bool ReInitPropertyPush(SubPropertyNode node, object parentObj, PropertyInfo propertyInfo, SubPropertyChangedEventHandler sub_PropertyChanged)
public static bool ReInitPropertyPush(SubPropertyNode node, object parentObj, PropertyInfo propertyInfo, SubPropertyChangedEventHandler sub_PropertyChanged)
{
var propertyValue = propertyInfo.GetValue(parentObj);
// propertyValue==null 也注册
......@@ -72,7 +72,7 @@ namespace WSCF
node.InterfaceType = propertyInfo.PropertyType;
node.Obj = propertyValue;
node.SubPropertyChanged = sub_PropertyChanged;
if (node.Obj != null)
{
//下级推送!!!!
......@@ -91,7 +91,7 @@ namespace WSCF
var list = node.Obj as System.Collections.IList;
if (list != null && list.Count>0)
if (list != null && list.Count > 0)
{
InitSubPropertyPushs(list, node, sub_PropertyChanged);
}
......@@ -164,8 +164,10 @@ namespace WSCF
}
public static string GetNodePath(SubPropertyNode node) {
if (string.IsNullOrEmpty(node.Name)) {
public static string GetNodePath(SubPropertyNode node)
{
if (string.IsNullOrEmpty(node.Name))
{
//已经是最上级
return null;
}
......@@ -173,17 +175,19 @@ namespace WSCF
StringBuilder sb = new StringBuilder();
sb.Append(node.Name);
while (node.Parent != null) {
while (node.Parent != null)
{
node = node.Parent;
if (string.IsNullOrEmpty(node.Name)) {
if (string.IsNullOrEmpty(node.Name))
{
//到了最上级
break;
}
sb.Insert(0, node.Name+".");
sb.Insert(0, node.Name + ".");
}
return sb.ToString();
}
public static SubPropertyNode FindNode(SubPropertyNode rootNode, string path)
public static SubPropertyNode FindNode(SubPropertyNode rootNode, string path)
{
SubPropertyNode node = null;
if (string.IsNullOrEmpty(path))
......@@ -192,13 +196,16 @@ namespace WSCF
var nodes = rootNode.Children;
//分解路径
string[] names = path.Split('.');
foreach (string name in names) {
if (string.IsNullOrEmpty(name)) {
foreach (string name in names)
{
if (string.IsNullOrEmpty(name))
{
//这个不算
continue;
}
node = nodes.Find(n => n.Name == name);
if (node == null) {
if (node == null)
{
//异常
return null;
}
......@@ -206,18 +213,18 @@ namespace WSCF
}
return node;
}
public static void NodeChildrenDispose(List<SubPropertyNode> nodes)
public static void NodeChildrenDispose(List<SubPropertyNode> nodes)
{
foreach (var node in nodes)
{
NodeDispose(node);
}
}
public static void NodeDispose(SubPropertyNode node)
public static void NodeDispose(SubPropertyNode node)
{
if (!node.IsArray)
{
if(node.Obj!=null)
if (node.Obj != null && node.Obj is INotifyPropertyChanged)
((INotifyPropertyChanged)(node.Obj)).PropertyChanged -= node.PropertyChanged;
}
......@@ -286,10 +293,11 @@ namespace WSCF
public PropertyChangedEventHandler PropertyChanged;
public SubPropertyChangedEventHandler SubPropertyChanged;
public SubPropertyNode() {
public SubPropertyNode()
{
PropertyChanged = new PropertyChangedEventHandler(_PropertyChanged);
}
public void _PropertyChanged(object sender, PropertyChangedEventArgs e)
public void _PropertyChanged(object sender, PropertyChangedEventArgs e)
{
//处理[PropertyPush]重新注册问题
COMMON.PropertyChanged_reInitPropertyPush(this, e);
......
......@@ -13,6 +13,7 @@ namespace WSCF
/// </summary>
public class PushAttribute : Attribute
{
public const string DefaultTriggerNameHeader = "Trigger_";
public Type EventArgsType;
public string TriggerName;
public PushAttribute(Type eventArgsType)
......
......@@ -11,26 +11,44 @@ using WebSocketSharp.Server;
namespace WSCF
{
public class Reflect_Proxy : WebSocketBehavior,IDisposable
public class Reflect_Proxy : WebSocketBehavior, IDisposable
{
static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
//对象的接口类型
#region Core
/// <summary>
/// 对象的接口类型
/// </summary>
Type interfaceType;
//代理对象
/// <summary>
/// 代理对象
/// </summary>
object obj;
//忽略设置
/// <summary>
/// 忽略设置
/// </summary>
public bool ignoreSet = false;
/// <summary>
/// 对象的全部event
/// </summary>
List<AnyEvent> anyEvents = new List<AnyEvent>();
/// <summary>
/// [PropertyPush] 标签树
/// </summary>
SubPropertyNode rootNode;
/// <summary>
/// interfaceType 及其父类 的全部属性
/// </summary>
List<string> properties = new List<string>();
#endregion
public bool isAlive = false;
public Reflect_Proxy()
{
}
#region Core
public void Init(Type interfaceType, object obj)
{
this.interfaceType = interfaceType;
......@@ -52,9 +70,6 @@ namespace WSCF
//处理[Push]
InitEventPush();
}
#region Init
void InitPropertyChanged()
{
if (!typeof(INotifyPropertyChanged).IsAssignableFrom(interfaceType))
......@@ -77,7 +92,6 @@ namespace WSCF
}
}
void InitEventPush()
{
var interfaceTypes = new List<Type>();
......@@ -104,18 +118,7 @@ namespace WSCF
var anyEvent = new AnyEvent()
{
eventName = eventInfo.Name,
PushObjInfoEx = (rd) => {
//数据推送!!!
//再嵌套
Reflect_OBJ_INTERFACE.PkgData pkgData = new Reflect_OBJ_INTERFACE.PkgData(
Reflect_OBJ_INTERFACE.PkgName.PUSH_Event,
null,
JObject.FromObject(rd)
);
string json = JsonConvert.SerializeObject(pkgData);
SendEx(json);
}
PushObjInfoEx = (rd) => reponse_PushObjInfoEx(rd, true)
};
//这个事件需要推送
eventInfo.AddEventHandler(obj, anyEvent.eventHandler);
......@@ -123,19 +126,7 @@ namespace WSCF
}
}
void SendEx(string msg) {
try
{
Send(msg);
}
catch (Exception e)
{
//异常,通常是断开了!!
logger.Error(e);
}
}
private void Sub_PropertyChanged(SubPropertyNode node, PropertyChangedEventArgs e)
void Sub_PropertyChanged(SubPropertyNode node, PropertyChangedEventArgs e)
{
//if (ignoreSet)//从服务器接收的数据,不用再推送给服务器
// return;
......@@ -160,135 +151,99 @@ namespace WSCF
name = COMMON.GetNodePath(node),
data = jObject
};
Reflect_OBJ_INTERFACE.PkgData pkgData = new Reflect_OBJ_INTERFACE.PkgData(
Reflect_OBJ_INTERFACE.PkgName.PUSH_PropertyChanged,
null,
JToken.FromObject(rData)
);
string json = JsonConvert.SerializeObject(pkgData);
SendEx(json);
reponse_PushObjInfoEx(rData, false);
}
#endregion
protected override void OnOpen()
Reflect_OBJ_INTERFACE.ReflectData request_CALL_GetAllProperties()
{
base.OnOpen();
isAlive = true;
AfterOpen?.Invoke(this);
}
public Action<Reflect_Proxy> AfterOpen;
var jObject = new JObject();
protected override void OnClose(CloseEventArgs e)
{
base.OnClose(e);
isAlive = false;
var type = obj.GetType();
Dispose();
}
foreach (var propertyName in properties)
{
var propertyInfo = type.GetProperty(propertyName);
var v = propertyInfo.GetValue(obj);
if (v == null)
jObject.Add(propertyInfo.Name, null);
else
jObject.Add(propertyInfo.Name, JToken.FromObject(v));
}
protected override void OnMessage(MessageEventArgs e)
{
if (!e.IsText)
return;
string json = e.Data;
var p = JsonConvert.DeserializeObject<Reflect_OBJ_INTERFACE.PkgData>(json);
OnMessage(p);
var rData = new Reflect_OBJ_INTERFACE.ReflectData
{
data = jObject
};
return rData;
}
void OnMessage(Reflect_OBJ_INTERFACE.PkgData pkgData)
void request_CALL_SetProperty(Reflect_OBJ_INTERFACE.ReflectData rData)
{
var pkgName = Enum.Parse(typeof(Reflect_OBJ_INTERFACE.PkgName), pkgData.name);
switch (pkgName)
{
case Reflect_OBJ_INTERFACE.PkgName.CALL_GetAllProperties:
{
//ignoreSet = true;
var jObject = new JObject();
var type = obj.GetType();
foreach (var propertyName in properties)
{
var propertyInfo = type.GetProperty(propertyName);
var v = propertyInfo.GetValue(obj);
if (v == null)
jObject.Add(propertyInfo.Name, null);
else
jObject.Add(propertyInfo.Name, JToken.FromObject(v));
}
var rData = new Reflect_OBJ_INTERFACE.ReflectData
{
data = jObject
};
//sub property
var node = COMMON.FindNode(rootNode, rData.name);
if (node == null)
{
//异常
//客户端乱发过来
return;
}
string json = rData.data.ToString();
JsonConvert.PopulateObject(json, node.Obj);
pkgData.data = JToken.FromObject(rData);
//ignoreSet = false;
}
string json = JsonConvert.SerializeObject(pkgData);
SendEx(json);
}
break;
case Reflect_OBJ_INTERFACE.PkgName.CALL_SetProperty:
{
//ignoreSet = true;
var rData = pkgData.data.ToObject<Reflect_OBJ_INTERFACE.ReflectData>();
void request_CALL_MethodInvoke(Reflect_OBJ_INTERFACE.ReflectData rData, CC cc)
{
var type = obj.GetType();
var paramNames_req = rData.data.Children().OfType<JProperty>().Select(p => p.Name);
MethodInfo methodInfo = GetMethodInfo(type, rData.name, paramNames_req);
if (methodInfo == null)
{
//不能找到,
throw new Exception($"程序写错了, 不能找到 rData.name={rData.name} 或者 参数名称不对,没法完全匹配");
}
var parameterInfos = methodInfo.GetParameters();
object[] parameters = new object[parameterInfos.Count()];
for (int i = 0; i < parameters.Count(); i++)
{
var ptype = parameterInfos[i].ParameterType;
var pname = parameterInfos[i].Name;
if (string.Compare(pname, Reflect_OBJ_INTERFACE.asyncDelegate, true) == 0)
{
parameters[i] = new AsyncCBHandler(asyncDelegate);
}
else if (string.Compare(pname, Reflect_OBJ_INTERFACE.asyncContext, true) == 0)
{
cc.methodName = rData.name;
parameters[i] = cc;
}
else
{
parameters[i] = rData.data[pname].ToObject(ptype);
}
}
methodInfo.Invoke(obj, parameters);
}
//sub property
var node = COMMON.FindNode(rootNode, rData.name);
if (node == null) {
//异常
//客户端乱发过来
break;
}
void asyncDelegate(object asyncContext, object retData)
{
var cc = (CC)asyncContext;
string json = rData.data.ToString();
JsonConvert.PopulateObject(json, node.Obj);
//ignoreSet = false;
}
break;
case Reflect_OBJ_INTERFACE.PkgName.CALL_MethodInvoke:
{
var rData = pkgData.data.ToObject<Reflect_OBJ_INTERFACE.ReflectData>();
var type = obj.GetType();
var paramNames_req = rData.data.Children().OfType<JProperty>().Select(p => p.Name);
MethodInfo methodInfo = GetMethodInfo(type, rData.name, paramNames_req);
if (methodInfo == null)
{
//不能找到,
throw new Exception($"程序写错了, 不能找到 rData.name={rData.name} 或者 参数名称不对,没法完全匹配");
}
var parameterInfos = methodInfo.GetParameters();
object[] parameters = new object[parameterInfos.Count()];
for (int i = 0; i < parameters.Count(); i++)
{
var ptype = parameterInfos[i].ParameterType;
var pname = parameterInfos[i].Name;
if (string.Compare(pname, Reflect_OBJ_INTERFACE.asyncDelegate, true) == 0)
{
parameters[i] = new AsyncCBHandler(asyncDelegate);
}
else if (string.Compare(pname, Reflect_OBJ_INTERFACE.asyncContext, true) == 0)
{
parameters[i] = new CC() { methodName = rData.name, guid = pkgData.guid };
}
else
{
parameters[i] = rData.data[pname].ToObject(ptype);
}
}
methodInfo.Invoke(obj, parameters);
}break;
}
var rData = new Reflect_OBJ_INTERFACE.ReflectData()
{
name = cc.methodName,
data = retData == null ? null : JToken.FromObject(retData)
};
reponse_CALL_MethodInvoke(rData, cc);
}
MethodInfo GetMethodInfo(Type type, string name, IEnumerable<string> parameterNames)
{
......@@ -324,46 +279,145 @@ namespace WSCF
}
return null;
}
void asyncDelegate(object asyncContext, object retData)
public void Dispose()
{
var cc = (CC)asyncContext;
if (typeof(INotifyPropertyChanged).IsAssignableFrom(interfaceType))
{
//继承了INotifyPropertyChanged
((INotifyPropertyChanged)(this.obj)).PropertyChanged -= rootNode.PropertyChanged;
}
var rData = new Reflect_OBJ_INTERFACE.ReflectData()
//释放subProperties
COMMON.NodeDispose(rootNode);
}
#endregion
void reponse_PushObjInfoEx(Reflect_OBJ_INTERFACE.ReflectData rData, bool isEvent)
{
//数据推送!!!
//再嵌套
var pkgName = isEvent ? Reflect_OBJ_INTERFACE.PkgName.PUSH_Event : Reflect_OBJ_INTERFACE.PkgName.PUSH_PropertyChanged;
Reflect_OBJ_INTERFACE.PkgData pkgData = new Reflect_OBJ_INTERFACE.PkgData()
{
name = cc.methodName,
data = retData == null ? null : JToken.FromObject(retData)
guid = Guid.NewGuid().ToString(),
name = pkgName.ToString(),
data = JToken.FromObject(rData)
};
string json = JsonConvert.SerializeObject(pkgData);
SendEx(json);
}
void reponse_CALL_MethodInvoke(Reflect_OBJ_INTERFACE.ReflectData rData, CC cc)
{
Reflect_OBJ_INTERFACE.PkgData pkgData = new Reflect_OBJ_INTERFACE.PkgData(
Reflect_OBJ_INTERFACE.PkgName.CALL_MethodInvoke,
cc.guid,
JToken.FromObject(rData)
);
Reflect_OBJ_INTERFACE.PkgData pkgData = new Reflect_OBJ_INTERFACE.PkgData()
{
guid = cc.guid,
name = Reflect_OBJ_INTERFACE.PkgName.CALL_MethodInvoke.ToString(),
data = JToken.FromObject(rData)
};
string json = JsonConvert.SerializeObject(pkgData);
SendEx(json);
}
public void Dispose()
void reponse_CALL_GetAllProperties(Reflect_OBJ_INTERFACE.ReflectData rData, CC cc)
{
if (typeof(INotifyPropertyChanged).IsAssignableFrom(interfaceType))
Reflect_OBJ_INTERFACE.PkgData pkgData = new Reflect_OBJ_INTERFACE.PkgData()
{
//继承了INotifyPropertyChanged
((INotifyPropertyChanged)(this.obj)).PropertyChanged -= rootNode.PropertyChanged;
}
guid = cc.guid,
name = Reflect_OBJ_INTERFACE.PkgName.CALL_GetAllProperties.ToString(),
data = JToken.FromObject(rData)
};
string json = JsonConvert.SerializeObject(pkgData);
SendEx(json);
}
//释放subProperties
COMMON.NodeDispose(rootNode);
void OnMessage(Reflect_OBJ_INTERFACE.PkgData pkgData)
{
var pkgName = Enum.Parse(typeof(Reflect_OBJ_INTERFACE.PkgName), pkgData.name);
switch (pkgName)
{
case Reflect_OBJ_INTERFACE.PkgName.CALL_GetAllProperties:
{
var rData = request_CALL_GetAllProperties();
reponse_CALL_GetAllProperties(rData, new CC() { guid = pkgData.guid });
}
break;
case Reflect_OBJ_INTERFACE.PkgName.CALL_SetProperty:
{
//ignoreSet = true;
var rData = pkgData.data.ToObject<Reflect_OBJ_INTERFACE.ReflectData>();
request_CALL_SetProperty(rData);
}
break;
case Reflect_OBJ_INTERFACE.PkgName.CALL_MethodInvoke:
{
var rData = pkgData.data.ToObject<Reflect_OBJ_INTERFACE.ReflectData>();
request_CALL_MethodInvoke(rData, new CC() { guid = pkgData.guid });
}
break;
}
}
class CC
{
public string methodName;
public string guid;
/// <summary>
/// CALL_MethodInvoke 时使用
/// </summary>
public string methodName;
}
void SendEx(string msg)
{
try
{
Send(msg);
}
catch (Exception e)
{
//异常,通常是断开了!!
logger.Error(e);
}
}
protected override void OnOpen()
{
base.OnOpen();
isAlive = true;
AfterOpen?.Invoke(this);
}
public Action<Reflect_Proxy> AfterOpen;
protected override void OnClose(CloseEventArgs e)
{
base.OnClose(e);
isAlive = false;
Dispose();
}
protected override void OnMessage(MessageEventArgs e)
{
if (!e.IsText)
return;
string json = e.Data;
var p = JsonConvert.DeserializeObject<Reflect_OBJ_INTERFACE.PkgData>(json);
OnMessage(p);
}
}
/// <summary>
......
......@@ -13,6 +13,7 @@ namespace WSCF
{
public class Reflect_SeviceClient : WebSocketClient, IDisposable
{
#region Core
/// <summary>
/// 忽略设置
/// </summary>
......@@ -22,6 +23,16 @@ namespace WSCF
/// </summary>
protected virtual Type InterfaceType { get; }
/// <summary>
/// 已经同步完成;
/// 已经收到了 CALL_GetAllProperties, 全部属性都与服务器一致
/// </summary>
public bool IsSynced { get; private set; }
/// <summary>
/// 当前 INotifyPropertyChanged 对象 引发了 PropertyChanged, 是由于 接收到数据导致的
/// </summary>
public bool IsInPushValue { get; protected set; }
class AnyEvent
{
......@@ -34,6 +45,27 @@ namespace WSCF
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 Reflect_OBJ_INTERFACE.ReflectData rData;
}
#endregion
class AnyMethodInvoke
{
public string guid;
......@@ -41,11 +73,9 @@ namespace WSCF
public object asyncContext;
}
List<AnyEvent> anyEvents = new List<AnyEvent>();
List<AnyCall> anyCalls = new List<AnyCall>();
List<AnyMethodInvoke> anyMethodInvokes = new List<AnyMethodInvoke>();
SubPropertyNode rootNode;
List<string> properties = new List<string>();
public Reflect_SeviceClient(string serverName,bool isByConnName, string addrOrConnName):base(serverName)
{
......@@ -59,6 +89,7 @@ namespace WSCF
init();
}
#region Core
void init()
{
rootNode = new SubPropertyNode
......@@ -72,6 +103,18 @@ namespace WSCF
COMMON.InitPropertyPush(rootNode);
InitEventPush();
InitCall();
this.PropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(IsConnected))
{
if (IsConnected == false)
{
IsSynced = false;
pushInfoList.Clear();
}
}
};
}
void InitPropertyChanged()
{
......@@ -120,7 +163,7 @@ namespace WSCF
string triggerName;
if (string.IsNullOrEmpty(pushAttribute.TriggerName))
{
triggerName = "Trigger_" + eventInfo.Name;
triggerName = PushAttribute.DefaultTriggerNameHeader + eventInfo.Name;
}
else
{
......@@ -199,17 +242,181 @@ namespace WSCF
name = COMMON.GetNodePath(node),
data = jObject
};
send_CALL_SetProperty(rData);
}
public override void Dispose()
{
base.Dispose();
if (typeof(INotifyPropertyChanged).IsAssignableFrom(InterfaceType))
{
//继承了INotifyPropertyChanged
((INotifyPropertyChanged)(this)).PropertyChanged -= rootNode.PropertyChanged;
}
//释放subProperties
COMMON.NodeDispose(rootNode);
}
protected void Call(string methodName, object parameters, AsyncCBHandler asyncDelegate, object asyncContext)
{
var rData = new Reflect_OBJ_INTERFACE.ReflectData()
{
name = methodName,
data = parameters == null ? null : JObject.FromObject(parameters)
};
send_CALL_MethodInvoke(rData, asyncDelegate, asyncContext);
}
protected void Call(string methodName, object parameters)
{
Call(methodName, parameters, null, null);
}
protected void Call(string methodName)
{
Call(methodName, null, null, null);
}
/// <summary>
/// 处理 从服务器 回复的 CALL_GetAllProperties
/// </summary>
/// <param name="rData"></param>
void receive_CALL_GetAllProperties(Reflect_OBJ_INTERFACE.ReflectData rData)
{
receive_PUSH_PropertyChanged(rData);
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(Reflect_OBJ_INTERFACE.ReflectData rData)
{
ignoreSet = true;
IsInPushValue = true;
var node = COMMON.FindNode(rootNode, rData.name);
if (node == null)
{
//异常
//服务器乱发过来
return;
}
string json = rData.data.ToString();
JsonConvert.PopulateObject(json, node.Obj);
IsInPushValue = false;
ignoreSet = false;
}
/// <summary>
/// 处理 从服务器 回复的 PUSH_Event
/// </summary>
/// <param name="rData"></param>
void receive_PUSH_Event(Reflect_OBJ_INTERFACE.ReflectData rData)
{
if (InterfaceType == null)
return;
var anyEvent = anyEvents.Find(ae => ae.name == rData.name);
if (anyEvent == null)
return;//异常!!!
//触发事件!!!
var methodInfo = GetType().GetMethod(anyEvent.triggerName);
if (methodInfo == null)
{
throw new Exception($"客户端 {GetType()} 忘记写 {anyEvent.triggerName}");
}
var obj = rData.data.ToObject(anyEvent.retType);
//出错,就提示,肯定是客户端忘记写 "Trigger_XXXX"
methodInfo.Invoke(this, new object[] { obj });
}
/// <summary>
/// 处理 从服务器 回复的 CALL_MethodInvoke
/// </summary>
/// <param name="rData"></param>
/// <param name="asyncDelegate"></param>
/// <param name="asyncContext"></param>
void receive_CALL_MethodInvoke(Reflect_OBJ_INTERFACE.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(Reflect_OBJ_INTERFACE.ReflectData rData, AsyncCBHandler asyncDelegate, object asyncContext)
{
Reflect_OBJ_INTERFACE.PkgData pkgData = new Reflect_OBJ_INTERFACE.PkgData(
Reflect_OBJ_INTERFACE.PkgName.CALL_SetProperty,
Reflect_OBJ_INTERFACE.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);
Send(json);
}
/// <summary>
/// 发送 CALL_SetProperty 请求到服务器
/// </summary>
/// <param name="rData"></param>
void send_CALL_SetProperty(Reflect_OBJ_INTERFACE.ReflectData rData)
{
Reflect_OBJ_INTERFACE.PkgData pkgData = new Reflect_OBJ_INTERFACE.PkgData(
Reflect_OBJ_INTERFACE.PkgName.CALL_SetProperty,
Guid.NewGuid().ToString(),
JToken.FromObject(rData)
);
string json = JsonConvert.SerializeObject(pkgData);
Send(json);
}
#region FObj
protected override void OnOpen()
{
......@@ -221,74 +428,52 @@ namespace WSCF
string json = JsonConvert.SerializeObject(pkgData);
Send(json);
}
protected override void OnMessage(string msg)
{
var pkgData = JsonConvert.DeserializeObject<Reflect_OBJ_INTERFACE.PkgData>(msg);
var pkgName = Enum.Parse(typeof(Reflect_OBJ_INTERFACE.PkgName), pkgData.name);
var pkgName = (Reflect_OBJ_INTERFACE.PkgName)Enum.Parse(typeof(Reflect_OBJ_INTERFACE.PkgName), pkgData.name);
switch (pkgName)
{
case Reflect_OBJ_INTERFACE.PkgName.PUSH_PropertyChanged:
case Reflect_OBJ_INTERFACE.PkgName.CALL_GetAllProperties:
case Reflect_OBJ_INTERFACE.PkgName.PUSH_Event:
{
ignoreSet = true;
var rData = pkgData.data.ToObject<Reflect_OBJ_INTERFACE.ReflectData>();
var node = COMMON.FindNode(rootNode, rData.name);
if (node == null)
if (!IsSynced)
{
//异常
//服务器乱发过来
break;
//还没同步完成,先缓存
pushInfoList.Add(
new PushInfoData()
{
isPushPropertyChanged = pkgName == Reflect_OBJ_INTERFACE.PkgName.PUSH_PropertyChanged,
rData = rData
});
return;
}
string json = rData.data.ToString();
JsonConvert.PopulateObject(json, node.Obj);
if (pkgName == Reflect_OBJ_INTERFACE.PkgName.PUSH_PropertyChanged)
receive_PUSH_PropertyChanged(rData);
else
receive_PUSH_Event(rData);
ignoreSet = false;
}
break;
case Reflect_OBJ_INTERFACE.PkgName.PUSH_Event:
case Reflect_OBJ_INTERFACE.PkgName.CALL_GetAllProperties:
{
if (InterfaceType == null)
return;
var rData = pkgData.data.ToObject<Reflect_OBJ_INTERFACE.ReflectData>();
var anyEvent = anyEvents.Find(ae => ae.name == rData.name);
if (anyEvent == null)
return;//异常!!!
//触发事件!!!
var methodInfo = GetType().GetMethod(anyEvent.triggerName);
if (methodInfo == null)
{
throw new Exception($"客户端 {GetType()} 忘记写 {anyEvent.triggerName}");
}
var obj = rData.data.ToObject(anyEvent.retType);
//出错,就提示,肯定是客户端忘记写 "Trigger_XXXX"
methodInfo.Invoke(this, new object[] { obj });
receive_CALL_GetAllProperties(rData);
}
break;
case Reflect_OBJ_INTERFACE.PkgName.CALL_MethodInvoke:
{
if (InterfaceType == null)
return;
var reponse = pkgData.data.ToObject<Reflect_OBJ_INTERFACE.ReflectData>();
var anyCall = anyCalls.Find(ac => ac.name == reponse.name);
if (anyCall == null)
{
//异常!!!应该有[Call]注明返回的类型
throw new Exception($"{reponse.name} 异常!!!应该有[Call]注明返回的类型");
}
var retData = reponse.data.ToObject(anyCall.retType);
var anyMethodInvoke = anyMethodInvokes.Find(ami => ami.guid == pkgData.guid);
if (anyMethodInvoke == null)
......@@ -297,48 +482,16 @@ namespace WSCF
throw new Exception($"{reponse.name} 异常!!!应该有回调");
}
anyMethodInvoke.asyncDelegate.Invoke(anyMethodInvoke.asyncContext, retData);
receive_CALL_MethodInvoke(reponse, anyMethodInvoke.asyncDelegate, anyMethodInvoke.asyncContext);
anyMethodInvokes.Remove(anyMethodInvoke);
}
break;
}
}
protected void Call(string methodName, object parameters, AsyncCBHandler asyncDelegate, object asyncContext)
{
var rData = new Reflect_OBJ_INTERFACE.ReflectData()
{
name = methodName,
data = parameters == null ? null : JObject.FromObject(parameters)
};
var pkgData = new Reflect_OBJ_INTERFACE.PkgData(Reflect_OBJ_INTERFACE.PkgName.CALL_MethodInvoke, Guid.NewGuid().ToString(), JObject.FromObject(rData));
anyMethodInvokes.Add(new AnyMethodInvoke() { guid = pkgData.guid, asyncDelegate = asyncDelegate, asyncContext = asyncContext });
string json = JsonConvert.SerializeObject(pkgData);
Send(json);
}
protected void Call(string methodName, object parameters)
{
Call(methodName, parameters, null, null);
}
protected void Call(string methodName)
{
Call(methodName, null, null, null);
}
#endregion
public void Dispose()
{
if (typeof(INotifyPropertyChanged).IsAssignableFrom(InterfaceType))
{
//继承了INotifyPropertyChanged
((INotifyPropertyChanged)(this)).PropertyChanged -= rootNode.PropertyChanged;
}
//释放subProperties
COMMON.NodeDispose(rootNode);
}
}
}
......@@ -175,7 +175,7 @@ namespace WSCF
public void Dispose()
public virtual void Dispose()
{
ws.Close();
FObjServiceClientManager.Instance.ObjClientDisponse(this);
......
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