在WCF中,有几种不同类型的基于HTTP的绑定:
这3个有什么不同?
特别是在功能/性能和兼容性方面有何不同?
由于BasicHttpsBinding是.net 4.5的新功能,我似乎无法找到两者之间的差异.
我有一个托管为Windows服务的WCF服务,客户端是一个使用WCF服务方法的ASP.Net应用程序.
在实施安全性的过程中,我很困惑哪个netTcpBinding/ 哪个wsHttpBinding适合我的情况.
很可能场景中的所有应用程序(WCF服务,Windows服务,ASP.Net网站)都将位于我们办公室的不同服务器上,因此位于Intranet中.用户可以通过Internet访问ASP.Net网站.
虽然,我总是可以在这里使用wsHttpBinding,它是否适合netTcpBinding在我的情况下设置服务端点?
这是我上周一直在调查的问题,无法找到任何解决方案.发现帖子问同样但从未得到答案,希望这也会帮助其他人.
我有一个WCF服务,返回一个包含stream内部对象的服务.我使用basicHttpBinding流式传输和Mtom将其发送给客户端.
客户端WCF在收到响应对象后立即调用服务并关闭代理.
接下来,客户端读取从WCF服务获取的流并将其写入本地磁盘上的文件.所有这一切都很好.
我的问题是客户端想要中止操作并停止从WCF服务下载数据.如果我.close()在流上调用,例如:serverReply.DataStream.Close();那么它会阻塞并从WCF服务读取整个流,直到它结束,然后再继续.流可能非常大,网络并不总是很快.
这对于网络资源使用都是非常不合需要的,这基本上浪费在不再使用的数据上.并且由于basicHttpBinding只允许两个并发TCP连接(默认情况下)到WCF服务服务器,因此它会阻止其他连接尝试,直到读取流直到结束.
我可以增加并发连接的数量,但这将是一个糟糕的解决方案,因为它会创建一个麻烦的开放.
例如,20个中止的下载仍在下载数据以将其丢弃.我需要完全停止转移.
在客户端上,流对象只是一个常规Stream类,因此它只有close方法,没有别的.
调用.close()或.abort()代理对象没有帮助,也没有使用.dispose()或任何其他方法销毁它.在服务器端,我处理OperationContext.OperationCompleted事件,但是直到stream读取数据直到结束才会触发.
所以问题是,如何在不完全读取流的情况下关闭/中止流?
我正在使用VSTS 2008 + C#+ .NET 3.0.我正在使用自托管的WCF服务.执行以下语句时,会出现以下"未找到绑定"错误.我发布了我的整个app.config文件,任何想法有什么问题?
ServiceHost host = new ServiceHost(typeof(MyWCFService));
Run Code Online (Sandbox Code Playgroud)
错误信息:
无法通过绑定MetadataExchangeHttpBinding找到与端点的方案http匹配的基址.注册的基地址方案是[https].
完整的app.config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="MyBinding"
closeTimeout="00:00:10"
openTimeout="00:00:20"
receiveTimeout="00:00:30"
sendTimeout="00:00:40"
bypassProxyOnLocal="false"
transactionFlow="false"
hostNameComparisonMode="WeakWildcard"
maxReceivedMessageSize="100000000"
messageEncoding="Mtom"
proxyAddress="http://foo/bar"
textEncoding="utf-16"
useDefaultWebProxy="false">
<reliableSession ordered="false"
inactivityTimeout="00:02:00"
enabled="true" />
<security mode="Transport">
<transport clientCredentialType="Digest"
proxyCredentialType="None"
realm="someRealm" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="MyWCFService"
behaviorConfiguration="mexServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="https://localhost:9090/MyService"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="MyBinding" contract="IMyService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="mexServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
</behavior>
</serviceBehaviors> …Run Code Online (Sandbox Code Playgroud) 我有一个案例,我需要使用wsHttp使用WCF 传输大量的序列化对象图(通过NetDataContractSerializer).我正在使用邮件安全性,并希望继续这样做.使用这个设置我想传输序列化的对象图,有时可以接近300MB左右但是当我尝试这样做时,我开始看到System.InsufficientMemoryException类型的异常出现.
经过一些研究后,默认情况下,WCF中默认情况下,服务调用的结果默认包含在单个消息中,其中包含序列化数据,并且默认情况下在服务器上缓冲此数据,直到完整写入整个消息.因此,内存异常是由于服务器的内存资源不足而导致分配的,因为该缓冲区已满.我遇到的两个主要建议是使用流式传输或分块来解决这个问题,但是我不清楚这涉及到什么,以及我的当前设置是否可以使用任何解决方案(wsHttp/NetDataContractSerializer/Message Security).到目前为止,我理解使用流式消息安全性不起作用,因为消息加密和解密需要处理整个数据集而不是部分消息.然而,Chunking听起来似乎有可能,但是我不清楚如何使用我列出的其他约束来完成它.如果有人可以就可用的解决方案以及如何实施它提供一些指导,我将非常感激.
我应该补充一点,在我的情况下,我真的不担心与其他客户端的互操作性,因为我们拥有并控制通信的每一面,并使用共享接口模式传输到任何一方的数据.所以我愿意接受任何符合使用带有消息安全性的wsHttp以转移使用NetDataContractSerializer序列化的对象图的约束的想法,我更喜欢一个解决方案,我不需要大幅改变我现有的服务和周围的基础设施.
相关资源:
我也对可以对这些数据进行的任何类型的压缩感兴趣,但看起来我可能最好在传输级别执行此操作,一旦我可以转换到.NET 4.0,以便客户端将自动支持gzip标题如果我理解正确的话.
关于如何在结论中得出缓冲消息太大导致我的问题的一些历史.最初我在测试时看到了下面的CommunicationException.
底层连接已关闭:连接意外关闭.
最后,在运行此操作并进行更多日志记录后,我发现了导致指定消息出现问题的基础InsufficientMemoryException异常.
无法分配268435456字节的托管内存缓冲区.可用内存量可能很低.
其中源于以下方法.
System.ServiceModel.Diagnostics.Utility.AllocateByteArray(Int32 size)
所以在其他方面,失败来自分配阵列.当写入序列化到磁盘的相同数据时,它需要大约146MB,如果我将其减少一半,那么我就会停止获取错误但是我没有更多地挖掘破坏我的缓冲区的特定阈值以及它是否特定于我的系统或不.
我想在这一点上我正在为以下内容寻找一些澄清.我的理解是,默认情况下WCF wsHttp具有消息安全性,在响应被发送回客户端之前需要在服务器上缓冲整个消息(通常是我正在返回的整个数据集),从而导致我的问题.
可能的解决方案:
限制我可以返回的数据只能达到某一点,并且与Streaming选项一样,这些选项需要在WCF服务调用之外编写许多较低级别的工作.所以我想我需要知道的是,通过允许将一组数据分解为服务器上的单独消息然后在客户端上拼凑在一起,是否任何可能的分块通道实现都可以解决大型消息问题.这样一种方式,我不必改变现有服务合同的接口/形状,并且在仍然使用消息安全性和wsHttp的同时,几乎隐藏了每个服务实现的客户端和服务器部分的过程.如果分块通道要求我重新编写我的服务合同以暴露流,那么我不会 看看这与Streaming解决方案有什么不同.如果有人可以简单地为我回答这些问题,我会给予奖励,并将其标记为答案.
wcf large-data-volumes chunking wshttpbinding netdatacontractserializer
服务器配置:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceCredentialsBehavior">
<serviceCredentials>
<serviceCertificate findValue="cn=cool" storeName="TrustedPeople" storeLocation="CurrentUser" />
</serviceCredentials>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ServiceCredentialsBehavior" name="Service">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="MessageAndUserName" name="SecuredByTransportEndpoint" contract="IService"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="MessageAndUserName">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client/>
</system.serviceModel>
<system.web>
<compilation debug="true"/>
</system.web>
Run Code Online (Sandbox Code Playgroud)
我的客户端配置:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="LocalCertValidation">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust" trustedStoreLocation="CurrentUser" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService" >
<security mode="Message"> …Run Code Online (Sandbox Code Playgroud) 在MSDN上我们可以阅读:
WS2007HttpBinding类添加了类似于WSHttpBinding的系统提供的绑定,但使用了ReliableSession,Security和TransactionFlow协议的结构化信息标准促进组织(OASIS)标准版本.使用此绑定时,不需要更改对象模型或默认设置.
但我没有找到任何可以解释我的文档为什么我想将wsHttpBinding移动到ws2007HttpBinding,在我看来标准是相同的.
有人可以给我一个很好的解释吗?
我正在尝试让Java客户端与WCF wshttpbinding WebService进行通信.但我无法这样做.电话会挂起,或者我得到"musunderstoodheader expcetions".
我的Web服务只是默认的Visual Studio生成的"WCF服务库模板".
我的Web服务客户端只是一个空白的IntelliJ项目,使用"添加Web服务客户端"生成相应的存根(指定的Web服务平台是JAX-WS 2.X).
当我将绑定更改为BasicHttpBinding时,一切都完美无瑕.
我尝试过使用WsHttpBinding配置,包括关闭安全性,但我没有成功.
建议?想法?WAXHttpBinding仅部分支持JAX-WS 2.0吗?
我有一个我正在编码的WCF应用程序.当我改变事物然后再次运行服务调用时,我会多次启动和停止它.
因为我需要会话信息我正在使用wsHttpBinding.
在我搬到wsHttpBinding我正在使用之前basicHttpBinding,我可以停止服务,进行更改并重新启动它.然后我可以针对端点运行我的WCF测试客户端(WCF Storm),它仍然可以正常运行.
现在它告诉我:
邮件无法处理.这很可能是因为" http://tempuri.org/IMyService/MyOperation "操作不正确,或者因为邮件包含无效或过期的安全上下文令牌,或者因为绑定之间存在不匹配.如果服务由于不活动而中止了通道,则安全上下文令牌将无效.要防止服务中止空闲会话,请过早增加服务端点绑定的接收超时.
这意味着我必须刷新我的连接并重新设置我的服务调用(几百次后会变得烦人.).
我读到安全超时是10分钟.我在不到2分钟内重新开始跑步,所以我认为这不是一个超时问题.
我的猜测是令牌因为我杀死并重新启动服务的明显原因而到期.
问题是我根本不需要安全的东西(我只需要会话的东西或者我会使用BasicHttpBinding
反正有没有让我的WCF服务不关心安全上下文令牌?
注意:我的测试客户端默认为wsHttpBinding并具有安全性设置.但我认为这是设置这个因为我的服务是发布它需要安全性.
我尝试过的事情:
我尝试过类似于我在这里找到的配置
<bindings>
<wsHttpBinding>
<binding name="WsEventLogBinding">
<security mode="Message">
<message establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
Run Code Online (Sandbox Code Playgroud)但我真的不知道这意味着什么,或者它是否是我需要的东西(根本没有安全性(现在)).
这并没有消除这个问题.
<security mode="None"> 这没有帮助.wshttpbinding ×10
wcf ×8
.net ×3
wcf-binding ×3
c# ×2
web-services ×2
certificate ×1
chunking ×1
java ×1
mtom ×1
security ×1
stream ×1