מדריך WCF – לתקשר עם Service שבאויר

רשימת נושאים בפרק 3:

סיכום דוגמת קוד מהפרק הקודם.

מה Client צריך לעשות כדי לתקשר עם ה – Service.

יצירת Client ראשון בעזרת ChannelFactory.

יצירת Client שני בעזרת Service Reference.

סיכום דוגמת קוד מהפרק הקודם

בפרק הקודם למדנו מה צריך לעשות כדי להרים Service לאוויר,

ראשית: לכתוב את ה – Contract (בסך הכול Interface עם Attribute של ServiceContract)

שנית: לממש אותו (בסך הכול מחלקה רגילה המממשת Interface)

שלישית: להחליט מי ה – Host שלנו (בדוגמא מהפרק הקודם הלכנו על Console Application), להגדיר בקובץ הקונפיג את ההגדרות המתאימות (באיזה פרוטוקול, את מה חושפים וכו'), ולהשתמש במחלקה ServiceHost כדי להרים את השירות לאוויר.

כל הקוד ביחד נראה כך:

Contract:

namespace Contarcts
{
[ServiceContract]
public interface ICalc
{
[OperationContract]
int Add(int a, int b);

[OperationContract]
int Sub(int a, int b);
}
}

Service:

namespace Service
{
public class Calc : ICalc
{
public int Add(int a, int b)
{
return a + b;
}

public int Sub(int a, int b)
{
return a - b;
}
}
}

Host – Config:

<system.serviceModel>
<
services>
<
service name="Service.Calc" >
<
endpoint address="http://localhost:8412/MyCalcService"
   binding="basicHttpBinding"
   contract="Contarcts.ICalc"></endpoint>
</
service>
</
services>
</
system.serviceModel
>

Host – Code:

namespace Host
{
class Program
{
static void Main(string[] args)
{
ServiceHost calcHost = new ServiceHost(typeof(Calc));
calcHost.Open();

Console.ReadLine();
}
}
}

כשהקשרים בינייהם נראים כך:

יש לנו שלושה פרוייקטים, Contract, Service, Host

Contract לא מכיר אף אחד ויש לו Reference ל – System.ServiceModel

Service מכיר את Contract

Host מכיר את שניהם  ויש לו Reference ל – System.ServiceModel

אחרי שהחלק הזה קיים, ניתן להריץ את ה – host והוא מחכה לפניות, ברגע שהוא יקבל פניה שמתאימה לאחת מהמתודות שנחשפו דרך ה – Contract הוא יפעיל אותם.

כעת נגש לצד הלקוח.

מה Client צריך לעשות כדי לתקשר עם ה – Service

כדי שלקוח יוכל לפנות לשירות הוא צריך להכיר את ההגדרות של ה – Endpoint שה – Service נחשף דרכו, הוא צריך לדעת באיזה כתובת כמובן ה – Service מאזין ובאיזה פרוטוקולים הוא מוכן לקבל בקשות וכמובן עליו לדעת מה ה – Contract כלומר אילו מתודות אפשר להפעיל.

יצירת Client ראשון בעזרת ChannelFactory

למעשה יש שתי דרכים להגדיר את הלקוח כדי שהוא יוכל לעבוד עם השירות המרוחק, אחת אוטומטית ואחת ידנית, נתחיל עם הידנית:

הלקוח יכול לתקשר עם השירות בעזרת מחלקה מיוחדת הנקראת ChannelFactory, אנחנו נשתמש בה במידה ויש לנו Reference ישיר לפרוייקט ה – Contract (וזה אחת הסיבות שמומלץ להפריד בין הפרוייקטים של ה – Service לבין ה – Contract – מכיון שרק כך הלקוח יכול להחזיק Reference ל – Contract).

נייצר פרוייקט חדש מסוג Console Application ונקרא לו בשם ClientWithChannelFactory.

נוסיף לו Reference לפרוייקט של ה – Contract.

ונכתוב בקונפיג קוד מאוד דומה למה שכתבנו בפרוייקט של ה – Host

<system.serviceModel>
<
client>
<
endpoint name="calcEndpoint"
address="http://localhost:8412/MyCalcService"
binding="basicHttpBinding"
contract="Contarcts.ICalc"></endpoint>
</
client>
</
system.serviceModel
>

אפשר לראות שה – Endpoint מוגדר באותה צורה שבה ה – Host הגדיר, ההבדל היחיד הוא שכאן ה – Endpoint עטוף באלמנט client וב – Host הוא היה עטוף באלמנט service.

בנוסף כאן ה – Endpoint קבל ערך למאפיין name – מיד נבין למה.

כעת נכתוב את הקוד הבא

namespace Client
{
class Program
{
static void Main(string[] args)
{
ChannelFactory<ICalc> channel = new ChannelFactory<ICalc>("calcEndpoint");
ICalc proxy = channel.CreateChannel();

int res = proxy.Add(2, 4);

channel.Close();
}
}
}

נשתמש במחלקה ChannelFactory כדי לייצר מופע שמתייחס ל – ICalc, בבנאי שלו הוא מקבל את השם של ה – Endpoint, לאחר מכן נשתמש במתודה CreateChannel כדי לקבל מופע של ICalc.

ונוכל להתחיל להשתמש במתודות – כמובן שה – Host חייב להיות באויר בזמן שמבצעים את השורות האלו.

יצירת Client שני בעזרת Service Reference

הרבה פעמים אין לנו Reference ישיר מהפרוייקט של ה – Client ל – Contract (או שאנחנו מתעצלים לכתוב לבד) ואנחנו רוצים שזה יקרה בצורה אוטומטית.

אפשר להשתמש בשירות של Visual Studio שנקרא Service Reference כדי לקבל את ה – Proxy, כדי לעשות זאת ה – Host שלנו חייב לחשוף את ה – wsdl (מסמך xml המתאר את השירות), נחזור לפרוייקט של ה – Host ונוסיף בקונפיג את הקוד הבא (מיד אחרי שהאלמנט services נסגר)

<behaviors>
<
serviceBehaviors>
<
behavior>
<
serviceMetadata httpGetEnabled="true"
httpGetUrl="http://localhost:8412/MyCalcService/Help"/>
</
behavior>
</
serviceBehaviors>
</
behaviors
>

בפרק הבא אני אסביר על המושג behaviors – כרגע כל מה שאני אגיד שמדובר בהגדרות שונות על השירות שאנחנו חושפים.

כעת נוסיף פרוייקט חדש מסוג Console Application ונקרא לו ClientWithServiceReference

בשלב הזה אנחנו חייבים להריץ את ה – Host (כדי ש – Visual Studio יוכל לקבל את קובץ ה – wsdl)

נלחץ קליק ימין על Add Reference בפרוייקט החדש ונבחר ב – Add Service Reference.

בתיבת הטקסט נוסיף את ה – url הבא – http://localhost:8412/MyCalcService/Help (הוא אותו כתובת שחשפנו במאפיין httpGetUrl)

נלחץ על GO ולאחר שהוא הוא ימצא את השירות, נכתוב בתיבת הטקסט (למטה) את השם CalcProxy.

Add Service Reference

כשנלחץ OK – הוא יצור עבורנו Proxy וכעת נוכל לכתוב את הקוד הבא:

namespace ClientWithServiceReference
{
class Program
{
static void Main(string[] args)
{
CalcClient proxy = new CalcClient();
int res = proxy.Add(2, 4);
}
}
}

}

אפשר לראות שהוא יצר לנו מאחורי הקלעים מחלקה עם אותו שם של ה – Service והוסיף את הסיומת Client.

בנוסף הוא גם ייצר לנו את קובץ הקונפיג, רק שהוא מוסיף כל מיני אלמנטים שלא צריך אותם אלא אם כן אנחנו רוצים לשנות את הערכים שלהם.

מה שהוא ייצר בקונפיג נראה ככה:

<system.serviceModel>
<
bindings>
<
basicHttpBinding>
<
binding name="BasicHttpBinding_ICalc" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                useDefaultWebProxy="true">
<
readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<
security mode="None">
<
transport clientCredentialType="None" proxyCredentialType="None"
                        realm="" />
<
message clientCredentialType="UserName" algorithmSuite="Default" />
</
security>
</
binding>
</
basicHttpBinding>
</
bindings>
<
client>
<
endpoint address="http://localhost:8412/MyCalcService" binding="basicHttpBinding"
            bindingConfiguration="BasicHttpBinding_ICalc" contract="CalcProxy.ICalc"
            name="BasicHttpBinding_ICalc" />
</
client>
</
system.serviceModel
>

זה קצת מבהיל בפעם הראשונה שמסתכלים על זה – אבל אל דאגה – בהמשך הפרקים נלמד ונבין כל אלמנט, כרגע אפשר פשוט למחוק את כל החלק העליון (bindings) וגם למחוק מהחלק התחתון את המאפיין bindingConfiguration,

בסופו של דבר כדי שזה יעבוד הקונפיג יכול להיראות כך:

<system.serviceModel>
<
client>
<
endpoint address="http://localhost:8412/MyCalcService"
   binding="basicHttpBinding"
   contract="CalcProxy.ICalc"
   name="BasicHttpBinding_ICalc" />
</
client>
</
system.serviceModel
>

שזה די דומה למה שאנחנו עשינו.

 

בפרק הבא נכנס קצת יותר לעומק למושגים Binding ו – Behaviors

תגיות:

תגובות בפייסבוק