首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web Service >

Silverlight+WCF双工有关问题,初学者,

2012-12-22 
Silverlight+WCF双工问题,菜鸟求助,急本帖最后由 alian_1126 于 2011-03-13 10:56:49 编辑我在Silverlight

Silverlight+WCF双工问题,菜鸟求助,急
本帖最后由 alian_1126 于 2011-03-13 10:56:49 编辑 我在Silverlight项目里添加了WCF服务引用,在Page.xaml.cs里用Service References智能提示可以弹出WCF服务接口IXMLService和IXMLServiceClient,却弹不出回调接口IXMLServiceCallBack,为什么啊,我要在SL里实现这个回调啊,弹不出来怎么实现啊,刚学,遇到问题了,前辈们帮帮我,谢谢
以下是WCF里的代码


//契约
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel;

namespace WcfService
{
    [ServiceContract(CallbackContract = typeof(IXMLClient))]
    public interface IXMLService//服务接口
    {
        [OperationContract(IsOneWay = true)]
        void GetData(Uri uri);
    }
    
    public interface IXMLClient//回调接口
    {
        [OperationContract(IsOneWay = true)]
        void BackToClient(String xmlData);
    }
}
//服务
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Text;
using System.Net;

namespace WcfService
{
    
    public class Service:IXMLService
    {
        IXMLClient client = OperationContext.Current.GetCallbackChannel<IXMLClient>();
        public void GetData(Uri uri)
        {
            WebClient webclient = new WebClient();
            webclient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webclient_DownloadStringCompleted);
            webclient.DownloadStringAsync(uri);
        }

        void webclient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            //throw new NotImplementedException();
            if (null == e.Error) { return; }
            client.BackToClient(e.Result);
        }
    }
}

[最优解释]
仔细看了下你前面说的内容,你现在能看到 IXMLServiceClient 是吧。
IXMLServiceClient里是什么内容?

另外现在用的 WSDualHttpBinding 还需要定义 cliendAddress。你现在还没有定义。

[其他解释]
1. IXMLClient client = OperationContext.Current.GetCallbackChannel<IXMLClient>();
你应该放到你GetData方法里,另外GetData应该用同步的DownloadString,否则客户端会死掉。

2. 客户端要把带有回调实例的InstanceContext加到WCF Client里去。
[其他解释]
你这是什么协议的?


[其他解释]
wsDualHttpBinding,寄宿在IIS中?
[其他解释]
哦,我刚才测试了一下,原先我们有一个WCF服务是net.tcp的,以前都是通过svcutil.exe来生成代理类。
刚才我测试了一下,新建silverlight工程,然后添加服务引用net.tcp://xxx.xxx.xxx.xxx:8001/wcfservice,能生成回调方法。
你这个改为下面的试试看行不行
接口那里添加SessionMode = SessionMode.Required
服务那里添加[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
[其他解释]
ServiceReferences.IXMLClientCallback -> ServiceReferences.IXMLClient

服务端也没有定义叫 IXMLClientCallback 的接口
[其他解释]
搜索了半天,才找到net.tcp不适合公网,WSDualHttpBinding适合公网这种说法的来源。
http://social.msdn.microsoft.com/Forums/zh-CN/wcfzhchs/thread/6db85086-a121-460a-9f1d-06921fb93166
这里这位大牛说的是吧?多数谬论就是这样一传十十传百出来的,我不太相信如果我手里有一块煤炭是黑的,人们在论坛上就可以把它生生说成白的。

楼主的问题是不能在引用时生成回调方法,[ServiceContract(CallbackContract = typeof(IXMLClient))]本身就为service定义了回调接口,还何必显式指定。引用时不能得到回调方法和方法具体实现没有关系。
[其他解释]
不行的话,服务端契约,明确定义下名字也行。

 [ServiceContract(Name="IXMLClientCallback")]
 public interface IXMLClient//回调接口
    {
        [OperationContract(IsOneWay = true)]
        void BackToClient(String xmlData);
    }

[其他解释]
SL 的 WCF 使用果然有些不同,看看这篇文章:

http://www.cnblogs.com/li_g_7711/archive/2009/11/02/1594584.html
[其他解释]
来人帮帮忙啊
[其他解释]

引用:
你这是什么协议的?


<?xml version="1.0"?>
<!--
    注意: 除了手动编辑此文件以外, 
    还可以使用 Web 管理工具来配置应用程序的设置。
    可以使用 Visual Studio 中的“网站”->“Asp.Net 配置”选项。
    设置和注释的完整列表在 
    machine.config.comments 中,该文件通常位于 
    \Windows\Microsoft.Net\Framework\v2.x\Config 
-->
<configuration>
  <configSections>
    <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
        <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
        <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">


          <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
          <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
          <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
          <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
        </sectionGroup>
      </sectionGroup>
    </sectionGroup>
  </configSections>
  <appSettings/>
  <connectionStrings/>
  <system.web>
    <!--
            设置 compilation debug="true" ,将调试符号 
            插入已编译的页面中。但由于这会影响性能, 
           因此请只在开发过程中 
            将此值设置为 true。
        -->
    <compilation debug="true">
      <assemblies>
        <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </assemblies>
    </compilation>
    <!--
            通过 <authentication> 节可以配置
            ASP.NET 使用的安全身份验证 
            模式,以标识传入的用户。 
        -->
    <authentication mode="Windows"/>
    <!--
            通过 <customErrors> 节可以配置在执行请求过程中出现未处理错误时, 
           应执行的操作。 
            具体说来,开发人员通过该节 
            可以配置要显示的 html 错误页 
            以代替错误堆栈跟踪。

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">


            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
        -->
    <pages>
      <controls>
        <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </controls>
    </pages>
    <httpHandlers>
      <remove verb="*" path="*.asmx"/>
      <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
    </httpHandlers>
    <httpModules>
      <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    </httpModules>
  </system.web>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <providerOption name="CompilerVersion" value="v3.5"/>
        <providerOption name="WarnAsError" value="false"/>
      </compiler>
    </compilers>
  </system.codedom>
  <!--
        在 Internet 信息服务 7.0 下,运行 ASP.NET AJAX 要求 
      system.webServer 节。这在以前版本的 IIS 中并非必需。
    -->
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules>
      <add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    </modules>
    <handlers>
      <remove name="WebServiceHandlerFactory-Integrated"/>
      <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>


      <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    </handlers>
  </system.webServer>
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <services>
      <service behaviorConfiguration="WcfService.ServiceBehavior" name="WcfService.Service">
        <endpoint address="" binding="wsDualHttpBinding" contract="WcfService.IXMLService"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost/XMLService"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WcfService.ServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>


我WCF配置文件是这样的
[其他解释]

<configuration>
    <system.serviceModel>
        <bindings />
        <client />
    </system.serviceModel>
</configuration>

Silverlight项目里的ServiceReferences.ClientConfig是这样的
[其他解释]
引用:
wsDualHttpBinding,寄宿在IIS中?

没在IIS哦,SL项目和WCF项目在同一个解决方案里面,我在SL添加服务引用的时候WCF就在VS里自动运行了的
[其他解释]
另外wsDualHttpBinding只支持局域网,如果是公网的需要改成net.tcp
[其他解释]
引用:
另外wsDualHttpBinding只支持局域网,如果是公网的需要改成net.tcp


说反了吧。。。
[其他解释]
引用:

说反了吧。。。

我们用了一年半的net.tcp被神赋予了特殊的公网双工功能。
[其他解释]
引用:
引用:
说反了吧。。。

我们用了一年半的net.tcp被神赋予了特殊的公网双工功能。

呵呵,那么你们是vpn,就算我开端口,你能用net.tcp访问到我么?
http和tcp协议,ls查查资料好。
[其他解释]
弄VPN就多余了。
我现在就在家,电信宽带,公司的是网通服务器,我也不知道咋就双工了,而且持续了一年多。
wsDualHttpBinding本质还是http,只不过服务器和客户端作为对等关系,如果在公网上双工通信,客户端必须暴露给服务端一个可用的公网地址(并非客户端项服务段发起时的地址),这在现实中是不可能的。
http tcp我压根不动,我只知道瞎做。
[其他解释]
引用:
1. IXMLClient client = OperationContext.Current.GetCallbackChannel<IXMLClient>();
你应该放到你GetData方法里,另外GetData应该用同步的DownloadString,否则客户端会死掉。

2. 客户端要把带有回调实例的InstanceContext加到WCF Client里去。

前辈,我看资料说是实现WCF的回调接口生成回调实例,再用回调实例生成InstanceContext的Context对象,再把这个Context对象加到WCF Client,可以我找不到我WCF里的回调接口来实现哦,例如:

public class ClientCallback: ServiceReferences.IXMLClientCallback//这里点不出来这个回调契约让我实现啊
    {
        //...
    }
InstanceContext instanceContext = new InstanceContext(new ClientCallback());
ServiceReference.XMLServiceClient = new ServiceReference.XMLServiceClient(instanceContext);

[其他解释]
引用:
ServiceReferences.IXMLClientCallback -> ServiceReferences.IXMLClient

服务端也没有定义叫 IXMLClientCallback 的接口

我服务端定义了IXMLClient这个接口,可是也点不出来哦,网上说客户端实现回调接口,使用VS自动生成代理的时候,对于回调接口的命名默认是以服务契约接口名称+Callback,可我不管IXMLClient(我定义的)还是IXMLServiceCallback(听说是默认的)都点不出来,
这里有说http://www.cnblogs.com/homezzm/archive/2009/12/18/1626939.html
[其他解释]
ls的,回调不在客户端实现,服务端怎么回调呢?

wsDualHttpBinding背后是http协议,
netTcpBinding 背后是tcp协议
http更易于穿越防火墙,tcp即便是在一个局域网内,还要受限于网段
公网更要受限于不同的网关还有防火墙,因此说是http协议更适合于公网
因为http是非持续性连接,所以http要实现双工通信必须要在客户端也公开出
http服务让服务端能够回调。

你的tcp能够在公网上实现双工通信必定是你在公网上能直接访问到公司的公网IP
我说的不适合不是说不能用。

[其他解释]
引用:
不行的话,服务端契约,明确定义下名字也行。

[ServiceContract(Name="IXMLClientCallback")]
 public interface IXMLClient//回调接口
  {
  [OperationContract(IsOneWay = true)]
  void BackToClient(String xmlData);
  }

我在Silverlight.web项目里添加服务引用是有IXMLServiceCallback这个接口的哦,但是在Silverlight项目里添加服务引用就没有,是不是我哪里搞错了?
Silverlight项目的服务引用里有IXMLService、IXMLServiceChannel、XMLServiceClient、XMLService.XMLServiceClientChannel;
Silverlight.web项目服务引用里的是IXMLService、IXMLServiceCallback、IXMLServiceChannel、XMLServiceClient;
我在Silverlight项目里怎么才能用上Silverlight.web项目里的IXMLServiceCallback啊
[其他解释]
引用:
ls的,回调不在客户端实现,服务端怎么回调呢?

wsDualHttpBinding背后是http协议,
netTcpBinding 背后是tcp协议
http更易于穿越防火墙,tcp即便是在一个局域网内,还要受限于网段
公网更要受限于不同的网关还有防火墙,因此说是http协议更适合于公网
因为http是非持续性连接,所以http要实现双工通信必须要在客户端也……

Silverlight net.TCP 不适合公网是因为没有安全传输.但这并非必须,而且可以通过应用层加密来解决.
------其他解决方案--------------------


引用:
ls的,回调不在客户端实现,服务端怎么回调呢?

wsDualHttpBinding背后是http协议,
netTcpBinding 背后是tcp协议
http更易于穿越防火墙,tcp即便是在一个局域网内,还要受限于网段
公网更要受限于不同的网关还有防火墙,因此说是http协议更适合于公网
因为http是非持续性连接,所以http要实现双工通信必须要在客户端也……


通常公司的服务器有公网IP比较容易,而客户端经常在NAT后面.
而且,提供对外服务的话,有公网IP或者合适的端口映射是基本条件

热点排行