热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

WCF开发(9)Unity连接WCF

参考:https:www.cnblogs.comJLZT1223p6062613.html和一般连接WCF的不同之处:1.要手动添加必要的dll2

参考:https://www.cnblogs.com/JLZT1223/p/6062613.html

和一般连接WCF的不同之处:

1.要手动添加必要的dll

2.要手动创建客户端代码(用svcutil.exe)



我用D盘的绝对路径是因为不加路径会导致无法创建文件,以管理员方式启动cmd的话应该就没问题。

System.Runtime.Serialization.dll不用添加,添加了会说已经存在。我的Unity是5.6.03f

生成文件内容:

//------------------------------------------------------------------------------
//
// 此代码由工具生成。
// 运行时版本:2.0.50727.8825
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
//

//------------------------------------------------------------------------------[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="WCFServiceLib", ConfigurationName="ICommonService")]
public interface ICommonService {[System.ServiceModel.OperationContractAttribute(Action="WCFServiceLib/ICommonService/Hello", ReplyAction="WCFServiceLib/ICommonService/HelloResponse")]string Hello(string name);[System.ServiceModel.OperationContractAttribute(Action="WCFServiceLib/ICommonService/GetString", ReplyAction="WCFServiceLib/ICommonService/GetStringResponse")]string GetString(int count, string item);[System.ServiceModel.OperationContractAttribute(Action="WCFServiceLib/ICommonService/SendString", ReplyAction="WCFServiceLib/ICommonService/SendStringResponse")]string SendString(string msg);[System.ServiceModel.OperationContractAttribute(Action="WCFServiceLib/ICommonService/GetData", ReplyAction="WCFServiceLib/ICommonService/GetDataResponse")]WCFModels.DataInfo GetData(string id, string name);[System.ServiceModel.OperationContractAttribute(Action="WCFServiceLib/ICommonService/SendData", ReplyAction="WCFServiceLib/ICommonService/SendDataResponse")]string SendData(WCFModels.DataInfo data);
}[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface ICommonServiceChannel : ICommonService, System.ServiceModel.IClientChannel {
}[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class CommonServiceClient : System.ServiceModel.ClientBase, ICommonService {public CommonServiceClient() {}public CommonServiceClient(string endpointConfigurationName) : base(endpointConfigurationName) {}public CommonServiceClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) {}public CommonServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) {}public CommonServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress) {}public string Hello(string name) {return base.Channel.Hello(name);}public string GetString(int count, string item) {return base.Channel.GetString(count, item);}public string SendString(string msg) {return base.Channel.SendString(msg);}public WCFModels.DataInfo GetData(string id, string name) {return base.Channel.GetData(id, name);}public string SendData(WCFModels.DataInfo data) {return base.Channel.SendData(data);}
}
namespace WCFModels {using System.Runtime.Serialization;[System.Diagnostics.DebuggerStepThroughAttribute()][System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")][System.Runtime.Serialization.DataContractAttribute(Name="DataInfo", Namespace="http://schemas.datacontract.org/2004/07/WCFModels")]public partial class DataInfo : object, System.Runtime.Serialization.IExtensibleDataObject {private System.Runtime.Serialization.ExtensionDataObject extensionDataField;private string IdField;private string NameField;private string TextField;public System.Runtime.Serialization.ExtensionDataObject ExtensionData {get {return this.extensionDataField;}set {this.extensionDataField = value;}}[System.Runtime.Serialization.DataMemberAttribute()]public string Id {get {return this.IdField;}set {this.IdField = value;}}[System.Runtime.Serialization.DataMemberAttribute()]public string Name {get {return this.NameField;}set {this.NameField = value;}}[System.Runtime.Serialization.DataMemberAttribute()]public string Text {get {return this.TextField;}set {this.TextField = value;}}}
}
脚本中测试

private void TestCommonServiceClient(){CommonServiceClient client = GetCommonServiceClient(WCFClient.Instance.Ip);client.SendString("CommonServiceClient Start");WCFModels.DataInfo data = client.GetData("1", "2");Write(string.Format("{0},{1}", data.Id, data.Name));}public static CommonServiceClient GetCommonServiceClient(string ip){NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);binding.MaxReceivedMessageSize = int.MaxValue;EndpointAddress endpointAddress = new EndpointAddress("net.tcp://" + ip + ":8001/CommonService");CommonServiceClient currentClient = new CommonServiceClient(binding, endpointAddress);return currentClient;}可以

接下来试试这部分代码在Hololens中能不能正常运行。

当初的最终目标就是在Hololens中使用wcf的,因为Hololens的运行环境是UWP,所以先研究了在UWP中使用WCF,然后再通过接口的方式在脚本中使用。

这么看来可能不需要这样。

等待后续测试吧,说不定在Hololens中不能使用呢。

=======================================================

svcutil生成的代码中的 数据类型 和 Unity引用的dll中的数据类型重复了,必须手动删除那部分代码。想让svcutil只生成客户代码,添加-reference:参数,没用,还是会生成。

用VS生成的话,只要客户端项目引用了数据类型所在的dll就不会重新创建这些类型的代码了了。

但是用VS添加服务引用生成的代码中包含异步调用的代码...

将客户端项目修改为3.5的(原本是4.5的),异步调用代码就没有了。

不使用svcutil.exe,还是用VS 项目生成代码吧,再移动到Unity中好了。
==========================================================

考虑到异步处理,还是用回调函数的方式处理返回结果,做一个Unity版本的WCFClient

将UWP中的代码移动到Unity中,相应的修改代码(基本上去掉async和await就行了),语法没问题,测试。

问题1:

获取列表数据时数量没问题,但是无法获取具体数据内容。发现是因为数据类中没有添加DataContract和DataMember,但是用UWP的话可以,之前有测试过的,没加相当于全加上的,但是这样看来在这里不适用。加上合适的DataContract和DataMember就可以了,加[Serializable]没用(《WCF服务编程》里面是说可以的)。

问题2:

MainTest:System.Xml.XmlException: Text content buffer exceeds the quota limitation at 5339. 12220 bytes and should be less than 8192 bytesat System.Xml.XmlBinaryDictionaryReader.Alloc (Int32 size) [0x00000] in :0 at System.Xml.XmlBinaryDictionaryReader.ReadTextOrValue (Byte ident, System.Xml.NodeInfo node, Boolean canSkip) [0x00000] in :0 at System.Xml.XmlBinaryDictionaryReader.Read () [0x00000] in :0 at System.Xml.XmlReader.Skip () [0x00000] in :0 at System.Runtime.Serialization.SerializationMap.DeserializeContent (System.Xml.XmlReader reader, System.Runtime.Serialization.XmlFormatterDeserializer deserializer, Boolean empty) [0x00000] in :0 at System.Runtime.Serialization.SerializationMap.DeserializeContent (System.Xml.XmlReader reader, System.Runtime.Serialization.XmlFormatterDeserializer deserializer) [0x00000] in :0 at System.Runtime.Serialization.SerializationMap.DeserializeObject (System.Xml.XmlReader reader, System.Runtime.Serialization.XmlFormatterDeserializer deserializer) [0x00000] in :0 at System.Runtime.Serialization.XmlFormatterDeserializer.DeserializeByMap (System.Xml.XmlQualifiedName name, System.Type type, System.Xml.XmlReader reader) [0x00000] in :0 at System.Runtime.Serialization.XmlFormatterDeserializer.DeserializeCore (System.Type type, System.Xml.XmlReader reader) [0x00000] in :0 at System.Runtime.Serialization.XmlFormatterDeserializer.Deserialize (System.Type type, System.Xml.XmlReader reader) [0x00000] in :0 at System.Runtime.Serialization.CollectionTypeMap.DeserializeContent (System.Xml.XmlReader reader, System.Runtime.Serialization.XmlFormatterDeserializer deserializer) [0x00000] in :0 at System.Runtime.Serialization.SerializationMap.DeserializeObject (System.Xml.XmlReader reader, System.Runtime.Serialization.XmlFormatterDeserializer deserializer) [0x00000] in :0 at System.Runtime.Serialization.XmlFormatterDeserializer.DeserializeByMap (System.Xml.XmlQualifiedName name, System.Type type, System.Xml.XmlReader reader) [0x00000] in :0 at System.Runtime.Serialization.XmlFormatterDeserializer.DeserializeCore (System.Type type, System.Xml.XmlReader reader) [0x00000] in :0 at System.Runtime.Serialization.XmlFormatterDeserializer.Deserialize (System.Type type, System.Xml.XmlReader reader) [0x00000] in :0 at System.Runtime.Serialization.XmlFormatterDeserializer.Deserialize (System.Xml.XmlReader reader, System.Type type, System.Runtime.Serialization.KnownTypeCollection knownTypes, IDataContractSurrogate surrogate, System.String name, System.String ns, Boolean verifyObjectName) [0x00000] in :0 at System.Runtime.Serialization.DataContractSerializer.ReadObject (System.Xml.XmlDictionaryReader reader, Boolean verifyObjectName) [0x00000] in :0 at System.Runtime.Serialization.XmlObjectSerializer.ReadObject (System.Xml.XmlDictionaryReader reader) [0x00000] in :0 at System.ServiceModel.Dispatcher.DataContractMessagesFormatter.MessageToParts (System.ServiceModel.Description.MessageDescription md, System.ServiceModel.Channels.Message message) [0x00000] in :0 at System.ServiceModel.Dispatcher.BaseMessagesFormatter.DeserializeReply (System.ServiceModel.Channels.Message message, System.Object[] parameters) [0x00000] in :0 at System.ServiceModel.ClientRuntimeChannel.Request (System.ServiceModel.Description.OperationDescription od, System.Object[] parameters) [0x00000] in :0 at System.ServiceModel.ClientRuntimeChannel.DoProcess (System.Reflection.MethodBase method, System.String operationName, System.Object[] parameters) [0x00000] in :0 at System.ServiceModel.ClientRuntimeChannel.Process (System.Reflection.MethodBase method, System.String operationName, System.Object[] parameters) [0x00000] in :0
UnityEngine.Debug:Log(Object)
应该是反序列化时数据量太大了。是因为有一个字符串属性的字符串内容长度为12220导致的。



两个都是反序列化的问题,一般来说是没问题的(正常添加DataContract,一个字符串属性长度不要太大)。

结论:可以使用。

=====================================================================

打包成Hololens的SLN时有问题,

 1. System.ServiceModel.dll重复了,说是已经存在了。修改dll的设置,WSAPlayer不选,只在Unity中使用。


 2. 前面生成的客户端代码不能用,特性相关的dll不能使用。修改代码,整个WCF客户端代码文件用#if UNITY_EDITOR包起来,只在Unity中测试用。

虽然在Hololens中无法使用,但是不如说正好接上UWP中的版本,一个用于在Unity中测试,测试好后再打包到UWP中测试,能显著减少打包成UWP的次数。



推荐阅读
  • 我有一个从C项目编译的.o文件,该文件引用了名为init_static_pool ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中配置 fstab 文件以实现开机自动挂载 NFS 共享目录的方法,并解决了常见的配置失败问题。 ... [详细]
  • 在分析Android的Audio系统时,我们对mpAudioPolicy->get_input进行了详细探讨,发现其背后涉及的机制相当复杂。本文将详细介绍这一过程及其背后的实现细节。 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 本文总结了一些开发中常见的问题及其解决方案,包括特性过滤器的使用、NuGet程序集版本冲突、线程存储、溢出检查、ThreadPool的最大线程数设置、Redis使用中的问题以及Task.Result和Task.GetAwaiter().GetResult()的区别。 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • Java高并发与多线程(二):线程的实现方式详解
    本文将深入探讨Java中线程的三种主要实现方式,包括继承Thread类、实现Runnable接口和实现Callable接口,并分析它们之间的异同及其应用场景。 ... [详细]
  • 在CentOS 7环境中安装配置Redis及使用Redis Desktop Manager连接时的注意事项与技巧
    在 CentOS 7 环境中安装和配置 Redis 时,需要注意一些关键步骤和最佳实践。本文详细介绍了从安装 Redis 到配置其基本参数的全过程,并提供了使用 Redis Desktop Manager 连接 Redis 服务器的技巧和注意事项。此外,还探讨了如何优化性能和确保数据安全,帮助用户在生产环境中高效地管理和使用 Redis。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • 在Cisco IOS XR系统中,存在提供服务的服务器和使用这些服务的客户端。本文深入探讨了进程与线程状态转换机制,分析了其在系统性能优化中的关键作用,并提出了改进措施,以提高系统的响应速度和资源利用率。通过详细研究状态转换的各个环节,本文为开发人员和系统管理员提供了实用的指导,旨在提升整体系统效率和稳定性。 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • Python 程序转换为 EXE 文件:详细解析 .py 脚本打包成独立可执行文件的方法与技巧
    在开发了几个简单的爬虫 Python 程序后,我决定将其封装成独立的可执行文件以便于分发和使用。为了实现这一目标,首先需要解决的是如何将 Python 脚本转换为 EXE 文件。在这个过程中,我选择了 Qt 作为 GUI 框架,因为之前对此并不熟悉,希望通过这个项目进一步学习和掌握 Qt 的基本用法。本文将详细介绍从 .py 脚本到 EXE 文件的整个过程,包括所需工具、具体步骤以及常见问题的解决方案。 ... [详细]
  • 利用 Python Socket 实现 ICMP 协议下的网络通信
    在计算机网络课程的2.1实验中,学生需要通过Python Socket编程实现一种基于ICMP协议的网络通信功能。与操作系统自带的Ping命令类似,该实验要求学生开发一个简化的、非标准的ICMP通信程序,以加深对ICMP协议及其在网络通信中的应用的理解。通过这一实验,学生将掌握如何使用Python Socket库来构建和解析ICMP数据包,并实现基本的网络探测功能。 ... [详细]
author-avatar
mmakarlen
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有