项目中有个告警实时推送的功能,需要服务端推送告警事件给客户端,打算用WCF的Callback实现的,用WPF客户端模拟成功了,但是放到Unity中就不行,提示:
System.NotImplementedException: The requested feature is not implemented.
at System.ServiceModel.DuplexClientBase`1[TChannel].CreateChannel () [0x00000] in <filename unknown>:0
at System.ServiceModel.ClientBase`1[TChannel].get_InnerChannel () [0x00000] in <filename unknown>:0
at System.ServiceModel.ClientBase`1[TChannel].get_Channel () [0x00000] in <filename unknown>:0
at Location.WCFServiceReferences.LocationCallbackServices.LocationAlarmServiceClient.Connect () [0x00001] in D:\GitHub\LocationSystem\Client\WPFWCFClient\Location.WCFServiceReferences\Service References\LocationCallbackServices\Reference.cs:991
at Location.WCFServiceReferences.LocationCallbackClient.Connect () [0x00009] in D:\GitHub\LocationSystem\Client\WPFWCFClient\Location.WCFServiceReferences\LocationCallbackClient.cs:41
UnityEngine.Debug:LogError(Object)
WCFClientTest:GetLocationServiceClient() (at Assets/Scripts/WCFClientTest.cs:115)
WCFClientTest:GetTopoList() (at Assets/Scripts/WCFClientTest.cs:259)
WCFClientTest:Start() (at Assets/Scripts/WCFClientTest.cs:18)
搜索到一个资料:https://answers.unity.com/questions/557434/how-to-solve-notimplementedexception-during-using.html
里面的问题和我的完全一样,后面的解答是替换 System.ServiceModel.dll and System.Runtime.Serialization.dll。问题是给的路径不能用。而用unity安装目录中的另外一个大一点的System.ServiceModel.dll不行,用WPC测试程序引用的相应的dll(3.0版本的)也不行。
猜测是CallbackContract导致的,去掉,先不管回调,用TCP方式调用一般的WCF方法行不行,结果还是不行,提示
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NotSupportedException: Operation is not supported.
at System.ServiceModel.Channels.SecurityChannelFactory`1[System.ServiceModel.Channels.IDuplexSessionChannel].OnCreateChannel (System.ServiceModel.EndpointAddress remoteAddress, System.Uri via) [0x00000] in <filename unknown>:0
at System.ServiceModel.Channels.ChannelFactoryBase`1[System.ServiceModel.Channels.IDuplexSessionChannel].CreateChannel (System.ServiceModel.EndpointAddress remoteAddress, System.Uri via) [0x00000] in <filename unknown>:0
at System.ServiceModel.Channels.TransactionChannelFactory`1[System.ServiceModel.Channels.IDuplexSessionChannel].OnCreateChannel (System.ServiceModel.EndpointAddress remoteAddress, System.Uri via) [0x00000] in <filename unknown>:0
at System.ServiceModel.Channels.ChannelFactoryBase`1[System.ServiceModel.Channels.IDuplexSessionChannel].CreateChannel (System.ServiceModel.EndpointAddress remoteAddress, System.Uri via) [0x00000] in <filename unknown>:0
at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x000d0] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222
--- End of inner exception stack trace ---
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x000eb] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:232
at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MethodBase.cs:115
at System.ServiceModel.ClientRuntimeChannel..ctor (System.ServiceModel.Dispatcher.ClientRuntime runtime, System.ServiceModel.Description.ContractDescription contract, TimeSpan openTimeout, TimeSpan closeTimeout, IChannel contextChannel, IChannelFactory factory, System.ServiceModel.Channels.MessageVersion messageVersion, System.ServiceModel.EndpointAddress remoteAddress, System.Uri via) [0x00000] in <filename unknown>:0
at System.ServiceModel.ClientRuntimeChannel..ctor (System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.ChannelFactory channelFactory, System.ServiceModel.EndpointAddress remoteAddress, System.Uri via) [0x00000] in <filename unknown>:0
at __clientproxy_ILocationAlarmService..ctor (System.ServiceModel.Description.ServiceEndpoint , System.ServiceModel.ChannelFactory , System.ServiceModel.EndpointAddress , System.Uri ) [0x00000] in <filename unknown>:0
at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (object,object[],System.Exception&)
at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00119] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:513
--- End of inner exception stack trace ---
at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0012c] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:519
at System.Reflection.MonoCMethod.Invoke (BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:528
at System.Activator.CreateInstance (System.Type type, BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object[] args, System.Globalization.CultureInfo culture, System.Object[] activationAttributes) [0x001b8] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Activator.cs:338
at System.Activator.CreateInstance (System.Type type, System.Object[] args, System.Object[] activationAttributes) [0x00000] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Activator.cs:268
at System.Activator.CreateInstance (System.Type type, System.Object[] args) [0x00000] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Activator.cs:263
at System.ServiceModel.ChannelFactory`1[Location.WCFServiceReferences.LocationCallbackServices.ILocationAlarmService].CreateChannel (System.ServiceModel.EndpointAddress address, System.Uri via) [0x00000] in <filename unknown>:0
at System.ServiceModel.ChannelFactory`1[Location.WCFServiceReferences.LocationCallbackServices.ILocationAlarmService].CreateChannel (System.ServiceModel.EndpointAddress address) [0x00000] in <filename unknown>:0
at System.ServiceModel.ChannelFactory`1[Location.WCFServiceReferences.LocationCallbackServices.ILocationAlarmService].CreateChannel () [0x00000] in <filename unknown>:0
at System.ServiceModel.ClientBase`1[TChannel].CreateChannel () [0x00000] in <filename unknown>:0
at System.ServiceModel.ClientBase`1[TChannel].get_InnerChannel () [0x00000] in <filename unknown>:0
at System.ServiceModel.ClientBase`1[TChannel].get_Channel () [0x00000] in <filename unknown>:0
at Location.WCFServiceReferences.LocationCallbackServices.LocationAlarmServiceClient.Connect () [0x00001] in D:\GitHub\LocationSystem\Client\WPFWCFClient\Location.WCFServiceReferences\Service References\LocationCallbackServices\Reference.cs:56
at Location.WCFServiceReferences.LocationCallbackClient.Connect () [0x00009] in D:\GitHub\LocationSystem\Client\WPFWCFClient\Location.WCFServiceReferences\LocationCallbackClient.cs:42
UnityEngine.Debug:LogError(Object)
WCFClientTest:GetLocationServiceClient() (at Assets/Scripts/WCFClientTest.cs:115)
WCFClientTest:GetTopoList() (at Assets/Scripts/WCFClientTest.cs:259)
WCFClientTest:Start() (at Assets/Scripts/WCFClientTest.cs:18)
这里有个Duplex,应该是双通道tcp的意思,也就是说unity不支持wcf的双通道tcp模式?
另外,用http的话我没问题的,能够正常获取数据。
实在不行考虑写一个轮询,客户端自己去获取告警事件。怎么区分当前告警列表和新增告警事件呢?新的告警事件什么时候进入告警列表中呢。
客户端自己轮询获取告警列表,服务端要在该客户端第一次查询时提供当前所有告警列表,而在后续查询(轮询)时提供新增的事件(可以分成两个指令)。服务端那边要维护一个列表,该客户端以及获取到的告警,该客户端未获取到的告警。
每个客户端进来都要维护一份,这个让我想起来刚刚看到的一个Web实时事件技术SignalR,而且还正好有相关资料。
两种方案,轮询的可以写一下作为练习用,SignalR肯定也是要实现一下看看。