WCF: делаем форму службой
Всем доброго времени суток. На связи Алексей Гулынин. Продолжаем работать с WCF. Часто возникает вопрос: как службе получить ссылку на форму, т.е. получить доступ к пользовательскому интерфейсу? Одним из вариантов будет сделать саму форму службой. Мы создаём форму, которая будет реализовывать контракт. Создадим простое Windows Forms-приложение, которое будет состоять из серверной и клиентской частей.
Накидайте на формы элементы управления так, чтобы они выглядели следующим образом:
Файл IContract.cs (наш контракт) добавляем в оба проекта. Не забываем подключать System.ServiceModel:
[ServiceContract] interface IContract { [OperationContract] string Print(string str); }
Клиентский код будет выглядеть следующим образом:
using System; using System.ServiceModel; using System.Windows.Forms; namespace Client { public partial class Form1 : Form { // Адрес Uri address = new Uri("http://localhost:343/IContract"); // Привязка BasicHttpBinding binding = new BasicHttpBinding(); // Фабрика каналов, один из которых будет реализовать контракт ChannelFactory<IContract> factory; // Ссылка на канал. IContract channel; public Form1() { InitializeComponent(); } private void btn_Send_Click(object sender, EventArgs e) { try { if (factory == null) { factory = new ChannelFactory<IContract>(binding, new EndpointAddress(address)); // Создаём канал channel = factory.CreateChannel(); } if (factory != null && channel != null) { tB_Client_Info.Text += "Моё сообщение: " + tB_Client_Send.Text + Environment.NewLine; // Здесь уже сервер отправляет сообщение клиенту tB_Client_Info.Text += "Сообщение с сервера: " + channel.Print(tB_Client_Send.Text) + Environment.NewLine; // Обнуляем поле с текстом для отправки сообщения tB_Client_Send.Text = ""; } } catch (Exception ex) { MessageBox.Show(ex.Message); } } } }
Код серверной части:
using System; using System.Windows.Forms; using System.ServiceModel; namespace Server { // Это означает, что экземпляр данного класса будет являться единственным. [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] // Здесь как раз указываем, что форма реализует интерфейс public partial class Form1 : Form, IContract { // Ссылка на экземпляр ServiceHost. ServiceHost serviceHost; public Form1() { InitializeComponent(); } private void btn_Start_Click(object sender, EventArgs e) { try { // Если хост ещё не запущен if (serviceHost == null) { // Создание экземпляра ServiceHost // Здесь мы передаём экземпляр самой формы serviceHost = new ServiceHost(this); // Ждём прихода новых сообщений serviceHost.Open(); tB_Server_Info.Text += "Сервер запущен." + Environment.NewLine; } } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void btn_Stop_Click(object sender, EventArgs e) { try { // Если уже хост запущен if (serviceHost != null) { // Останавливаем сервер serviceHost.Close(); serviceHost = null; tB_Server_Info.Text += "Сервер остановлен." + Environment.NewLine; } } catch (Exception ex) { MessageBox.Show(ex.Message); } } // Реализуем контракт (определяем метод Print) public string Print(string str) { tB_Server_Info.Text += "От клиента пришло сообщение: " + str + Environment.NewLine; return "Сообщение клиента: " + str; } } }
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name ="Server.Form1"> <host> <baseAddresses> <add baseAddress="http://localhost:343/IContract"/> </baseAddresses> </host> <!-- указываем адрес, привязку и контракт --> <endpoint address="" binding="basicHttpBinding" contract="Server.IContract" /> </service> </services> </system.serviceModel> </configuration>
Сначала запускаем сервер, а далее клиента. Видим, что всё корректно работает:
В данной статье вы научились делать форму службой WCF.
На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.