在本次实验中你将会看到几种不同的operation方式:request/reply、one-way和duplex callbacks。打开Operation文件夹下的Operation.sln解决方案。程序是一个交通灯的管理系统。
解决方案包含了三个项目:
TrafficLightClient项目包含了一个winform程序,用来表示单个交通灯:
 Step by Step WCF—Operaton and Calls
TrafficController项目包含了一个winform程序,用来设置当前交通灯的状态:
 Step by Step WCF—Operaton and Calls
你可以通过RadioButton来设置交通灯的状态,并通过点击Timer button来启动一个Timer来自动改变所有交通灯的状态。
最后,TraficLightService项目包含了一个服务,用来接受交通灯的新状态,并把这个状态通知所有正在运行的交通灯。

这个程序的架构如图所示:
 Step by Step WCF—Operaton and Calls
交通灯连接到TrafficLightService来订阅交通灯状态。TrafficControllerForm会调用TrafficLightService并通知它新的交通灯的状态。TrafficLightService再把这个状态通知到所有的订阅者。
编译并运行程序,现在还没有很多事情会发生。目前唯一的contract是ITrafficLightStatus,TrafficControllerForm用它来设置状态:

Step by Step WCF—Operaton and Callsenum LightColor
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls   Red,
Step by Step WCF—Operaton and Calls   Yellow,
Step by Step WCF—Operaton and Calls   Green
Step by Step WCF—Operaton and Calls}

Step by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls[ServiceContract]
Step by Step WCF—Operaton and Calls
interface ITrafficLightStatus
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls   [OperationContract]
Step by Step WCF—Operaton and Calls   
void
 SetState(LightColor color);
Step by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls   [OperationContract]
Step by Step WCF—Operaton and Calls   LightColor GetState();
Step by Step WCF—Operaton and Calls}

Step by Step WCF—Operaton and Calls


开发Service
TrafficLightService实现了ITrafficLightStatus接口:

Step by Step WCF—Operaton and Calls[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
Step by Step WCF—Operaton and Calls
class
 TrafficLightService : ITrafficLightStatus
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls   LightColor m_Color 
=
 LightColor.Red;
Step by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls   
public void
 SetState(LightColor color)
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls   
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls      m_Color 
=
 color;
Step by Step WCF—Operaton and Calls   }

Step by Step WCF—Operaton and Calls   
public LightColor GetState()
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls   
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls      
return
 m_Color;
Step by Step WCF—Operaton and Calls   }

Step by Step WCF—Operaton and Calls}

Step by Step WCF—Operaton and Calls


TrafficLightService是一个单实例,也就是所有的client端都可以访问到它的状态。我们还需要添加一些功能让client端能够连接到service,并且让service回调它们通知状态。
在TrafficLightService.cs文件中加入ITrafficLightManager和ITrafficLightManagerCallback接口:

Step by Step WCF—Operaton and Calls[ServiceContract(CallbackContract=typeof(ITrafficLightManagerCallback))]
Step by Step WCF—Operaton and Calls
interface
 ITrafficLightManager
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls    [OperationContract]
Step by Step WCF—Operaton and Calls    LightColor Connect();
Step by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls    [OperationContract]
Step by Step WCF—Operaton and Calls    
void
 Disconnect();
Step by Step WCF—Operaton and Calls}

Step by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls
interface ITrafficLightManagerCallback
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls    [OperationContract(IsOneWay
=true
)]
Step by Step WCF—Operaton and Calls    
void
 OnStateChanged(LightColor newColor);
Step by Step WCF—Operaton and Calls}

Step by Step WCF—Operaton and Calls


ITrafficLightManager只有一个任务,就是让client连接或者断开服务。并且告诉了WCF回调的接口。
TrafficLightService将会保存回调的引用,这样当交通灯状态改变时,它将会通知所有的client端这个新的状态。添加如下代码:

Step by Step WCF—Operaton and Calls[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
Step by Step WCF—Operaton and Calls
class
 TrafficLightService : ITrafficLightStatus, ITrafficLightManager
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls    LightColor m_Color 
=
 LightColor.Red;
Step by Step WCF—Operaton and Calls    List
<ITrafficLightManagerCallback> m_Callback = new List<ITrafficLightManagerCallback>
();
Step by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls    
public void
 SetState(LightColor color)
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls    
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls        m_Color 
=
 color;
Step by Step WCF—Operaton and Calls        m_Callback.ForEach(
delegate
(ITrafficLightManagerCallback callback)
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls        
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls            callback.OnStateChanged(color);
Step by Step WCF—Operaton and Calls        }
);
Step by Step WCF—Operaton and Calls    }

Step by Step WCF—Operaton and Calls    ……
Step by Step WCF—Operaton and Calls    
public LightColor Connect()
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls    
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls        ITrafficLightManagerCallback callback 
= OperationContext.Current.GetCallbackChannel<ITrafficLightManagerCallback>
();
Step by Step WCF—Operaton and Calls        m_Callback.Add(callback);
Step by Step WCF—Operaton and Calls        
return
 m_Color;
Step by Step WCF—Operaton and Calls    }

Step by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls    
public void Disconnect()
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls    
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls        ITrafficLightManagerCallback callback 
= OperationContext.Current.GetCallbackChannel<ITrafficLightManagerCallback>
();
Step by Step WCF—Operaton and Calls        m_Callback.Remove(callback);
Step by Step WCF—Operaton and Calls    }

Step by Step WCF—Operaton and Calls}

Step by Step WCF—Operaton and Calls

在app.config中为ITrafficLightManager添加endpoint:

Step by Step WCF—Operaton and Calls<services>
Step by Step WCF—Operaton and Calls 
<service name = "TrafficLightService">
Step by Step WCF—Operaton and Calls  
<endpoint
Step by Step WCF—Operaton and Calls     
address  = "net.tcp://localhost:8001/TrafficLightService"

Step by Step WCF—Operaton and Calls     binding  
= "netTcpBinding"
Step by Step WCF—Operaton and Calls     contract 
= "ITrafficLightStatus"
Step by Step WCF—Operaton and Calls    
/>
Step by Step WCF—Operaton and Calls  
<endpoint 
Step by Step WCF—Operaton and Calls   
address="net.tcp://localhost:8002/TrafficLightService"
 
Step by Step WCF—Operaton and Calls   binding
="netTcpBinding"
 
Step by Step WCF—Operaton and Calls   contract
="ITrafficLightManager"
 
Step by Step WCF—Operaton and Calls 
/>

Step by Step WCF—Operaton and Calls 
</service>
Step by Step WCF—Operaton and Calls
</services>


编译程序,确保服务器端都正确。

开发client
在Proxy.cs文件中添加如下的定义:

Step by Step WCF—Operaton and Calls[ServiceContract(CallbackContract = typeof(ITrafficLightManagerCallback))]
Step by Step WCF—Operaton and Calls
interface
 ITrafficLightManager
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls    [OperationContract]
Step by Step WCF—Operaton and Calls    LightColor Connect();
Step by Step WCF—Operaton and Calls    [OperationContract]
Step by Step WCF—Operaton and Calls    
void
 Disconnect();
Step by Step WCF—Operaton and Calls}

Step by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls
interface ITrafficLightManagerCallback
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls    [OperationContract(IsOneWay
=true
)]
Step by Step WCF—Operaton and Calls    
void
 OnStateChanged(LightColor newColor);
Step by Step WCF—Operaton and Calls}

Step by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls
class TrafficLightManagerClient : DuplexClientBase<ITrafficLightManager>, ITrafficLightManager
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls    
public
 TrafficLightManagerClient(InstanceContext inputInstance)
Step by Step WCF—Operaton and Calls        : 
base
(inputInstance)
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls    
Step by Step WCF—Operaton and Calls{ }

Step by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls    
public LightColor Connect()
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls    
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls        
return
 Channel.Connect();
Step by Step WCF—Operaton and Calls    }

Step by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls    
public void Disconnect()
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls    
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls        Channel.Disconnect();
Step by Step WCF—Operaton and Calls    }

Step by Step WCF—Operaton and Calls}

Step by Step WCF—Operaton and Calls


注意到TrafficLightManagerClient是从DuplexClientBase<T>这个基类继承而来,主要的目的就是为了回调。
修改TrafficLightClient项目的app.config文件,加入endpoint:

Step by Step WCF—Operaton and Calls  <client>
Step by Step WCF—Operaton and Calls   
<endpoint 
Step by Step WCF—Operaton and Calls    
address="net.tcp://localhost:8002/TrafficLightService"
 
Step by Step WCF—Operaton and Calls    binding
="netTcpBinding"
 
Step by Step WCF—Operaton and Calls    contract
="ITrafficLightManager" />

Step by Step WCF—Operaton and Calls  
</client>
Step by Step WCF—Operaton and Calls

打开TrafficLight.cs文件,加入ITrafficLightManager的实现,添加一个代理类的实例;向服务端出入一个引用。

Step by Step WCF—Operaton and Callspartial class TrafficLight : Form, ITrafficLightManagerCallback
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls    TrafficLightManagerClient m_TrafficManager;
Step by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls    
public
 TrafficLight()
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls    
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls        InitializeComponent();
Step by Step WCF—Operaton and Calls        InstanceContext instance 
= new InstanceContext(this
);
Step by Step WCF—Operaton and Calls        m_TrafficManager 
= new
 TrafficLightManagerClient(instance);
Step by Step WCF—Operaton and Calls        m_TrafficLightControl.State 
=
 m_TrafficManager.Connect();
Step by Step WCF—Operaton and Calls    }

Step by Step WCF—Operaton and Calls    
void OnClosing(object sender, FormClosingEventArgs e)
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls    
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls        m_TrafficManager.Disconnect();
Step by Step WCF—Operaton and Calls        m_TrafficManager.Close();
Step by Step WCF—Operaton and Calls    }

Step by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls    
public void OnStateChanged(LightColor newColor)
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls    
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls        Thread.Sleep(
300
);
Step by Step WCF—Operaton and Calls        m_TrafficLightControl.State 
=
 newColor;
Step by Step WCF—Operaton and Calls    }

Step by Step WCF—Operaton and Calls}

Step by Step WCF—Operaton and Calls

运行程序
解决方案已经配置为了多项目启动,直接按F5编译并运行程序。为了观察多个client端的运行情况,可以多启动几个client端:
 
我们可以观察到在OnStateChanged方法中会有延迟,几个client端不是同时在改变状态。解决这个问题我们可以将这个通知client的方法配置为one-way。在TrafficLightService.cs文件中将OnStateChanged方法配置为one-way:

Step by Step WCF—Operaton and Callsinterface ITrafficLightManagerCallback
Step by Step WCF—Operaton and CallsStep by Step WCF—Operaton and Calls
Step by Step WCF—Operaton and Calls
{
Step by Step WCF—Operaton and Calls    [OperationContract(IsOneWay
=true
)]
Step by Step WCF—Operaton and Calls    
void
 OnStateChanged(LightColor newColor);
Step by Step WCF—Operaton and Calls}


这下再运行一下程序,所有client端就会一起改变状态了。

转载于:https://www.cnblogs.com/dongxue/archive/2008/07/23/1249763.html

相关文章:

  • 2022-12-23
  • 2021-11-01
  • 2021-08-14
  • 2021-11-14
  • 2021-10-14
  • 2022-01-16
  • 2021-06-11
  • 2022-01-18
猜你喜欢
  • 2021-12-04
  • 2021-10-13
  • 2022-01-22
  • 2022-03-05
  • 2021-08-27
相关资源
相似解决方案