Monday, February 25, 2008 7:38 PM
kolbis
How to update client GUI from a Server using WCF?
The title is a bit confusing. So, in order to solve that, let me explain the meaning of it.
Lets say I have a Client - Server application.
The server is hosted in a console application and can perform several operations that are requested from a client application.
The client application is a windows application that sends messages to the server using WCF.
One thing that I think is extremely important when developing such applications is the acknowledgement process. In other words, I want to know that the operation I invoked from the client against the server completed successfully or failed.
In order to do so, I would like the server to send the client an acknowledgement upon completion. There are several ways of doing so, however I will describe my way.
I have selected to create a service that will be exposed from the client and will be hosted in the windows application. The server will add a service reference to it and will be able to report the client of its progress. So far everything is pretty straight forward.
The code should look something like this:
[ServiceContract(Namespace = "http://www.QTech.co.il/08/01/20")]
public interface IAknowledgemnt
{
[OperationContract]
void Aknowledge(AknowledgeInfo aknowledge);
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class AknowledgemntService : IAknowledgemnt
{
#region IAknowledgemnt Members
public void Aknowledge(AknowledgeInfo aknowledge)
{
}
#endregion
}
The server will add a service reference and will send messages to the AknowledgementService. The challenge is to upon receiving the message do some GUI related operations, such as displaying progress bar or adding the message into a log control or simply pop up a message box.
In order to achieve that, I will need to alert the GUI. To do so, I will use static events and will modify the AknowledgementService as follows:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class AknowledgemntService : IAknowledgemnt
{
private static EventHandlerList _eventHandlers = new EventHandlerList();
private static readonly object _dataArriveKey = new object();
public static event DataArriveEventHandler DataArrive
{
add
{
_eventHandlers.AddHandler(_dataArriveKey, value);
}
remove
{
_eventHandlers.RemoveHandler(_dataArriveKey, value);
}
}
internal void OnDataArrive(AknowledgeInfo aknowledge)
{
DataArriveEventHandler myEvent = _eventHandlers[_dataArriveKey] as DataArriveEventHandler;
if (myEvent != null)
myEvent(null, new DataArriveEventArgs(aknowledge));
}
#region IAknowledgemnt Members
public void Aknowledge(AknowledgeInfo aknowledge)
{
OnDataArrive(aknowledge);
}
#endregion
}
public delegate void DataArriveEventHandler(object sender, DataArriveEventArgs e);
public class DataArriveEventArgs : EventArgs
{
private AknowledgeInfo _aknowledge;
public string Aknowledge
{
get { return _aknowledge; }
set
{
_aknowledge = value;
}
}
public DataArriveEventArgs(AknowledgeInfo aknowledge)
{
_aknowledge = aknowledge;
}
}
The addition to the code is with regards to the events. Once a new message arrives from the server I will fire the event to all whom are registered to it.
We have one more peace to add to the passel and it is the consuming of the service from the client. The client must register to the event, right? So here is the basic concept for that:
public partial class CtrlAknowledge : UserControl
{
AknowledgemntService _aknowledgemntService;
public CtrlAknowledge()
{
InitializeComponent();
_aknowledgemntService = new AknowledgemntService();
AknowledgemntService.DataArrive += new DataArriveEventHandler(OnDataArrive);
}
void OnDataArrive(object sender, DataArriveEventArgs e)
{
MessageBox.Show("OK");
}
}
By adding your own custom logic to the OnDataArrive method, you can display the message arrived from the server on to the GUI.
תגים:.NET Framework 3.0, WCF, .NET Framework 3.5