XCFの原形
18225 ワード
前編の回顧
前編では,WCFの契約が必ずしもタイプを生成するのではなく,構成に基づいてもよいかどうかを考え,WCFの原理からその可能性を述べ,最後にXCFの概念を提案した.
2周间の努力を経て、ついに1つの原形を実现して、この1篇の中でどのように1つのXCFの原形をすることを说明します.
実装ベース
まず、WCFクライアント自体がメッセージの送信をサポートします.不思議に聞こえるでしょ?これがみんなの思考がWCFの枠組みの思考の定勢に制限されて、かえってこれらの基礎あるいは原始的な用法を無視しました.
重要なインタフェースを見てみましょう:IRequestChannel
もちろん、WCFのキーインタフェースはこれだけではありませんが、通常のtcp/httpベースのWCFサービスでは、このインタフェースで十分です.このインタフェースを使用して、tcp/httpのwcfサービスに任意のメッセージを送信することができる.もちろん、ここでは、任意のメッセージがサービスのプロトコルに合致しなければならないという問題があります.そうしないと、サービス側はエラーを返します.
サービス・エンドの準備
試験を容易にするために、まず簡単にサービス側契約を準備します.
簡単な実装:
および構成(wcfのログを追加):
ここで注意しなければならないのは、安全な部分を除去することであり、安全なwcfがメッセージ体を修正し、符号化されたメッセージ体を使用することで、原形に少なからぬ面倒をもたらすからである.
標準クライアント
対照的に、まず標準的なクライアントを用意し、プロセスはもちろん標準的なサービス参照を追加します.
次に、前の標準の呼び出しを準備します.
クライアントとサービス側の準備ができたら、シミュレーション呼び出しを行い、wcfログを表示します.
これが要求メッセージ全体のメッセージ体,すなわちXcfを実現するには,この要求を完璧にシミュレートしなければならない.
Xcfクラスライブラリ準備
略:ファイルのダウンロード.
Xcfの使用
まず、クラスライブラリを解凍してプロジェクトに置く、以前に準備したwcfサービスを要求するために、このようなtestを準備する必要がある.xml:
この段落の内容は、前に捕まえたメッセージのBody部分と一致しています.
準備ができました.この原形をサービスに呼び出す方法をshowします.
ここで、fはエンジニアリングであり、cはチャネルであり、readerは要求のbodyを取得するために使用され、要求はactionとbodyの2つの部分から構成され、respは戻りメッセージを保存するために使用され、respBodyはrespメッセージの主体を表す.
実行すると、クライアントに返されたメッセージが表示され、サービス側にもリクエストのNameとAgeが表示され、ログに対応するリクエストとレスポンスメッセージボディが見つかります.
次回予告
これまで原形はよく機能していたが,要求されたWcf呼び出しを変更することはできず,明らかに実用的ではない.焦らないで、このリクエストxmlをどのように生かすかは、次の議題です.
前編では,WCFの契約が必ずしもタイプを生成するのではなく,構成に基づいてもよいかどうかを考え,WCFの原理からその可能性を述べ,最後にXCFの概念を提案した.
2周间の努力を経て、ついに1つの原形を実现して、この1篇の中でどのように1つのXCFの原形をすることを说明します.
実装ベース
まず、WCFクライアント自体がメッセージの送信をサポートします.不思議に聞こえるでしょ?これがみんなの思考がWCFの枠組みの思考の定勢に制限されて、かえってこれらの基礎あるいは原始的な用法を無視しました.
重要なインタフェースを見てみましょう:IRequestChannel
もちろん、WCFのキーインタフェースはこれだけではありませんが、通常のtcp/httpベースのWCFサービスでは、このインタフェースで十分です.このインタフェースを使用して、tcp/httpのwcfサービスに任意のメッセージを送信することができる.もちろん、ここでは、任意のメッセージがサービスのプロトコルに合致しなければならないという問題があります.そうしないと、サービス側はエラーを返します.
サービス・エンドの準備
試験を容易にするために、まず簡単にサービス側契約を準備します.
[ServiceContract(Namespace = "urn:test")]
public interface IEchoService
{
[OperationContract(Action = "Echo")]
Person Echo(Person p);
}
[DataContract(Namespace = "urn:test")]
public class Person
{
[DataMember]
public string Name { get; set; }
[DataMember]
public int Age { get; set; }
}
簡単な実装:
public class EchoService : IEchoService
{
public Person Echo(Person p)
{
Console.WriteLine("Name={0},Age={1}", p.Name, p.Age);
return p;
}
}
および構成(wcfのログを追加):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IEchoService">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="WcfHost.EchoServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="WcfHost.EchoServiceBehavior"
name="WcfHost.EchoService">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IEchoService" contract="WcfHost.IEchoService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:12345/EchoService/" />
</baseAddresses>
</host>
</service>
</services>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="2000"/>
</diagnostics>
</system.serviceModel>
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="messages"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="messages.log" />
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
ここで注意しなければならないのは、安全な部分を除去することであり、安全なwcfがメッセージ体を修正し、符号化されたメッセージ体を使用することで、原形に少なからぬ面倒をもたらすからである.
標準クライアント
対照的に、まず標準的なクライアントを用意し、プロセスはもちろん標準的なサービス参照を追加します.
次に、前の標準の呼び出しを準備します.
Svc.EchoServiceClient client = new WcfNormalClient.Svc.EchoServiceClient();
var resp = client.Echo(new WcfNormalClient.Svc.Person
{
Name = "abc",
Age = 12,
});
client.Close();
Console.WriteLine("Name={0},Age={1}", resp.Name, resp.Age);
クライアントとサービス側の準備ができたら、シミュレーション呼び出しを行い、wcfログを表示します.
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">Echo</a:Action>
<a:MessageID>urn:uuid:fb825687-ad4c-4eab-8b65-0f7c78b9f845</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">http://localhost:12345/EchoService/</a:To>
</s:Header>
<s:Body>
<Echo xmlns="urn:test">
<p xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Age>12</Age>
<Name>abc</Name>
</p>
</Echo>
</s:Body>
</s:Envelope>
これが要求メッセージ全体のメッセージ体,すなわちXcfを実現するには,この要求を完璧にシミュレートしなければならない.
Xcfクラスライブラリ準備
略:ファイルのダウンロード.
Xcfの使用
まず、クラスライブラリを解凍してプロジェクトに置く、以前に準備したwcfサービスを要求するために、このようなtestを準備する必要がある.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Echo xmlns="urn:test">
<p>
<Age>23</Age>
<Name>def</Name>
</p>
</Echo>
この段落の内容は、前に捕まえたメッセージのBody部分と一致しています.
準備ができました.この原形をサービスに呼び出す方法をshowします.
using (var f = new XcfChannelFactory(new WSHttpBinding()))
using (var c = f.Create(new Uri("http://localhost:12345/EchoService/")))
using (var reader = XmlReader.Create("Test.xml"))
using (var resp = c.Request("Echo", reader))
using (var respBody = resp.GetBody())
{
Console.WriteLine(respBody.ReadInnerXml());
}
ここで、fはエンジニアリングであり、cはチャネルであり、readerは要求のbodyを取得するために使用され、要求はactionとbodyの2つの部分から構成され、respは戻りメッセージを保存するために使用され、respBodyはrespメッセージの主体を表す.
実行すると、クライアントに返されたメッセージが表示され、サービス側にもリクエストのNameとAgeが表示され、ログに対応するリクエストとレスポンスメッセージボディが見つかります.
次回予告
これまで原形はよく機能していたが,要求されたWcf呼び出しを変更することはできず,明らかに実用的ではない.焦らないで、このリクエストxmlをどのように生かすかは、次の議題です.