Vous êtes sur la page 1sur 12

VISOKA ŠKOLA ZA INFORMACIJSKE TEHNOLOGIJE

DISTRIBUIRANO OBJEKTNO
PROGRAMIRANJE

5. LABORATORIJSKA VJEŽBA

Microsoft WCF

(Windows Communication Foundation)


Zoran Radek

V1.00

Distribuirano Objektno Programiranje 1


Zagreb, travanj 2021

Kreiranje servisa (server)

1. Sučelje

Implementirat ćemo servis kroz jednostavnu Windows Forms aplikaciju. Kreirajte novi
projekt, Visual C#, Windows Forms App (.Net Framework). Nazovite ga
BMICalcServer. Dodajte na GUI jednu labelu i gumb prema slici.

Distribuirano Objektno Programiranje 2


2. Service Contract

Da bi kreirali servis u sklopu WCF platforme, potrebno je napraviti nekoliko detalja:


- dodajte referencu na System.ServiceModel Assembly. U solution exploreru,
desni klik na References, Add Reference.

- U datoteku form1.cs dodati using System.ServiceModel


- U istu datoteku dodajte interface koji će naš servis implementirati. Možete ga
dodati na kraj, iza klase Form1 (ukoliko Form1 nije prva klasa u datoteci,
moglo bi biti problema sa grafičkim sučeljem).
Nazvat ćemo ga IBMICalcInterface. Obratite pažnju na [ServiceContract] i
[OperationContract] deklaracije.
Ovime smo završili ServiceContract deklaraciju čime smo definirali što sve naš servis
mora nuditi, odnosno čemu će sve klijenti imati pristup. U našem slučaju, to je samo
funkcija CalcBMI.

Distribuirano Objektno Programiranje 3


// dodano
using System.ServiceModel;

namespace BMICalcServer
{
public partial class Form1 : Form...

[ServiceContract] //Označava da ovaj interface definira WCF servis.


interface IBMICalcService
{
[OperationContract] //označava da je ova metoda dio WCF servisa (klijent je vidi)
float CalcBMI(float mass, float height);
}

Sljedeći korak je DataContract deklaracija. Ovdje se definiraju custom podatkovne


strukture koje se koriste u interface-u. Slično kao i elementi Service Contract-a, i ovi
elementi se moraju adekvatno označiti: klasa koja predstavlja podatkovnu strukturu
mora se kvalificirati kao [DataContract], dok se svaki element mora kvalificirati kao
[DataMember]
Pošto funkcija iz našeg interface-a ne koristi custom podatkovne strukture niti kao
parametre, niti kao return value, možemo preskočiti ovaj korak.

3. Implementacija servisa

U datoteku Form1.cs, iza interface-a, dodajte klasu koja ga implementira. Nazovimo


je BMICalcService.

class BMICalcService : IBMICalcService


{
public float CalcBMI(float mass, float height)
{
return mass/(height*height);
}
}

Distribuirano Objektno Programiranje 4


4. Konfiguracija servisa

Otvorite datoteku App.config te u nju dodajte sljedeći kod (žuto označeni dio), odmah
iza linije (odnosno unutar taga) <configuration>:

<?xml version="1.0" encoding="utf-8" ?>


<configuration>
<system.serviceModel>
<services>
<service name="BMICalcServer.BMICalcService" behaviorConfiguration="BMICalcServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:9999/BMICalcService" />
</baseAddresses>
</host>
<endpoint address="" binding="basicHttpBinding" contract="BMICalcServer.IBMICalcService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="BMICalcServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>

<system.serviceModel> je krovni tag. Unutar njega se nalazi tag <services> u


kojemu su definirani svi servisi i pripadni endpointovi, svaki unutar svojeg <service>
taga. Mi imamo samo jedan servis pa imamo i samo jedan <service> tag. Unutar
<service> taga se u atributu „name“ nalazi ime klase koja implementira
[ServiceContract] interface.

Unutar <endpoint> taga imamo atribute:

- address: dio koji se dodaje na baznu adresu. Nama je prazno, što znači da
nam je puna adresa servisa upravo bazna adresa, definirana unutar
<baseAddresses> taga: http://localhost:9999/BMICalcService
- binding atribut definira transportni protokol koji servis koristi
- contract atribut sadrži ime [ServiceContract] interface-a.

Distribuirano Objektno Programiranje 5


5. Hostanje servisa

Preostaje samo još pokrenuti servis, te ga zatvoriti prilikom izlaska. Dodajte u klasu
Form1 sljedeći kod (označeno žuto).

public partial class Form1 : Form


{
ServiceHost server;

public Form1()
{
server = new ServiceHost(typeof(BMICalcService));
server.Open();
InitializeComponent();
}

private void buttonExit_Click(object sender, EventArgs e)


{
server.Close();
Application.Exit();
}
}

Za hostanje servisa koristimo ServiceHost klasu. Pokretanje i zatvaranje servisa se


radi pomoću Open() i Close() metoda.

Server je spreman. Da bi ga pokrenuli, morat ćete Visual studio pokrenuti kao


administrator. U suprotnom će se na liniji server.Open(); javiti greška „your process
does not have access rights to this namespace“.

Distribuirano Objektno Programiranje 6


Konzumacija servisa (klijent)

Kad je server pokrenut, možemo otvoriti punu adresu servisa u browseru (sjetite se,
to je: http://localhost:9999/BMICalcService). Na njoj možemo saznati WSDL adresu
servisa.

U novoj instanci Visual Studia (ovaj put je ne morate pokrenuti kao administrator)
kreirajte novi projekt, Visual C#, Windows Forms App (.Net Framework). Nazovite ga
BMICalcClient.

Dodajte referencu na serverski servis, prema slici (U solution exploreru, desni klik na
References, Add Service Reference). U polje Address upišite WDSL adresu servisa.
Pod Namespace upišite BMICalcService.

Distribuirano Objektno Programiranje 7


Distribuirano Objektno Programiranje 8
Na sučelje ćemo ovaj put dodati tri textbox itema sa odgovarajućim te jedan button
za poziv izračuna. Textbox iteme nazovite: textBoxVisina, textBoxTezina i
textBoxBMI kako bi kod iz nastavka vježbe odgovarao (u suprotnom možete u kodu
zamijeniti imena tih varijabli sa stvarnim imenima iz vašeg projekta).

Što se koda tiče, unutar datoteke Form1.cs, napravit ćemo sljedeće (opet, označeno
žuto):

- dodat ćemo using BMICalcClient.BMICalcService;


- Unutar klase Form1 ćemo objekt client koji se veže na servis koji smo kreirali
u prvom dijelu (moramo ga kasnije i inicijalizirati) te float varijable za težinu i
visinu.
- Na klik gumbića dodat ćemo poziv izračuna na udaljenom objektu (korištenje
servisa).

// dodano
using BMICalcClient.BMICalcService;

namespace BMICalcClient
{
public partial class Form1 : Form
{
BMICalcServiceClient client;
float l_tezina;
float l_visina;

public Form1()
{
client = new BMICalcServiceClient();
InitializeComponent();
}

private void buttonBMI_Click(object sender, EventArgs e)


{
if ( float.TryParse(textBoxTezina.Text, out l_tezina)
& float.TryParse(textBoxVisina.Text, out l_visina))
{
textBoxBMI.Text = client.CalcBMI(l_tezina, l_visina).ToString();
}
}
}

Distribuirano Objektno Programiranje 9


Distribuirano Objektno Programiranje 10
Zadatak:

Nakon uspješnog buildanja pokrenite obje aplikacije. Na klijentu popunite polja za


visinu/težinu i pokrenute izračun. Naravno, podrazumijeva se da je visina u metrima
(npr. 2), a težina u kg (npr. 100).

Kao samostalni zadatak, proširite funkciju iz interface-a sa dodatnim parametrom:

float CalcBMI(float mass, float height, string height_unit);

U implementaciju te funkcije dodajte odgovarajući kod za konverziju iz raznih drugih


jedinica.. npr:

public float CalcBMI(float mass, float height, string height_unit)


{
if (height_unit.Equals("cm"))
{
height = height / 100;
}
return mass / (height * height);
}

Na klijentu dodajte polje u kojem će korisnik moći upisati mjernu jedinicu za visinu te
iskoristite i sadržaj tog polja za upit prema servisu.

Primijetite da i nakon što napravite sve promjene na strani servisa, klijent i dalje
„misli“ da funkcija ima samo dva parametra. Da bi se promjene vidjele na klijentu,
morat ćete ažurirati referencu na servis (update service reference):

Distribuirano Objektno Programiranje 11


Problem sa ovim upisom je što klijent ne može znati koje su jedinice podržane na
serveru. Ono što bi možda dobro došlo je nova funkcija na interface-u/serveru koja bi
vraćala listu podržanih jedinica, a na klijentu bi onda tu listu mogli ponuditi korisniku
na izbor. Pokušajte implementirati i ovu funkcionalnost.

Ovo je jednostavan primjer koji ilustrira način na koji se kreiraju i koriste WCF servisi.
Izračun BMI je jednostavan te za njega u stvarnosti nije potrebno koristiti vanjski
dedicirani servis. Razmislite i navedite nekoliko realnih primjera koji bi bili primjereniji
za realizaciju pomoću servisa.

Kao rješenje vježbe, pošaljite mail sa odgovorom na pitanje na adresu asistenta. Kao
attachment maila dodajte formi1.cs datoteke iz oba projekta.

Distribuirano Objektno Programiranje 12

Vous aimerez peut-être aussi