Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
W
WSCF
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
潘栩锋
WSCF
Commits
c021c2f6
Commit
c021c2f6
authored
Oct 21, 2021
by
潘栩锋
🚴
Browse files
Options
Browse Files
Download
Plain Diff
合并
parents
9c0b9932
13e8ec64
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
6 additions
and
1045 deletions
+6
-1045
MainWindow.xaml
WSCF.Test.Client/MainWindow.xaml
+3
-0
COMMON.cs
WSCF.standard/COMMON.cs
+0
-301
Reflect_Proxy.cs
WSCF.standard/Reflect_Proxy.cs
+0
-400
Reflect_SeviceClient.cs
WSCF.standard/Reflect_SeviceClient.cs
+0
-344
WSCF.standard.csproj
WSCF.standard/WSCF.standard.csproj
+3
-0
No files found.
WSCF.Test.Client/MainWindow.xaml
View file @
c021c2f6
...
@@ -13,6 +13,9 @@
...
@@ -13,6 +13,9 @@
IsConnected=<Run Text="{Binding IsConnected,Mode=OneWay}"/>
IsConnected=<Run Text="{Binding IsConnected,Mode=OneWay}"/>
</TextBlock>
</TextBlock>
<TextBlock>
<TextBlock>
IsSynced=<Run Text="{Binding IsSynced,Mode=OneWay}"/>
</TextBlock>
<TextBlock>
Number=<Run Text="{Binding Number,Mode=OneWay}"/>
Number=<Run Text="{Binding Number,Mode=OneWay}"/>
</TextBlock>
</TextBlock>
<TextBlock>
<TextBlock>
...
...
WSCF.standard/COMMON.cs
deleted
100644 → 0
View file @
9c0b9932
using
System
;
using
System.Collections.Generic
;
using
System.ComponentModel
;
using
System.Linq
;
using
System.Reflection
;
using
System.Text
;
using
System.Threading.Tasks
;
namespace
WSCF
{
static
class
COMMON
{
static
bool
IsPropertyPush
(
PropertyInfo
propertyInfo
)
{
if
(
propertyInfo
.
GetCustomAttribute
<
PropertyPushAttribute
>()
==
null
)
return
false
;
//必须是[PropertyPush]
if
(!
typeof
(
INotifyPropertyChanged
).
IsAssignableFrom
(
propertyInfo
.
PropertyType
))
return
false
;
//必须是从INotifyPropertyChanged派生的
return
true
;
}
/// <summary>
/// 获取全部属性, 包括父类的属性, 可能有重复的
/// </summary>
/// <returns></returns>
public
static
List
<
PropertyInfo
>
GetAllPropertyInfos
(
Type
interfaceType
)
{
var
interfaceTypes
=
new
List
<
Type
>();
interfaceTypes
.
Add
(
interfaceType
);
interfaceTypes
.
AddRange
(
interfaceType
.
GetInterfaces
());
var
propertyInfos
=
new
List
<
PropertyInfo
>();
//获取全部属性, 包括父类的属性
foreach
(
var
ifaceType
in
interfaceTypes
)
{
propertyInfos
.
AddRange
(
ifaceType
.
GetProperties
());
}
return
propertyInfos
;
}
public
static
void
InitPropertyPush
(
SubPropertyNode
rootNode
)
{
//处理[PropertyPush]
var
propertyInfos
=
GetAllPropertyInfos
(
rootNode
.
InterfaceType
);
foreach
(
var
propertyInfo
in
propertyInfos
)
{
if
(
propertyInfo
.
GetCustomAttribute
<
PropertyPushAttribute
>()
==
null
)
continue
;
//必须是[PropertyPush]
SubPropertyNode
node
=
new
SubPropertyNode
();
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
)
{
var
propertyValue
=
propertyInfo
.
GetValue
(
parentObj
);
// propertyValue==null 也注册
if
(
typeof
(
INotifyPropertyChanged
).
IsAssignableFrom
(
propertyInfo
.
PropertyType
))
{
//必须是从INotifyPropertyChanged派生的
node
.
Name
=
propertyInfo
.
Name
;
node
.
InterfaceType
=
propertyInfo
.
PropertyType
;
node
.
Obj
=
propertyValue
;
node
.
SubPropertyChanged
=
sub_PropertyChanged
;
if
(
node
.
Obj
!=
null
)
{
//下级推送!!!!
((
INotifyPropertyChanged
)(
propertyValue
)).
PropertyChanged
+=
node
.
PropertyChanged
;
InitSubPropertyPush
(
propertyValue
,
node
,
sub_PropertyChanged
);
}
return
true
;
}
else
if
(
typeof
(
System
.
Collections
.
IList
).
IsAssignableFrom
(
propertyInfo
.
PropertyType
))
{
//数组
node
.
Name
=
propertyInfo
.
Name
;
node
.
InterfaceType
=
propertyInfo
.
PropertyType
;
node
.
Obj
=
propertyValue
;
node
.
IsArray
=
true
;
var
list
=
node
.
Obj
as
System
.
Collections
.
IList
;
if
(
list
!=
null
&&
list
.
Count
>
0
)
{
InitSubPropertyPushs
(
list
,
node
,
sub_PropertyChanged
);
}
return
true
;
}
return
false
;
}
static
void
InitSubPropertyPush
(
object
obj
,
SubPropertyNode
node
,
SubPropertyChangedEventHandler
sub_PropertyChanged
)
{
//继续向下找
var
propertyInfos
=
obj
.
GetType
().
GetProperties
();
foreach
(
var
propertyInfo
in
propertyInfos
)
{
if
(!
IsPropertyPush
(
propertyInfo
))
continue
;
//必须是[PropertyPush]
var
element
=
propertyInfo
.
GetValue
(
obj
);
var
node_sub
=
new
SubPropertyNode
()
{
Name
=
propertyInfo
.
Name
,
InterfaceType
=
propertyInfo
.
PropertyType
,
Obj
=
element
,
Parent
=
node
,
SubPropertyChanged
=
sub_PropertyChanged
};
//下级推送!!!!
((
INotifyPropertyChanged
)(
element
)).
PropertyChanged
+=
node_sub
.
PropertyChanged
;
node
.
Children
.
Add
(
node_sub
);
InitSubPropertyPush
(
element
,
node_sub
,
sub_PropertyChanged
);
}
}
static
void
InitSubPropertyPushs
(
System
.
Collections
.
IList
list
,
SubPropertyNode
node
,
SubPropertyChangedEventHandler
sub_PropertyChanged
)
{
for
(
int
i
=
0
;
i
<
list
.
Count
;
i
++)
{
var
element
=
list
[
i
];
if
(
element
==
null
)
{
//空的。。。
continue
;
}
var
elementType
=
element
.
GetType
();
if
(!
typeof
(
INotifyPropertyChanged
).
IsAssignableFrom
(
elementType
))
{
//异常!!!!
continue
;
}
var
node_sub
=
new
SubPropertyNode
()
{
Name
=
$"[
{
i
}
]"
,
InterfaceType
=
elementType
,
Obj
=
element
,
Parent
=
node
,
SubPropertyChanged
=
sub_PropertyChanged
};
//下级推送!!!!
((
INotifyPropertyChanged
)(
element
)).
PropertyChanged
+=
node_sub
.
PropertyChanged
;
node
.
Children
.
Add
(
node_sub
);
InitSubPropertyPush
(
element
,
node_sub
,
sub_PropertyChanged
);
}
}
public
static
string
GetNodePath
(
SubPropertyNode
node
)
{
if
(
string
.
IsNullOrEmpty
(
node
.
Name
))
{
//已经是最上级
return
null
;
}
StringBuilder
sb
=
new
StringBuilder
();
sb
.
Append
(
node
.
Name
);
while
(
node
.
Parent
!=
null
)
{
node
=
node
.
Parent
;
if
(
string
.
IsNullOrEmpty
(
node
.
Name
))
{
//到了最上级
break
;
}
sb
.
Insert
(
0
,
node
.
Name
+
"."
);
}
return
sb
.
ToString
();
}
public
static
SubPropertyNode
FindNode
(
SubPropertyNode
rootNode
,
string
path
)
{
SubPropertyNode
node
=
null
;
if
(
string
.
IsNullOrEmpty
(
path
))
return
rootNode
;
var
nodes
=
rootNode
.
Children
;
//分解路径
string
[]
names
=
path
.
Split
(
'.'
);
foreach
(
string
name
in
names
)
{
if
(
string
.
IsNullOrEmpty
(
name
))
{
//这个不算
continue
;
}
node
=
nodes
.
Find
(
n
=>
n
.
Name
==
name
);
if
(
node
==
null
)
{
//异常
return
null
;
}
nodes
=
node
.
Children
;
}
return
node
;
}
public
static
void
NodeChildrenDispose
(
List
<
SubPropertyNode
>
nodes
)
{
foreach
(
var
node
in
nodes
)
{
NodeDispose
(
node
);
}
}
public
static
void
NodeDispose
(
SubPropertyNode
node
)
{
if
(!
node
.
IsArray
)
{
if
(
node
.
Obj
!=
null
)
((
INotifyPropertyChanged
)(
node
.
Obj
)).
PropertyChanged
-=
node
.
PropertyChanged
;
}
if
(
node
.
Children
.
Count
>
0
)
NodeChildrenDispose
(
node
.
Children
);
node
.
Children
.
Clear
();
node
.
Obj
=
null
;
node
.
Parent
=
null
;
}
/// <summary>
/// 处理因为服务器 修改了 [PropertyPush] 的对象, 需要重新注册推送事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public
static
void
PropertyChanged_reInitPropertyPush
(
SubPropertyNode
node
,
PropertyChangedEventArgs
e
)
{
var
sub_node
=
node
.
Children
.
Find
(
n
=>
n
.
Name
==
e
.
PropertyName
);
if
(
sub_node
==
null
)
return
;
//这个被修改了
//卸载它
COMMON
.
NodeDispose
(
sub_node
);
var
propertyInfo
=
node
.
Obj
.
GetType
().
GetProperty
(
e
.
PropertyName
);
//重新注册
COMMON
.
ReInitPropertyPush
(
sub_node
,
node
.
Obj
,
propertyInfo
,
node
.
SubPropertyChanged
);
}
}
/// <summary>
/// 子属性节点,用于注册 INotifyPropertyChanged
/// </summary>
class
SubPropertyNode
{
/// <summary>
/// 下级节点
/// </summary>
public
List
<
SubPropertyNode
>
Children
=
new
List
<
SubPropertyNode
>();
/// <summary>
/// 上级节点
/// </summary>
public
SubPropertyNode
Parent
;
/// <summary>
/// 节点名称;
/// 正常情况,就是属性的Name;
/// 但,当为数组时, 它的下级就是数组的元素。 元素不是数组的属性。 元素的name为 $"[{序号}]"
/// </summary>
public
string
Name
;
/// <summary>
/// 节点对象
/// </summary>
public
object
Obj
;
/// <summary>
/// 对象的模板接口。默认就是 Obj.GetType()
/// </summary>
public
Type
InterfaceType
;
/// <summary>
/// 是数组
/// </summary>
public
bool
IsArray
;
public
PropertyChangedEventHandler
PropertyChanged
;
public
SubPropertyChangedEventHandler
SubPropertyChanged
;
public
SubPropertyNode
()
{
PropertyChanged
=
new
PropertyChangedEventHandler
(
_PropertyChanged
);
}
public
void
_PropertyChanged
(
object
sender
,
PropertyChangedEventArgs
e
)
{
//处理[PropertyPush]重新注册问题
COMMON
.
PropertyChanged_reInitPropertyPush
(
this
,
e
);
SubPropertyChanged
?.
Invoke
(
this
,
e
);
}
}
delegate
void
SubPropertyChangedEventHandler
(
SubPropertyNode
node
,
PropertyChangedEventArgs
e
);
}
WSCF.standard/Reflect_Proxy.cs
deleted
100644 → 0
View file @
9c0b9932
using
Newtonsoft.Json
;
using
Newtonsoft.Json.Linq
;
using
System
;
using
System.Collections.Generic
;
using
System.ComponentModel
;
using
System.Linq
;
using
System.Reflection
;
using
WebSocketSharp
;
using
WebSocketSharp.Server
;
namespace
WSCF
{
public
class
Reflect_Proxy
:
WebSocketBehavior
,
IDisposable
{
static
NLog
.
Logger
logger
=
NLog
.
LogManager
.
GetCurrentClassLogger
();
//对象的接口类型
Type
interfaceType
;
//代理对象
object
obj
;
//忽略设置
public
bool
ignoreSet
=
false
;
List
<
AnyEvent
>
anyEvents
=
new
List
<
AnyEvent
>();
SubPropertyNode
rootNode
;
List
<
string
>
properties
=
new
List
<
string
>();
public
bool
isAlive
=
false
;
public
Reflect_Proxy
()
{
}
public
void
Init
(
Type
interfaceType
,
object
obj
)
{
this
.
interfaceType
=
interfaceType
;
this
.
obj
=
obj
;
rootNode
=
new
SubPropertyNode
{
Obj
=
obj
,
InterfaceType
=
interfaceType
,
SubPropertyChanged
=
Sub_PropertyChanged
};
//注册 obj 的PropertyChanged 事件,获取 interfaceType 全部属性名称,包括它的父类的全部属性名称
InitPropertyChanged
();
//处理[PropertyPush]
COMMON
.
InitPropertyPush
(
rootNode
);
//处理[Push]
InitEventPush
();
}
#
region
Init
void
InitPropertyChanged
()
{
if
(!
typeof
(
INotifyPropertyChanged
).
IsAssignableFrom
(
interfaceType
))
return
;
//继承了INotifyPropertyChanged
((
INotifyPropertyChanged
)(
this
.
obj
)).
PropertyChanged
+=
rootNode
.
PropertyChanged
;
var
propertyInfos
=
COMMON
.
GetAllPropertyInfos
(
this
.
interfaceType
);
//获取全部属性, 包括父类的属性
foreach
(
var
propertyInfo
in
propertyInfos
)
{
if
(
propertyInfo
.
GetCustomAttribute
<
JsonIgnoreAttribute
>()
!=
null
)
continue
;
//这个不需要推送
if
(
properties
.
Contains
(
propertyInfo
.
Name
))
continue
;
properties
.
Add
(
propertyInfo
.
Name
);
}
}
void
InitEventPush
()
{
var
interfaceTypes
=
new
List
<
Type
>();
interfaceTypes
.
Add
(
this
.
interfaceType
);
interfaceTypes
.
AddRange
(
this
.
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
.
eventName
==
eventInfo
.
Name
))
continue
;
//已经添加了
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
);
}
};
//这个事件需要推送
eventInfo
.
AddEventHandler
(
obj
,
anyEvent
.
eventHandler
);
anyEvents
.
Add
(
anyEvent
);
}
}
void
SendEx
(
string
msg
)
{
try
{
Send
(
msg
);
}
catch
(
Exception
e
)
{
//异常,通常是断开了!!
logger
.
Error
(
e
);
}
}
private
void
Sub_PropertyChanged
(
SubPropertyNode
node
,
PropertyChangedEventArgs
e
)
{
//if (ignoreSet)//从服务器接收的数据,不用再推送给服务器
// return;
var
type
=
node
.
Obj
.
GetType
();
var
propertyInfo
=
type
.
GetProperty
(
e
.
PropertyName
);
if
(
propertyInfo
==
null
)
return
;
//获取失败!!!
if
(
propertyInfo
.
GetCustomAttribute
<
JsonIgnoreAttribute
>()
!=
null
)
return
;
//这个不需要推送
var
v
=
propertyInfo
.
GetValue
(
node
.
Obj
);
var
jObject
=
new
JObject
();
if
(
v
==
null
)
jObject
.
Add
(
propertyInfo
.
Name
,
null
);
else
jObject
.
Add
(
propertyInfo
.
Name
,
JToken
.
FromObject
(
v
));
var
rData
=
new
Reflect_OBJ_INTERFACE
.
ReflectData
{
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
);
}
#
endregion
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
);
}
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
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
};
pkgData
.
data
=
JToken
.
FromObject
(
rData
);
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
>();
//sub property
var
node
=
COMMON
.
FindNode
(
rootNode
,
rData
.
name
);
if
(
node
==
null
)
{
//异常
//客户端乱发过来
break
;
}
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
;
}
}
MethodInfo
GetMethodInfo
(
Type
type
,
string
name
,
IEnumerable
<
string
>
parameterNames
)
{
var
methodInfos
=
from
mi
in
type
.
GetMethods
()
where
mi
.
Name
==
name
select
mi
;
if
(
methodInfos
.
Count
()
==
0
)
return
null
;
if
(
methodInfos
.
Count
()
==
1
)
return
methodInfos
.
First
();
//必须完全匹配
foreach
(
var
methodInfo
in
methodInfos
)
{
var
parameterInfos
=
methodInfo
.
GetParameters
();
//全部参数名称
var
names
=
parameterInfos
.
Select
(
pi
=>
pi
.
Name
).
ToList
();
//删除掉 asyncDelegate,asyncContext
names
.
Remove
(
Reflect_OBJ_INTERFACE
.
asyncDelegate
);
names
.
Remove
(
Reflect_OBJ_INTERFACE
.
asyncContext
);
var
names_req
=
parameterNames
;
if
(
names
.
Count
()
!=
names_req
.
Count
())
continue
;
//数量不一致,肯定不同
var
sames
=
names_req
.
Intersect
(
names
);
if
(
sames
.
Count
()
!=
names_req
.
Count
())
continue
;
// names 与 names_req 的交集数量与names_req不一样,肯定不同
//就是它
return
methodInfo
;
}
return
null
;
}
void
asyncDelegate
(
object
asyncContext
,
object
retData
)
{
var
cc
=
(
CC
)
asyncContext
;
var
rData
=
new
Reflect_OBJ_INTERFACE
.
ReflectData
()
{
name
=
cc
.
methodName
,
data
=
retData
==
null
?
null
:
JToken
.
FromObject
(
retData
)
};
Reflect_OBJ_INTERFACE
.
PkgData
pkgData
=
new
Reflect_OBJ_INTERFACE
.
PkgData
(
Reflect_OBJ_INTERFACE
.
PkgName
.
CALL_MethodInvoke
,
cc
.
guid
,
JToken
.
FromObject
(
rData
)
);
string
json
=
JsonConvert
.
SerializeObject
(
pkgData
);
SendEx
(
json
);
}
public
void
Dispose
()
{
if
(
typeof
(
INotifyPropertyChanged
).
IsAssignableFrom
(
interfaceType
))
{
//继承了INotifyPropertyChanged
((
INotifyPropertyChanged
)(
this
.
obj
)).
PropertyChanged
-=
rootNode
.
PropertyChanged
;
}
//释放subProperties
COMMON
.
NodeDispose
(
rootNode
);
}
class
CC
{
public
string
methodName
;
public
string
guid
;
}
}
/// <summary>
/// 事件推送包装
/// </summary>
class
AnyEvent
{
/// <summary>
/// 事件名称
/// </summary>
public
string
eventName
;
/// <summary>
/// json包装后的ReflectData 推送
/// </summary>
public
Action
<
Reflect_OBJ_INTERFACE
.
ReflectData
>
PushObjInfoEx
;
/// <summary>
/// 给 EventInfo 调用
/// </summary>
public
EventHandler
eventHandler
;
public
AnyEvent
()
{
eventHandler
=
new
EventHandler
(
Obj_AnyEvent
);
}
void
Obj_AnyEvent
(
object
sender
,
EventArgs
e
)
{
var
rData
=
new
Reflect_OBJ_INTERFACE
.
ReflectData
()
{
name
=
eventName
,
data
=
JObject
.
FromObject
(
e
)
};
PushObjInfoEx
?.
Invoke
(
rData
);
}
}
}
WSCF.standard/Reflect_SeviceClient.cs
deleted
100644 → 0
View file @
9c0b9932
using
Newtonsoft.Json
;
using
Newtonsoft.Json.Linq
;
using
System
;
using
System.Collections.Generic
;
using
System.ComponentModel
;
using
System.Linq
;
using
System.Net
;
using
System.Reflection
;
using
System.Text
;
using
System.Threading.Tasks
;
namespace
WSCF
{
public
class
Reflect_SeviceClient
:
WebSocketClient
,
IDisposable
{
/// <summary>
/// 忽略设置
/// </summary>
public
bool
ignoreSet
;
/// <summary>
/// 代理对象 接口类型
/// </summary>
protected
virtual
Type
InterfaceType
{
get
;
}
class
AnyEvent
{
public
string
name
;
public
string
triggerName
;
public
Type
retType
;
}
class
AnyCall
{
public
string
name
;
public
Type
retType
;
}
class
AnyMethodInvoke
{
public
string
guid
;
public
AsyncCBHandler
asyncDelegate
;
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
)
{
if
(
isByConnName
==
false
)
{
base
.
Init
(
addrOrConnName
);
}
else
{
base
.
InitByConnName
(
addrOrConnName
);
}
init
();
}
void
init
()
{
rootNode
=
new
SubPropertyNode
{
Obj
=
this
,
InterfaceType
=
InterfaceType
,
SubPropertyChanged
=
Sub_PropertyChanged
};
InitPropertyChanged
();
COMMON
.
InitPropertyPush
(
rootNode
);
InitEventPush
();
InitCall
();
}
void
InitPropertyChanged
()
{
if
(!
typeof
(
INotifyPropertyChanged
).
IsAssignableFrom
(
InterfaceType
))
return
;
//继承了INotifyPropertyChanged
this
.
PropertyChanged
+=
rootNode
.
PropertyChanged
;
var
propertyInfos
=
COMMON
.
GetAllPropertyInfos
(
this
.
InterfaceType
);
//获取全部属性, 包括父类的属性
foreach
(
var
propertyInfo
in
propertyInfos
)
{
if
(
propertyInfo
.
GetCustomAttribute
<
JsonIgnoreAttribute
>()
!=
null
)
continue
;
//这个不需要推送
if
(
properties
.
Contains
(
propertyInfo
.
Name
))
continue
;
properties
.
Add
(
propertyInfo
.
Name
);
}
}
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
=
"Trigger_"
+
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
(!
IsConnected
)
return
;
if
(
ignoreSet
)
//从服务器接收的数据,不用再推送给服务器
return
;
var
type
=
node
.
Obj
.
GetType
();
var
propertyInfo
=
type
.
GetProperty
(
e
.
PropertyName
);
if
(
propertyInfo
==
null
)
return
;
//获取失败!!!
if
(
propertyInfo
.
GetCustomAttribute
<
JsonIgnoreAttribute
>()
!=
null
)
return
;
//这个不需要推送
var
v
=
propertyInfo
.
GetValue
(
node
.
Obj
);
var
jObject
=
new
JObject
();
if
(
v
==
null
)
jObject
.
Add
(
propertyInfo
.
Name
,
null
);
else
jObject
.
Add
(
propertyInfo
.
Name
,
JToken
.
FromObject
(
v
));
var
rData
=
new
Reflect_OBJ_INTERFACE
.
ReflectData
{
name
=
COMMON
.
GetNodePath
(
node
),
data
=
jObject
};
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
()
{
Reflect_OBJ_INTERFACE
.
PkgData
pkgData
=
new
Reflect_OBJ_INTERFACE
.
PkgData
(
Reflect_OBJ_INTERFACE
.
PkgName
.
CALL_GetAllProperties
,
Guid
.
NewGuid
().
ToString
(),
null
);
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
);
switch
(
pkgName
)
{
case
Reflect_OBJ_INTERFACE
.
PkgName
.
PUSH_PropertyChanged
:
case
Reflect_OBJ_INTERFACE
.
PkgName
.
CALL_GetAllProperties
:
{
ignoreSet
=
true
;
var
rData
=
pkgData
.
data
.
ToObject
<
Reflect_OBJ_INTERFACE
.
ReflectData
>();
var
node
=
COMMON
.
FindNode
(
rootNode
,
rData
.
name
);
if
(
node
==
null
)
{
//异常
//服务器乱发过来
break
;
}
string
json
=
rData
.
data
.
ToString
();
JsonConvert
.
PopulateObject
(
json
,
node
.
Obj
);
ignoreSet
=
false
;
}
break
;
case
Reflect_OBJ_INTERFACE
.
PkgName
.
PUSH_Event
:
{
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
});
}
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
)
{
//异常!!!应该有对应的回调
throw
new
Exception
(
$"
{
reponse
.
name
}
异常!!!应该有回调"
);
}
anyMethodInvoke
.
asyncDelegate
.
Invoke
(
anyMethodInvoke
.
asyncContext
,
retData
);
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
);
}
}
}
WSCF.standard/WSCF.standard.csproj
View file @
c021c2f6
...
@@ -18,9 +18,12 @@
...
@@ -18,9 +18,12 @@
<ItemGroup>
<ItemGroup>
<Compile Include="..\WSCF\AsyncCBHandler.cs" Link="AsyncCBHandler.cs" />
<Compile Include="..\WSCF\AsyncCBHandler.cs" Link="AsyncCBHandler.cs" />
<Compile Include="..\WSCF\COMMON.cs" Link="COMMON.cs" />
<Compile Include="..\WSCF\CallAttribute.cs" Link="CallAttribute.cs" />
<Compile Include="..\WSCF\CallAttribute.cs" Link="CallAttribute.cs" />
<Compile Include="..\WSCF\FObjServiceClientManager.cs" Link="FObjServiceClientManager.cs" />
<Compile Include="..\WSCF\FObjServiceClientManager.cs" Link="FObjServiceClientManager.cs" />
<Compile Include="..\WSCF\ReflectData.cs" Link="ReflectData.cs" />
<Compile Include="..\WSCF\ReflectData.cs" Link="ReflectData.cs" />
<Compile Include="..\WSCF\Reflect_Proxy.cs" Link="Reflect_Proxy.cs" />
<Compile Include="..\WSCF\Reflect_SeviceClient.cs" Link="Reflect_SeviceClient.cs" />
<Compile Include="..\WSCF\WebSocketClient.cs" Link="WebSocketClient.cs" />
<Compile Include="..\WSCF\WebSocketClient.cs" Link="WebSocketClient.cs" />
</ItemGroup>
</ItemGroup>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment