Artech

Develop every application as an art using the most suitable technologies!

常用链接

统计

积分与排名

网上邻居

我的博文系列

最新评论

[原创]我的WCF之旅(3):在WCF中实现双向通信(Bi-directional Communication)

昨天写了一篇Remoting中如何实现双向通信的文章《[原创].NET Remoting: 如何通过Remoting实现双向通信(Bidirectional Communication) 》,作为对比,今天我们来讨论一下WCF的双向通信。

为了使我们能够更好地对比双向通信在Remoting中和WCF中的实现,我们的Sample采用一样的业务逻辑——调用一个数学计算的远程调用,除了传递相应的操作数之外,我们还传递一个对象,这个对象可以在Server端中回调 (Callback) 把运算结果在Client端显示出来。
可以通过下面的URL下载源代码:
http://www.cnblogs.com/files/artech/Artech.WCFService.2007.03.02.zip

Step1:构建整个Solution的整体构架。


整个Solution的架构在我的之前的Blog有了详细的介绍([原创]我的WCF之旅(1):创建一个简单的WCF程序),这里只作一个简单的介绍。

  • Artech.WCFService.Contract: Class Library Project,用来保存Contract(Service Contact、Message Contract、Data Contract), 之所以把Contract独立出来的原因是考虑到他同时被Server端——Service本身和Service Hosting和Client端使用
  •  Artech.WCFService.Service:Class Library Project,Service的业务逻辑, 这个Project引用Artech.WCFService.Contract Project和System.ServiceModel DLL。
  •  Artech.WCFService.Hosting:Console Application, 用于以Self-Hosting的方式Host Service。这个Project引用Artech.WCFService.Contract和Artech. Project WCFService.Service。Project和System.ServiceModel DLL。
  •  Artech.WCFService.Client:Console Application, 用以模拟现实中的调用Service的Clinet。这个Project引用Artech.WCFService.Contract Project 和System.ServiceModel DLL。
  •  http://localhost/WCFService: Web Site Project, 用于模拟如何把Service Host到IIS中。这个Project引用Artech.WCFService.Contract、Artech.WCFService.Service和System.ServiceModel DLL。

Step 2 在Artech.WCFService.Contract定义Calculator Service 和Callback的Contract

1.IDuplexCalculator.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;

namespace Artech.WCFService.Contract
{
     [ServiceContract(CallbackContract 
= typeof(ICalculatorCallback))]
    
public interface IDuplexCalculator
    
{
         [OperationContract]
        
void Add(double x, double y);
    }

}
2.ICalculatorCallback.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;

namespace Artech.WCFService.Contract
{
    [ServiceContract]
    
public interface ICalculatorCallback
    
{
        [OperationContract]
        
void ShowResult(double x, double y, double result);
    }

}
这里有以下几点需要注意的:

 

1.在一个分布式的环境中,Client能够调用Service,它必须知道Service的Contract, Contract定义了Service暴露给外界的所有可用的Operation,以及这些Operation的签名(Signature).至于Service中定义的Opertion采用怎样的实现,Client不需要了解。这也是在WCF中把Service Contract与具体的Service Implementation相互分离的一个重要原因——我们把Contract单独提取出来,把他暴露给Client,从而可以避免把过多的暴露业务逻辑的实现。

2.在一个分布式的环境中,Serer端和Client并不是一成不变的,他们是可以相互转化的。提供服务的就是Server,消费Service的就是Client。在这个例子中,当Artech.WCFService.Client调用Host在Artech.WCFService.Hosting中的DuplexCalculatorService(定义在 Artech.WCFService.Service中),Artech.WCFService.Client是Client,而Server端的执行环境是Artech.WCFService.Hosting。而当Calculator Service回调(Callback)Client的逻辑把运算结果显示出来时候,因为Callback的逻辑是在Artech.WCFService.Client中执行的,所以Artech.WCFService.Client成了Server,而CalculatorCallbackHandler(定义在 Artech.WCFService.Client中)成了真正的Service。

3.我们已经说过Client能够调用Service,它必须知道Service的Contract。所以DuplexCalculatorService能过Callback Artech.WCFService.Client,它也必须知道回调操作的Contract。WCF通过在ServiceContractAttribute中的CallbackContrac参数在制定。


 [ServiceContract(CallbackContract = typeof(ICalculatorCallback))]
    
public interface IDuplexCalculator
    
{
         [OperationContract]
        
void Add(double x, double y);
    }
Step 3 在Artech.WCFService.Service定义Duplex Calculator Service
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
    
public class DuplexCalculatorService:IDuplexCalculator
    
{
        
IDuplexCalculator Members
    }
这里有以下几点需要注意的:

1. 必须把并发模式ConcurrencyMode设置为ConcurencyMode. Reentrant 或者ConcurencyMode.Multiple。要弄清种种的原因,我们先来看看在本例中的具体的消息交互的情况(假设我们的调用Duplex Calculator Service 和回调都采用Request/Response的Message Excahnge Pattern,时间上一般这种情况我们应该采用One-way的ME):


首先Client调用Duplex Calculator Service, Service Request从Client到Service,Service开始执行运算,运算完成后Callback Client将运算结构在Client端显示出来,这个过程中Service向Client发送一个Callback Message,等Client完成Callback操作后,会向Service端发送一个Callback Response(实际上是一个空的Message——以为Callback操作没有返回值),Service收到Callback Response之后,会执行后续的操作,等所有的操作执行完毕,会发送Service Response(这里也是一个空的Message)到Client。

现在我们 来看看为什么在建立Duplex Service的时候要把并发模式设为ConcurencyMode. Reentrant 或者ConcurencyMode.Multiple。在默认的并发模式下(ConcurencyMode.Single),WCF为了保证其线程安全性(Thread Safety),在整个调用Service的过程中,InstanceContext会被WCF锁住(Lock)。一本Sample为例,从Client向Service发送Service Request 到手的Server发回的Service Resqonse,整个InstanceContext会在Server端被锁住, 由于在Client执行的Callback操作使用的是同一个InstanceContext, 这样形成了一个死锁(DeadLock)——Calculator Service必须等Callback操作完成之后才能执行后续的操作,而Callback操作必须等待InstanceContext被解锁(Unlock)才能执行,然而InstanceContext却被Calculator Service锁住。

当ConcurencyMode为ConcurencyMode. Reentrant 或者ConcurencyMode.Multiple的时候。当Serivice向外调用某个操作(outgoing call)的时候,或者说在向外发送一个Outgoing Message的时候,WCF会解锁(Unlock)InstanceContext。以本例为例,Service 回调Client的时候,原来被锁住的InstanceContext会被解锁。这样Callback操作就可以利用InstanceContext来执行。

2. Service可以通过OperationContext.Current.GetCallbackChannel<T>() 来或者Client在调用Calculator Service时指定的Callback Object。其中T一般被指定为Callback Contract对应的Type。 

ICalculatorCallback callback = OperationContext.Current.GetCallbackChannel<ICalculatorCallback>();

Step 4 在Artech.WCFService.Hosting中Host Duplex  Calculator  Service

<?xml version="1.0" encoding="utf-8" ?>
<configuration>  
    
<system.serviceModel>
        
<behaviors>
            
<serviceBehaviors>
                
<behavior name="calculatorServieBehavior">
                    
<serviceMetadata httpGetEnabled="true" />
                
</behavior>
            
</serviceBehaviors>
        
</behaviors>      
        
<services>            
            
<service behaviorConfiguration="calculatorServieBehavior" name="Artech.WCFService.Service.DuplexCalculatorService">
                
<endpoint binding="wsDualHttpBinding" contract="Artech.WCFService.Contract.IDuplexCalculator">                  
                
</endpoint>
                
<host>
                    
<baseAddresses>
                        
<add baseAddress="http://localhost:7777/DuplexCalculator" />
                    
</baseAddresses>
                
</host>
            
</service>            
        
</services>
    
</system.serviceModel>
</configuration>
Program.cs 
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using Artech.WCFService.Contract;
using Artech.WCFService.Service;
using System.ServiceModel.Description;

namespace Artech.WCFService.Hosting
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            HostDuplexCalculator();
        }


       
static void HostDuplexCalculator()
        
{
            
using (ServiceHost calculatorSerivceHost = new ServiceHost(typeof(DuplexCalculatorService)))
            
{
                calculatorSerivceHost.Opened 
+= delegate
                
{
                    Console.WriteLine(
"Duplex calculator Service has begun to listen  ");
                }
;

                calculatorSerivceHost.Open();

                Console.Read();
            }

        }
        
    }

}

这里需要注意的时候,在Host Duplex  Calculator Service 的时候,我们要为它添加相应的Endpoint。对于支持双向通信的Service,它对Endpoint有一定的要求——我们必须为它指定一个支持Duplex MEP(Message Exchange Pattern)的Binding——比如wsDualHttpBinding,netDualTcpBinding。这里我们使用的时wsDualHttpBinding。

Step 5 在Artech.WCFService.Client定义Callback对象和调用Duplex  Calculator  Service 

DuplexCalculatorClient.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;

using Artech.WCFService.Contract;

namespace Artech.WCFService.Client
{
    
class DuplexCalculatorClient:ClientBase<IDuplexCalculator>,IDuplexCalculator
    
{

        
public DuplexCalculatorClient(InstanceContext callbackInstance)
            : 
base(callbackInstance)
        
{ }

        
IDuplexCalculator Members
    }

}

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<system.serviceModel>
    
<bindings>
      
<wsDualHttpBinding>
          
<binding name="wsDualBinding_IDuplexCalculator" clientBaseAddress="http://localhost:6666/myClient/" />
      
</wsDualHttpBinding>
    
</bindings>
    
<client>      
      
<endpoint address="http://localhost:7777/DuplexCalculator" binding="wsDualHttpBinding"
        bindingConfiguration
="wsDualBinding_IDuplexCalculator" contract="Artech.WCFService.Contract.IDuplexCalculator"
        name
="duplexCalculatorEndpoint" />
      
<endpoint address="http://localhost/WCFService/SessionfulCalculatorService.svc"
        binding
="wsHttpBinding" bindingConfiguration="" contract="Artech.WCFService.Contract.ISessionfulCalculator" />
    
</client>
  
</system.serviceModel>
 
</configuration>

CalculatorCallbackHandler.cs
using System;
using System.Collections.Generic;
using System.Text;
using Artech.WCFService.Contract;

namespace Artech.WCFService.Client
{
    
class CalculatorCallbackHandler:ICalculatorCallback
    
{
        
ICalculatorCallback Members
    }

}
Program.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;

using Artech.WCFService.Contract;

namespace Artech.WCFService.Client
{
    
class Program
    
{
        
static void Main()
        
{
            
try
            
{                   InvocateDuplexCalculator();
            }

            
catch (Exception ex)
            
{
                Console.WriteLine(ex.Message);
            }


            Console.Read();    
        }


        
        
static void InvocateDuplexCalculator()
        

            CalculatorCallbackHandler callbackHandler 
= new CalculatorCallbackHandler();

            
using(DuplexCalculatorClient calculator = new DuplexCalculatorClient(new InstanceContext(callbackHandler)))
            
{
                Console.WriteLine(
"Begin to invocate duplex calculator ");
                calculator.Add(
12);
            }

        }
        
    }

}

这里有以下几点需要注意的:

1. 在调用Duplex Calculator Service的时候,我们需要指定执行回调的Callback对象。在WCF中,Callback对象用一个InstanceContext对象来表示。而他在DuplexCalculatorClient的构造函数中指定。

 public DuplexCalculatorClient(InstanceContext callbackInstance)
            : 
base(callbackInstance)
        
{ }
2. Client调用Duplex Calculator Service,Service端需要注册相应的Channel来监听来自Client的请求。同理,Service回调Client,Client也需要相应的Channel来监听来自Service的回调。这个Channel通过下面的方式注册。   
    
<wsDualHttpBinding>
          
<binding name="wsDualBinding_IDuplexCalculator" clientBaseAddress="http://localhost:6666/myClient/" />
</wsDualHttpBinding>

到现在为止我们已经完成了所有的Program,我们来运行一下。

1.         运行Artech.DuplexRemoting.Hosting


2.         运行Artech. WCFService.Client


将Duplex Calculator  Service Host 到IIS中

1.         在http://localhost/WCFService中添加于Artech.WCFService.Service。DuplexCalculatorService相对应的SVC文件。

DuplexCalculatorService.svc

<%@ ServiceHost Language="C#" Debug="true" Service="Artech.WCFService.Service.DuplexCalculatorService" %>

2.         并添加类似于Artech.WCFService.Hosting/App.Config中 的Configuration。

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
  
<system.serviceModel>
    
<behaviors>
      
<serviceBehaviors>
        
<behavior name="calculatorServiceBehavior">
          
<serviceMetadata httpGetEnabled="true" ></serviceMetadata>
        
</behavior>
      
</serviceBehaviors>
    
</behaviors>
    
<services>
      
<service behaviorConfiguration="calculatorServiceBehavior" name="Artech.WCFService.Service.DuplexCalculatorService">
        
<endpoint binding="wsDualHttpBinding" contract="Artech.WCFService.Contract.IDuplexCalculator" />
      
</service>      
    
</services>
  
</system.serviceModel>  
    
<system.web>
        
<compilation debug="true">
            
<assemblies>
                
<add assembly="System.Security, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
                
<add assembly="Microsoft.Transactions.Bridge, Version=3.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
                
<add assembly="SMDiagnostics, Version=3.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
                
<add assembly="System.IdentityModel.Selectors, Version=3.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
                
<add assembly="System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
                
<add assembly="System.Web.RegularExpressions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
                
<add assembly="System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
                
<add assembly="System.Messaging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
                
<add assembly="System.ServiceProcess, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/></assemblies></compilation>
    
</system.web>
</configuration>
这样我们可以不需要Hosting的情况下通过这样的Uri访问Duplex Calculator Service:http://localhost/Artech.WCFService/ DuplexCalculatorService.svc。 

3.         修改Client的App.Config——修正Endpoint 的Address:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<system.serviceModel>
    
<bindings>
      
<wsDualHttpBinding>
          
<binding name="wsDualBinding_IDuplexCalculator" clientBaseAddress="http://localhost:6666/myClient/" />
      
</wsDualHttpBinding>
    
</bindings>
    
<client>      
      
<endpoint address=" http://localhost/Artech.WCFService/ DuplexCalculatorService.svc " binding="wsDualHttpBinding"
        bindingConfiguration
="wsDualBinding_IDuplexCalculator" contract="Artech.WCFService.Contract.IDuplexCalculator"
        name
="duplexCalculatorEndpoint" />
      
<endpoint address="http://localhost/WCFService/SessionfulCalculatorService.svc"
        binding
="wsHttpBinding" bindingConfiguration="" contract="Artech.WCFService.Contract.ISessionfulCalculator" />
    
</client>
  
</system.serviceModel>
 
</configuration>
在不起用Hosting的情况下运行Artech.WCFService.Client,我们一样可以得到相同的结果。


WCF相关内容:
[原创]我的WCF之旅(1):创建一个简单的WCF程序
[原创]我的WCF之旅(2):Endpoint Overview
[原创]我的WCF之旅(3):在WCF中实现双向通信(Bi-directional Communication)
[原创]我的WCF之旅(4):WCF中的序列化(Serialization)- Part I
[原创]我的WCF之旅(4):WCF中的序列化(Serialization)- Part II
[原创]我的WCF之旅(5):Service Contract中的重载(Overloading)
[原创]我的WCF之旅(6):在Winform Application中调用Duplex Service出现TimeoutException的原因和解决方案
[原创]我的WCF之旅(7):面向服务架构(SOA)和面向对象编程(OOP)的结合——如何实现Service Contract的继承
[原创]我的WCF之旅(8):WCF中的Session和Instancing Management
[原创]我的WCF之旅(9):如何在WCF中使用tcpTrace来进行Soap Trace
[原创]我的WCF之旅(10): 如何在WCF进行Exception Handling
[原创]我的WCF之旅(11):再谈WCF的双向通讯-基于Http的双向通讯 V.S. 基于TCP的双向通讯

[原创]我的WCF之旅(12):使用MSMQ进行Reliable Messaging
[原创]我的WCF之旅(13):创建基于MSMQ的Responsive Service
Tag标签: WCF,Callback,Duplex

posted on 2007-03-02 17:17 Artech 阅读(14425) 评论(109)  编辑 收藏 网摘 所属分类: J. WCF

评论

#101楼[楼主] 2007-03-26 13:29 Artech      

@老鹰
按理说不会出现这样的情况。
我回去试试,有结果答复你!
  回复  引用  查看    

#102楼 2007-03-26 16:30 dreammaster[未注册用户]

关于Dulex的Communication我从微软下载了一个demo, 基本上和你的方法一样,我可以得到同样的结果,不过有个问题想请教一下, 我在同一台机上运行没有什么问题, 但是在不同机器上就出现了安全错误, 请问如何配置才能工作呢?谢谢.   回复  引用    

#103楼[楼主] 2007-03-26 16:49 Artech      

@dreammaster
可能是Client调用Service,或者是Service回调Client权限不够。
  回复  引用  查看    

#104楼 2007-03-27 12:09 老鹰[未注册用户]

@老鹰
按理说不会出现这样的情况。
我回去试试,有结果答复你!

有结果了吗?
  回复  引用    

#105楼[楼主] 2007-03-27 13:57 Artech      

@老鹰
Sorry,还没来得急,今天晚上答复你!
  回复  引用  查看    

#106楼[楼主] 2007-03-27 22:19 Artech      

@老鹰
刚刚做了试验,同时使用WinForm Application作为Host和Client。你说的没错,是会发生你说的情况,原因是这样的。
在Winform Client在主线程调用Duplex WCF Server,Service Side可以接受到这个请求,可以正确执行操作,也可以把结果发回Client,但是Client不能接收。
为什么呢?由于Window Application 不同于Console Application,它的主线程为了应付UI的操作,一直处于忙碌的状态,所以没有机会去处理接收Message的操所。

我们的解决方案是,在Client端,通过异步的方式调用Duplex Service。只要不在主线程调用Duplex WCF Service,它就能正常接收到Service Side传到Client的Callback Request。
Source Code,你可以下载我刚刚写的Sample:http://www.cnblogs.com/files/artech/Artech.DuplexWCFService.zip">http://www.cnblogs.com/files/artech/Artech.DuplexWCFService.zip
  回复  引用  查看    

#107楼[楼主] 2007-03-30 00:48 Artech      

@老鹰
请参考我心的文章http://www.cnblogs.com/artech/archive/2007/03/29/692032.html">[原创] 我的WCF之旅(6)在Winform Application中调用Duplex Service出现Timeout Exception的原因和解决方案(Pending)
  回复  引用  查看    

#108楼 2007-04-02 10:04 Frank[未注册用户]

我记得Winform中的远程回调以前就不能通过主线程callback的,会报一个上下文异常,因为回调消息传递回来的时候是无权限操作winform主线程的。以前的解决方法是用一个delegate来invoke异步调用,并处理回调响应。   回复  引用    

#109楼[楼主] 2007-04-02 11:51 Artech      

@Frank
是这样的,之所以会这样的UI线程在调用Service的时候,他会一直等待整个结果的返回,但是Callback会回调UI主线程,造成死锁。所以我们有两个解决方案:
1.异步调用(你可以使用Delegate,也可以用Thread,......)
2.使用One-way的Service 甚至是One-way Callback。
  回复  引用  查看    

#110楼 2007-04-16 17:44 菜菜陈熙尚      

将Service Host 到IIS中,是不是你上面提供的三步都要做!我老是失败,不知道为什么!配置这东西比较麻烦~~   回复  引用  查看    

#111楼[楼主] 2007-04-16 18:19 Artech      

@菜菜陈熙尚
1.创建svc文件。
2.建立虚拟目录。
3.在虚拟目录的根目录下作相应的配置。

下面的配置是必要的:

1. Service
2.Endpoint(Binding & Contract)Address都不需要,因为svc文件地网络地址就是对应的Address。
3.如果希望Client通过http或者https获得原数据,配置serviceMetadata httpGetEnabled="true" 。

如果Service定义在另一个Project,需要对它的引用。或者说Service的Dll在虚拟目录的Bin目录下。
  回复  引用  查看    

#112楼 2007-04-20 18:38 lyqfqy[未注册用户]

我有一个问题,web service 和WCF的区别和联系是什么?怎么实现他们之间的互相转换? 我实现了一个WCF转Web service的例子,但是仅仅是把WCF包装了一下,有没有直接的方法实现呢?
谢谢!
  回复  引用    

#113楼[楼主] 2007-04-20 19:08 Artech      

@lyqfqy
web service是基于SOA和开放式标准的的一种分布式技术。WCF可以看成一个基础构架实现了.NET平台的不同分布式技术的统一,这不但包括web service,还包括Remoting,Enterprise Service,MSMQ,甚至是XML RPC。所以WCF是一个更加宽泛的概念,比Web Service有着更加广泛的应用。

至于如何实现Web service和WCF之间的转换,虽然他们都是采用的是申明式、可配置的方式,但是他们采用了不同的编程模式,要把一个WCF service直接转换成Web Service,我觉得没有直接的方法。不过从这个问题可以得出这个的结论,我们在开发的时候,应该把逻辑分离出来,供不同的Service共用,Web Service和WCF Service仅仅是一个把逻辑封装成不同Service供外界访问的壳而已,自身不应该包含任何逻辑。
  回复  引用  查看    

#114楼 2007-04-30 18:42 lyqfqy[未注册用户]

@Artech
说的真对啊!理解了。
还有一个问题:在老鹰的那个问题中,我看到你实现新建了一个线程来执行Calculate(如下):
Thread newThread = new Thread(new ThreadStart(this.Calculate));
newThread.Start();
你说这个是异步调用,我觉得异步调用应该是使用:***.BeginInvoke(...); 和***.EndInvoke(ar);来实现的吗?这个和线程有什么关系啊?
  回复  引用    

#115楼 2007-04-30 18:48 lyqfqy[未注册用户]

哦 还有,对于我的第一个问题,既然web service被WCF 所涵盖,那怎么通过WCF发布web service呢?   回复  引用    

#116楼[楼主] 2007-04-30 18:57 Artech      

@lyqfqy
异步调用的本质就是操作在另外一个线程中执行。 所以我们可以通过很多的方式来进行异步调用。比如调用Delege的BeginInvoke和EndInvoke;某写Class定义的BeginXXX和EndXXX;我们也可以直接创建新的线程,这个一种很直接的做法。不过不值得推荐,因为线程是一种稀缺的资源,其创建需要耗费大量的资源,所以我们应该以一种池的机制来使用线程。
  回复  引用  查看    

#117楼 2007-04-30 20:12 lyqfqy[未注册用户]

@Artech
楼主真勤快啊,这么快就回我的帖子了,实在感激!

池的机制就是所谓的线程池吧?能抛砖引玉,或举一个小例否?

另外一问题:
# re: [原创]我的WCF之旅(3):在WCF中实现双向通信(Bi-directional Communication) 2007-04-30 18:48 lyqfqy
哦 还有,对于我的第一个问题,既然web service被WCF 所涵盖,那怎么通过WCF发布web service呢?
  回复  引用    

#118楼[楼主] 2007-05-01 10:33 Artech      

@lyqfqy
我们说WCF囊括了.NET平台下所有的分布式技术,并非简单地把WCF当成一个容器,把他们组合在一起。WCF实际上构建一个用于Communication的基本构架,用于这些不同的技术进行通信。通过对这些分布式技术进行改造,使得这些原来完全不同的分布式技术现在可以采用同样的编程模式,同样的发布方式,同样的对外接口和使用方式。

明白这一点之后,我想你就不会提出这样的问题了“怎么通过WCF发布web service”。在这样一个统一的引擎下,WCF已经没有Web Service,Remoting,Enterprise Service的概念,无论底部采用的怎样的通信方式,对于编程人员,甚至是IT人员,都不需要太多地关注。对于WCF,无论通过那种底层技术发布的Service都是一样的,在WCF中,实际上已经没有了web service的概念,所有的都是一样的service。
  回复  引用  查看    

#119楼[楼主] 2007-05-01 11:43 Artech      

@lyqfqy
呵呵,我很喜欢和别人一起探讨技术问题。
我们现在来说说池(Pool),对于一些具有这样属性的资源:他会别频繁的使用,创建却要耗费大量的资源,我们一般会使用Pool的机制来防止频繁创建这样的对象,在理想的情况下,我们只需要创建对象一次,把它放在Pool中,要使用该对象的时候,从Pool中取出,用完之后释放到Pool中。
在.NET中,Pool有着广泛的使用:线程池、字符串池、数据库连接池、对象池。
对于线程池,最直接的用法就是使用System.Threading.ThreadPool这个Class。
  回复  引用  查看    

#120楼 2007-05-04 13:39 lyqfqy[未注册用户]

@Artech
谢谢你的耐心回复!短短两段话,看了之后真是受益匪浅。
最近利用WCF技术再做一个具有远程控制功能的数据采集系统。看来,线程池可以用到我的系统里面去了。嘿嘿
  回复  引用    

#121楼[楼主] 2007-05-04 15:07 Artech      

@lyqfqy
谢谢你对本Blog的关注,很高兴我所说的能对你带来帮助。
  回复  引用  查看    

#122楼 2007-05-06 01:53 lyqfqy[未注册用户]

@Artech
Artech,你在前面曾经说过,不喜欢使用工具Svcutil.exe,但是如果服务端发布的服务我们事先不知道的话,那么我们就必须把元数据转变为我们需要的代理类,这肯定是要该工具来转换的吧?
另外对于老鹰中的线程问题,我查了一下,最好要加上Thread.CurrentThread.IsBackground = true; 这样在关闭程序后,相应的进程会关闭(我测了一下,好像是这样的^_^).

另请教一个问题,我在尝试制作远程控制程序时,按照该主题的例子好像很难实现(因为服务被发布出来,他们是基于消息的,没法持续的在服务器端运行)。是不是需要WCF的别的功能,比如session?具体我不太清楚,能否给一些clues?或者实现一个小程序,可否?万分感激!
  回复  引用    

#123楼[楼主] 2007-05-08 11:33 Artech      

@lyqfqy

象Svcutil.exe这样的工具,确实可以带来很多便利,很多人都喜欢用它,以至MSDN都很推崇,我不喜欢用,只是个人喜好问题。可能我对Coding有太强的控制欲:)

至于最后一个问题,你可以参考WCF的instancing management和sesssin相关内容。
  回复  引用  查看    

#124楼 2007-06-14 11:55 妖居      

我在使用IIS-Hosting的时候总是问题多多。唉……
我下载了博主的Source,也可以通过IE访问到http://localhost/WCFService/DuplexCalculatorService.svc" target="_new">http://localhost/WCFService/DuplexCalculatorService.svc。(但是http://localhost/Artech.WCFService/" target="_new">http://localhost/Artech.WCFService/ DuplexCalculatorService.svc是访问不到的,中间多了个Artech,是不是笔误呢?)
但是单独运行Client就会显示The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
好奇怪。

PS:博主的回复好快啊,赞一个。 :D
  回复  引用  查看    

#125楼[楼主] 2007-06-14 12:40 Artech      

@妖居
不是笔误,Artech.WCFService是虚拟目录的名称。
  回复  引用  查看    

#126楼[楼主] 2007-06-14 12:40 Artech      

@妖居
换成你对应的虚拟目录就可以了。
  回复  引用  查看    

#127楼 2007-06-15 14:11 m9n5[未注册用户]

博主,问个比较幼稚的问题。

WCF中实现Callback是像1.1和2.0一样通过事件机制来完成的?还是通过端口?
  回复  引用    

#128楼[楼主] 2007-06-15 14:57 Artech      

@m9n5
没有幼稚的问题,只有幼稚的答案。
我简单是说说我对WCF Callback的实现的理解:Service的Host启动之后,会有一个Endpoint会在某个指定的Port监听来个外界的Soap请求。Client在访问该Service的时候,需要在Client端也建立一个Endpoint来监听来自Service端的请求。它和Service之间建立一个Duplex Channel,并向Service Endpoint监听的URI发送Soap Message,Client用于监听的Endpoint相关信息被置于Soap中,Service在执行相关操作,需要Callback Client,便提取Client端Endpoint信息,使用同一个Channel向Client发送Soap,Client端接受到请求之后执行相应的Callback操作。
如果从Message excahnge讲,倘若两个操作都采用Request/Response的MEP的话,其Message Exchange方式是这样的:Client-〉Service-〉Client-〉Service-〉Client。
你可以以事件机制的方式来实现Callback。
  回复  引用  查看    

#129楼 2007-06-26 18:17 Persevere[未注册用户]

你的例子我怎么老是运行不过去呀?我是刚研究WCF的。请告知,谢谢!
错误原因是: ex.Message "通信对象 System.ServiceModel.Channels.ServiceChannel 无法用于通信,因为其处于“出错”状态。" string
  回复  引用    

#130楼[楼主] 2007-06-26 19:03 Artech      

@Persevere
从你给出的简短的Error Message,我很难说是哪里错了。
你是否为SVC文件创建了对应的虚拟目录:WCFSerice。
如果不行,请参阅我在另一篇文章中关于Duplex Channel的Sample:http://www.cnblogs.com/artech/archive/2007/06/18/788071.html" target="_blank">[原创]我的WCF之旅 (11): 再谈WCF的双向通讯-基于Http的双向通讯 V.S. 基于TCP的双向通讯
  回复  引用  查看    

#131楼 2007-06-27 09:31 Persevere[未注册用户]

try
{
//InvocateCalclatorServiceViaCode();
//InvocateCalclatorServiceViaConfiguration();
InvocateDuplexCalculator();
//InvocateSessionfulCalculator();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}

运行到catch这里就会弹出那个错误,是否是我还有什么配置没有弄好,我也没有建立虚拟目录。
出现这个错误非常郁闷,又没法调试。好像是客户端调服务时,出现了错误。
我的邮箱:rpx_010@163.com,以后请你多指点。

创建一个简单的WCF程序
我运行你这个例子就出现这个错误。
是否要配置什么服务么?
  回复  引用    

#132楼 2007-06-27 09:33 Persevere[未注册用户]

非常谢谢你及时解答。
  回复  引用    

#133楼 2007-06-27 09:51 Persevere[未注册用户]

ex.Message"无法连接到 http://localhost:8888/generalCalculator。TCP 错误代码 10061: 由于目标机器积极拒绝,无法连接。。 "
这是第一个例子的错误,
很奇怪:IIS-host service里运行成功,Self-host service就出错,是否是什么WINDOWS服务没有开启么?
程序是:Artech.WCFService.Client里的Program.cs
方法是:
static void InvocateCalclatorServiceViaConfiguration()
{
Console.WriteLine("Invocate self-host calculator service... ...");

#region Invocate Self-host service
using (GeneralCalculatorClient calculator_http = new GeneralCalculatorClient("selfHostEndpoint_http"))
{
using (GeneralCalculatorClient calculator_tcp = new GeneralCalculatorClient("selfHostEndpoint_tcp"))
{
try
{
Console.WriteLine("Begin to invocate calculator service via http transport... ...");
Console.WriteLine("x + y = {2} where x = {0} and y = {1}", 1, 2, calculator_http.Add(1, 2));

Console.WriteLine("Begin to invocate calculator service via tcp transport... ...");
Console.WriteLine("x + y = {2} where x = {0} and y = {1}", 1, 2, calculator_tcp.Add(1, 2));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
#endregion

Console.WriteLine("\n\nInvocate IIS-host calculator service... ...");

#region Invocate IIS-host service
using (GeneralCalculatorClient calculator = new GeneralCalculatorClient("iisHostEndpoint"))
{
try
{
Console.WriteLine("Begin to invocate calculator service via http transport... ...");
Console.WriteLine("x + y = {2} where x = {0} and y = {1}", 1, 2, calculator.Add(1, 2));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
#endregion
}
  回复  引用    

#134楼[楼主] 2007-06-27 10:27 Artech      

@Persevere
Check一下Hosting的Code和Application Configiration,确认Hosting的Endpoint的Address是不是和client端配置的一样,并且确保正常启动。
  回复  引用  查看    

#135楼[楼主] 2007-06-27 10:31 Artech      

@Persevere
采用IIS Host的方式,需要把Service对应的SVC文件置于相应的虚拟目录中,才能通过IIS像访问一般Web Server Resource一样进行访问,所以你需要为SVC文件创建对应的虚拟目录,并保证Client采用对应的URI调用该Service。
  回复  引用  查看    

#136楼 2007-06-27 11:40 Persevere[未注册用户]

我是用的你传上来的代码,没有改动过,IIS Host的方法是可以执行的,里输出的结果也显示出来了,就是Self-host 里面的没有出来,与防火墙有关系么?
对WCF是最近接触的,里面一些原理还是很模糊,我想用你的例子来入门,可是一运行就出那个错误。
现在想用这个来做个项目,以后希望得到你支持,先谢谢啦!有什么好资料推荐一下,我现在就是看MSDN。去书店没有找到,郁闷!
  回复  引用    

#137楼[楼主] 2007-06-27 12:54 Artech      

@Persevere
这个Demo有点乱,我发了一个相对简单、清晰的给你,请接收一下:rpx_010@163.com.
  回复  引用  查看    

#138楼 2007-06-27 13:32 Persevere[未注册用户]

非常感谢!我收到了。

  回复  引用    

#139楼 2007-06-27 13:59 Persevere[未注册用户]

Type:System.ServiceModel.EndpointNotFoundException
Message "无法连接到 http://localhost:9999/calculator。TCP 错误代码 10061: 由于目标机器积极拒绝,无法连接。。 "

惭愧还是出上面的错误,是否我的环境搭的有错误呀!
还是我的系统配置有问题
winServer2003
  回复  引用    

#140楼 2007-06-27 14:12 Persevere[未注册用户]

1.安装VS2005SP1补丁包
VS80sp1-KB926604-X86-CHS.exe
2.dotnetfx3
dotnetfx3.exe
dotnetfx3langpackzh-CHS.exe
3.WindowsSDK
WindowsServer2003-KB912818-v3-x86-CHS.exe
6.0.6000.0.0.WindowsSDK_Vista_rtm.DVD.Rel.img
vsextwfx.msi(CTP2006)
Visual Studio 2005 Extensions for 4.Windows Workflow Foundation (CHS).exe
4.VS2005SDK 3.0 最新开发包.exe

这是我机器上配置的东东,这样配置是否有问题?
  回复  引用    

#141楼[楼主] 2007-06-27 15:12 Artech      

@Persevere
问一个很弱的问题,你启动Host了吗?
  回复  引用  查看    

#142楼 2007-06-27 15:36 Persevere[未注册用户]

嘻嘻!具体一点,我还真不知道?   回复  引用    

#143楼 2007-06-27 16:19 Persevere[未注册用户]

请说一下,我不知道你具体指的是什么?谢谢!   回复  引用    

#144楼[楼主] 2007-06-27 16:32 Artech      

@Persevere
启动Artech.DuplexService.Hosting, 再启动Artech.DuplexService.Client
  回复  引用  查看    

#145楼 2007-06-27 16:46 Persevere[未注册用户]

Artech.DuplexWCF.Hosting.exe
Artech.DuplexWCF.Client.exe
你指的是否是那两个文件。
  回复  引用    

#146楼 2007-06-27 16:54 Persevere[未注册用户]

唉!知道了,我想给你建议一下,可以弄个测试服务注册呀!
弄的我绕了半天,真的还是很谢谢你。
以后做项目还请你多多帮忙。
  回复  引用    

#147楼 2007-06-27 17:03 Persevere[未注册用户]

说的不错,以前几乎没有开发过remoting .
你能推荐几本书,或者有什么好的资料。
我现在也只有网上找资料看看。
  回复  引用    

#148楼 2007-07-29 10:56 hustnn[未注册用户]

@Artech
我寄宿于iis中,直接启动了client,没有正确结果
显示如下:
the communication object , system.servicemodel.duplexchannelfactory'1[hustnn.wcfservice.contract.iduplexcalculator],cannot be used for communication because it is in the faulted state
  回复  引用    

#149楼 2007-07-31 15:56 写代码的人[未注册用户]

我现在参与的一个项目就是用WFC结合MVC开发的,以前一直都不怎么明白为什么要那样做看了你前面的一些讲解总算是知道了些,感觉你的理论讲解的很不错,前面部分都只要看看你的理论说明就知道下面的例子该怎么写和调试了,不知道你对MVC在winform中运用的了解多吗?我有些这方面的疑问,如肯赐教不剩感激.我的油箱是tt3620455@yahoo.com.cn   回复  引用    

#150楼[楼主] 2007-07-31 17:20 Artech      

@写代码的人
很高兴看到读者从我的文章中收益,至于MVC,每个人都会有自己的不同的理解,赐教实在不敢当,我们可以在一起交流。
我的Email:jiangjinnan@gmail.com
IM: jiangjinnan@hotmail.com
  回复  引用  查看    

#151楼 2007-09-25 16:32 初学者_123[未注册用户]

@Persevere

我也出现"由于目标机器积极拒绝",这种情况出现是因为.我在hosting里面open了两个service.
然后client访问第一个启动的service的时候就出现这个错误.如果client访问第二个就没错.

请问@Artech
这是什么原因呢?怎么在一个hosting中open多个service?
比如你例子中
static void Main(string[] args)
{
//HostCalculatorServiceViaCode();
HostCalculatorSerivceViaConfiguration();
HostDuplexCalculator();
}
你的client访问第一个的时候就会出"由于目标机器积极拒绝"的错.
  回复  引用    

#152楼 2008-04-03 15:22 Chiun[未注册用户]

请问一下博主,这样的双向通信,是否能穿网,主要是指服务段callback客户端?   回复  引用    

#153楼[楼主] 2008-04-07 13:14 Artech      

@Chiun
这取决于你网络的防火墙设置,相应的Port是否被封掉。 如果使用Http,Callback会默认使用80, 这样的话,如果Client的IIS会将Callback截获,导致Callback不能正确执行。所以在Client端一般指定定一个可用的Port。

TCP原本就是双向的协议,所以不会出现这样的问题。
  回复  引用  查看    

#154楼 2008-05-17 12:08 阿滨       

很好很强大!   回复  引用  查看    

#155楼 2008-07-10 11:40 finix      

看的有些晕   回复  引用  查看    

#156楼 2008-08-05 14:10 Hamby[未注册用户]

这几天开始接触WCF感觉有点难,之前我一直是做B/S系统的,对这方面没做过研究,请问如果学习的话应如果入手.   回复  引用    

#157楼 2008-08-27 11:45 边城浪1[未注册用户]

同理,Service回调Client,Client也需要相应的Channel来监听来自Service的回调。这个Channel通过下面的方式注册。
<wsDualHttpBinding>
<binding name="wsDualBinding_IDuplexCalculator" clientBaseAddress="http://localhost:6666/myClient/" />
</wsDualHttpBinding>

这个好像是多余的。。根据不需要吧。。。。。。。。。因为Client调用Service,和Service回调 Client 应该使用的是同一个 Channel
  回复  引用    

#158楼[楼主] 2008-08-27 12:01 Artech      

@边城浪1
对于TCP来讲,由于本身支持Duplex, 所以使用的同一个Channel。
而Http就是简单的Request/Response的stateless协议,其Channel不可能支持Duplex.
  回复  引用  查看    

#159楼 2008-08-28 13:33 边城浪1[未注册用户]

没说清楚..
我的意思是在客户端同样也只需要简单的把 binding设为 wsDualHttpBinding 就可以了..
示例:
<system.serviceModel>
<client>
<endpoint address="http://localhost:8080/WCFService/CalculatorService "
binding="wsDualHttpBinding"
contract="WCFService.Contract.ICalculator"/>
</client>
</system.serviceModel>
而不再需要单独的 Channel 来监听.
http 的 wsDualHttpBinding 方式是支持双工的.......
  回复  引用    

#160楼[楼主] 2008-08-28 14:11 Artech      

@边城浪1
在不指定clientBaseAddress的情况下,将使用80 port,这在IIS 5(Windows XP)的情况下将会报AddressAlreadyInUseException,因为80端口已经被IIS使用;
如何IIS 6, IIS 7将不会出现这样的问题。
  回复  引用  查看    

#161楼 2008-08-28 17:27 边城浪1[未注册用户]

回复真及时.再顶一个..
正在看你的文章.十分精彩.谢谢了~~~
  回复  引用    

#162楼[楼主] 2008-08-28 17:36 Artech      

@边城浪1
谢顶:)
  回复  引用  查看    

#163楼 2008-09-02 09:53 wangxm[未注册用户]

--引用--------------------------------------------------
Artech: @Frank
<br>谢谢!利用ChannelFactory可以省掉我们去定义Client端的Proxy类,这样也更加优雅一点,呵呵!
--------------------------------------------------------
楼主,具体如何使用ChannelFactory省掉定义Client端的Proxy类?
  回复  引用    

#164楼[楼主] 2008-09-02 09:56 Artech      

@wangxm
在后续的文章中,你会看到我基本上都是使用的ChannelFactory方式.
  回复  引用  查看    

#165楼 2008-09-05 15:53 问题请教[未注册用户]

IIS-host service里运行成功,Self-host service就出错
显示如下:
The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be
used for communication because it is in the Faulted state.
以下是配置代码:
Host端:
<service behaviorConfiguration="calculatorServieBehavior" name="Alex.WCFService.Service.DuplexCalculatorService">
<endpoint binding="wsDualHttpBinding" contract="Alex.WCFService.Contract.IDuplexCalculator" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:9998/DuplexCalculator" />
</baseAddresses>
</host>
  回复  引用    

#166楼 2008-09-05 15:57 问题请教[未注册用户]

client端
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="wsDualBinding_IDuplexCalculator" clientBaseAddress="http://localhost:9995/myClient/" />
</wsDualHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:9991/generalCalculator" binding="basicHttpBinding" contract="Alex.WCFService.Contract.IGeneralCalculator" name="selfHostEndpoint_http" />
<endpoint address="net.tcp://localhost:9992/generalCalculator" binding="netTcpBinding" contract="Alex.WCFService.Contract.IGeneralCalculator" name="selfHostEndpoint_tcp" />
endpoint address="http://localhost:9998/DuplexCalculator" binding="wsDualHttpBinding" contract="Alex.WCFService.Contract.IDuplexCalculator" name="duplexCalculatorEndpoint" bindingConfiguration="wsDualBinding_IDuplexCalculator" />
<endpoint address="http://localhost:1601/WCFService/GeneralCalculatorService.svc" binding="basicHttpBinding" contract="Alex.WCFService.Contract.IGeneralCalculator" name="iisHostEndpoint" />
  回复  引用    

#167楼 2008-09-05 16:00 问题请教[未注册用户]

<endpoint address="http://localhost:1601/WCFService/DuplexCalculatorService.svc" binding="wsDualHttpBinding" contract="Alex.WCFService.Contract.IDuplexCalculator" name="duplexCalculatorEndpoint" bindingConfiguration="wsDualBinding_IDuplexCalculator" />
<endpoint address="http://localhost:1601/WCFService/SessionfulCalculatorService.svc" binding="wsHttpBinding" bindingConfiguration="" contract="Alex.WCFService.Contract.ISessionfulCalculator" />
</client>
</system.serviceModel>
</service>
请帮忙查看下是什么原因
  回复  引用    

#168楼[楼主] 2008-09-05 16:10 Artech      

@问题请教
你直接把真个Source Code发给我好了:jiangjinnan@gmail.com
  回复  引用  查看    

#169楼 2008-09-06 09:19 问题请教[未注册用户]

谢谢,,问题已经解决。是using作用域导致的问题。我启用client是在host中using作用完成后,,所以在服务器一直不能找到chanle。一个不小心的错误,害我搞了老半天,,,:(   回复  引用    

#170楼[楼主] 2008-09-08 09:26 Artech      

@问题请教
你是说ServiceHost被Dispose了?
  回复  引用  查看    

#171楼 2008-09-10 15:00 pijiuhua[未注册用户]

在这个代码中clinet端只能启动一个,原因因为是当前Clint端的端口被占用,请问下一个楼主 如何解决这个问题.   回复  引用    

#172楼[楼主] 2008-09-12 09:34 Artech      

@pijiuhua
你可以通过代码的方式,手工指定一个可用的Port!
  回复  引用  查看    

#173楼 2008-11-01 17:09 AlexMc[未注册用户]

楼主,我下了你的source code 也建立了虚拟目录,但是执行 client.exe和 host.exe之后。两端都没有反映....

过了一会儿呢,client屏幕上就出现了 "The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state. "

我装的是 VS2008,开了你的程序后,会有一个code wizard popup.一步一步做完后,就出现了上述的结果。 麻烦帮我解答一下,不甚感谢。
  回复  引用    

#174楼 2008-11-01 17:12 AlexMc[未注册用户]

只有下了你那个application demo [Artech.DuplexWCFService] 也是一样的问题,client和 host都没有反映。过了一会儿,client 触发 timeout, client的form自己dispose了.   回复  引用    

#175楼 2008-11-21 22:24 NineTyNineLP[未注册用户]

运行后的结果跟单向的不一样吗?

服务器没有调用客户端的方法吧?

怎么体现的是双向的?

不知道我说没说清楚我的问题?
  回复  引用    

#176楼[楼主] 2008-11-24 09:56 Artech      

@NineTyNineLP
双向通信通过Callback体现!
  回复  引用  查看    

#177楼 2008-12-11 22:02 Doho      

请问楼主:DuplexClientBase<T> 与 ClientBase<T> 有什么区别?用Reflector 看DuplexClientBase<T>只是ClientBase<T>的简单封装。
类DuplexCalculatorClient 也可以继承 DuplexClientBase<T>
class DuplexCalculatorClient:DuplexClientBase<IDuplexCalculator>,IDuplexCalculator
  回复  引用  查看    

#178楼[楼主] 2008-12-12 11:02 Artech      

@Doho
DuplexClientBase<T>通过创建Duplex Channel调用服务,通过DuplexClientBase<T>可以执行封装callback对象的InstanceContext对象。
  回复  引用  查看    

#179楼 2008-12-16 19:23 zhichiyan      

请教一个一直困扰的问题
wcf的服务端和客户端在通讯的过程中,采用的是xml进行通讯,也就是说,服务端先要将客户端请求的数据封装成xml格式,然后写成xml文件在硬盘上,通过协议发送到客户端。客户端接受到的也是xml文件,然后反馈给用户调用接口。

也就是说,在一次请求过程中,出现了两次硬盘读写操作(即服务端和客户端各一次),而读写硬盘的操作是很费时的,这样的话,是不是比直接内存发送效率要低很多呢? wcf的每次通讯都必须要写硬盘吗?
一直为这个问题困惑,请解答一下,谢谢!
  回复  引用  查看    

#180楼[楼主] 2008-12-17 09:43 Artech      

@zhichiyan
我们说WCF通过XML进行通信,并没有说通过XML文件进行通信呀:)
  回复  引用  查看    

#181楼 2008-12-17 13:25 zhichiyan      

@Artech
原来不是通过xml文件,明白了,谢谢。这也是我期望的,不然通讯效率可真不得了啊。
  回复  引用  查看    

#182楼[楼主] 2008-12-26 09:12 Artech      

@zhichiyan
通信怎么可以依赖于存储于硬盘的文件呢?
  回复  引用  查看    

#183楼 2009-03-08 22:45 goldenlily

问个弱弱的问题:
在前面您写到:
1、运行Artech.DuplexRemoting.Hosting
2、运行Artech. WCFService.Client
请问怎么做到先运行前者,再运行后者呢?不都在同一个solution吗?这里不明白
  回复  引用    

#184楼 2009-03-08 22:47 goldenlily

问个弱弱的问题:
前面您写到:
1、运行Artech.DuplexRemoting.Hosting
2、运行Artech. WCFService.Client
请问怎么做到先运行前者,后运行后者呢?不都是在同一个solution里吗?这时不明白。麻烦您再说得详细一些,谢谢!
  回复  引用    

#185楼 2009-03-08 22:49 goldenlily

--引用--------------------------------------------------
Artech: @Persevere
<br>启动Artech.DuplexService.Hosting, 再启动Artech.DuplexService.Client
--------------------------------------------------------
问题同前,怎么做到先后启动呢?在同一个解决方案里啊?

  回复  引用    

#186楼 2009-03-08 22:51 goldenlily

--引用--------------------------------------------------
Persevere: 你的例子我怎么老是运行不过去呀?我是刚研究WCF的。请告知,谢谢!
<br>错误原因是: ex.Message &quot;通信对象 System.ServiceModel.Channels.ServiceChannel 无法用于通信,因为其处于“出错”状态。&quot; string
<br>
--------------------------------------------------------
我为SVC已创建了虚拟目录了,可是还是出现上面的错误信息,是怎么回事呢?
  回复  引用    

#187楼[楼主] 2009-03-09 08:43 Artech      

--引用--------------------------------------------------
goldenlily: --引用--------------------------------------------------
Persevere: 你的例子我怎么老是运行不过去呀?我是刚研究WCF的。请告知,谢谢!
&lt;br&gt;错误原因是: ex.Message &amp;quot;通信对象 System.ServiceModel.Channels.ServiceChannel 无法用于通信,因为其处于“出错”状态。&amp;quot; string
&lt;br&gt;
--------------------------------------------------------
我为SVC已创建了虚拟目录了,可是还是出现上面的错误信息,是怎么回事呢?
--------------------------------------------------------
可以试试这个例子:http://www.cnblogs.com/artech/archive/2007/06/18/788071.html" target="_new">http://www.cnblogs.com/artech/archive/2007/06/18/788071.html
  回复  引用  查看    

#188楼[楼主] 2009-03-09 08:44 Artech      

--引用--------------------------------------------------
goldenlily: --引用--------------------------------------------------
Artech: @Persevere
&lt;br&gt;启动Artech.DuplexService.Hosting, 再启动Artech.DuplexService.Client
--------------------------------------------------------
问题同前,怎么做到先后启动呢?在同一个解决方案里啊?


--------------------------------------------------------
右击项目, 选择Debug-〉start new instance
  回复  引用  查看    

#189楼 2009-03-09 18:03 goldenlily

谢谢ARTECH, 运行成功!“右击项目, 选择Debug-〉start new instance ”我以前没有用过(真是不好意思!)谢谢您的回复!   回复  引用    

#190楼 2009-03-09 18:06 goldenlily

再向您请教一下:这个例子从结果上看和前一个例子没有什么分别呢?本身没有体现出“双向通信”的应用呢。不知道是不是我还没有正确理解呢?   回复  引用    

#191楼[楼主] 2009-03-10 08:37 Artech      

--引用--------------------------------------------------
goldenlily: 再向您请教一下:这个例子从结果上看和前一个例子没有什么分别呢?本身没有体现出“双向通信”的应用呢。不知道是不是我还没有正确理解呢?
--------------------------------------------------------
Duplex体现为Callback,服务端调用客户端操作!
  回复  引用  查看    

#192楼 2009-04-06 01:08 寒枫      

感觉Remoting的双向通信貌似比WCF要简洁些,WCF定义太多了。   回复  引用  查看    

#193楼 2009-04-06 01:13 寒枫      

不知道作者提供的Demo中ISessionfulCalculator这个契约是干嘛用的,文中只字没提,忍不住要问下....   回复  引用  查看    

#194楼[楼主] 2009-04-13 08:32 Artech      

--引用--------------------------------------------------
寒枫: 感觉Remoting的双向通信貌似比WCF要简洁些,WCF定义太多了。
--------------------------------------------------------
从复杂度来讲,都差不多了!
  回复  引用  查看    

#195楼[楼主] 2009-04-13 08:33 Artech      

--引用--------------------------------------------------
寒枫: 不知道作者提供的Demo中ISessionfulCalculator这个契约是干嘛用的,文中只字没提,忍不住要问下....
--------------------------------------------------------
ISessionfulCalculator在本篇文章中并没有涉及:)
  回复  引用  查看    

#196楼 2009-05-04 15:37 Bob-wei      

Artech真的很勤快,向您学习了。   回复  引用  查看    

评论共2页: 上一页 1 2 



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 661969




相关文章:

相关链接: