<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      code4fun:host wcf service just in time

      當ServiceContract非常多的情況下,比如要self-host hundred of service的時候,or更多的時候,每次hosting都是建立一個tcp listen.這樣,host的init工作會占用非常多的時間和資源。對于一些對start有較快需求的case,這明顯會影響用戶體驗。本文意在尋求一種技術手段解決這個問題,讓service只有在運行時才host。我們姑且稱之為host just in time吧

      先說一下思路。

      client如果能發送消息給service,并且消息可達,先決條件就是消息到達service之前,service已經被host,注意,是說消息到達之前,而并不是在客戶端發送消息之后,這就給我們提供了一個可以做手腳的時期,即消息從客戶端發送出去到消息在被服務端接收之前這段時間,如果我們能Inspect它,并根據其self description,便能在消息發送到真正的服務之前,host那個service,而做這樣一個事情,rounter明顯是最在行的了。下面是實現host just in time的原理圖。

      image

      按照上面的思路,做了一個簡單的demo,過程如下

      首先創建Contracts項目Jillzhang.Wcf.HostJIT.Contracts,包含兩個ServiceContract:ICalculator和IActivity,代碼分別為:

      ICalculator:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.ServiceModel;
      namespace Jillzhang.Wcf.HostJIT.Contracts
      {
      [ServiceContract]
      public interface  ICalculator
      {
      [OperationContract]
      int Add(int a, int b);
      }
      }

      IActivity:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.ServiceModel;
      namespace Jillzhang.Wcf.HostJIT.Contracts
      {
      [ServiceContract]
      public interface IActivity
      {
      [OperationContract]
      void Excute();
      }
      }

      demo只模擬對這兩個ServiceContract的host just in time

      建立好契約項目之后,新建服務項目:Jillzhang.Wcf.HostJIT.Services,添加兩個類:Caculator和Activity,分別實現ICalculator和IActivity,其代碼如下:

      Caculator:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using Jillzhang.Wcf.HostJIT.Contracts;
      namespace Jillzhang.Wcf.HostJIT.Services
      {
      public class Calculator : ICalculator
      {
      public int Add(int a, int b)
      {
      return a + b;
      }
      }
      }

      Activity:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using Jillzhang.Wcf.HostJIT.Contracts;
      namespace Jillzhang.Wcf.HostJIT.Services
      {
      public class Activity:IActivity
      {
      public void Excute()
      {
      Console.WriteLine("activity is running!");
      }
      }
      }

      接著,我們需要簡歷本實例中最重要的項目:Jillzhang.Wcf.HostJIT.Dispatcher,這個項目的release自身就是一個對wcf service的self-host的hosting app.為了實現路由,截獲以及調度的功能,實現了路由接口IRounter和類Dispatcher,下面是他們的code:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.ServiceModel;
      using System.ServiceModel.Channels;
      using System.Collections;
      using Jillzhang.Wcf.HostJIT.Services;
      namespace Jillzhang.Wcf.HostJIT.Dispatcher
      {
      [ServiceContract]
      public interface IRounter
      {
      [OperationContract(Action = "*", ReplyAction = "*")]
      Message ProcessMessage(Message msg);
      }
      [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
      public class Dispatcher : IRounter
      {
      public static readonly Hashtable hostTable = new Hashtable();
      public Message ProcessMessage(Message msg)
      {
      string to = msg.Headers.To.ToString();
      string serviceName = "";
      //todo:if no host,host first
      if (to.IndexOf("8031") > -1)
      {
      if (!hostTable.ContainsKey("Calculator"))
      {
      ServiceHost host = new ServiceHost(typeof(Calculator));
      host.Opened += new EventHandler(delegate(object sender, EventArgs arg)
      {
      Console.WriteLine("Calculator service is opened!");
      });
      host.Open();
      hostTable.Add("Calculator", host);
      }
      serviceName = "Calculator";
      }
      else
      {
      if (!hostTable.ContainsKey("Activity"))
      {
      ServiceHost host = new ServiceHost(typeof(Activity));
      host.Opened += new EventHandler(delegate(object sender, EventArgs arg)
      {
      Console.WriteLine("activity service is opened!");
      });
      host.Open();
      hostTable.Add("Activity", host);
      }
      serviceName = "Activity";
      }
      //todo:rounter the message
      using (ChannelFactory<IRounter> channelFactory = new ChannelFactory<IRounter>(serviceName))
      {
      var chanenl = channelFactory.CreateChannel();
      using (chanenl as IDisposable)
      {
      return chanenl.ProcessMessage(msg);
      }
      }
      }
      }
      }

      通過代碼可以看出,首先Dispatcher是一個有路由功能的服務,它會根據message中Header中的To判斷要調用的Service是哪一個,然后判斷是否已經承載了那個最終目的的Service,如果沒有,host frist and add it to hostTable ,host之后,就可以將消息調度給真正的服務了。

      app.config的代碼如下:

      <?xml version="1.0" encoding="utf-8" ?>
      <configuration>
      <system.serviceModel>
      <services>
      <service name="Jillzhang.Wcf.HostJIT.Services.Calculator">
      <host>
      <baseAddresses>
      <add baseAddress="net.tcp://127.0.0.1:8031"/>
      </baseAddresses>
      </host>
      <endpoint address="Calculator" binding="netTcpBinding" contract="Jillzhang.Wcf.HostJIT.Contracts.ICalculator"></endpoint>
      </service>
      <service name="Jillzhang.Wcf.HostJIT.Services.Activity">
      <host>
      <baseAddresses>
      <add baseAddress="net.tcp://127.0.0.1:8032"/>
      </baseAddresses>
      </host>
      <endpoint address="Activity" binding="netTcpBinding" contract="Jillzhang.Wcf.HostJIT.Contracts.IActivity"></endpoint>
      </service>
      <service name="Jillzhang.Wcf.HostJIT.Dispatcher.Dispatcher">
      <host>
      <baseAddresses>
      <add baseAddress="net.tcp://127.0.0.1:8030"/>
      </baseAddresses>
      </host>
      <endpoint address="" binding="netTcpBinding" contract="Jillzhang.Wcf.HostJIT.Dispatcher.IRounter"></endpoint>
      </service>
      </services>
      <client>
      <endpoint  address="net.tcp://127.0.0.1:8031/Calculator" binding="netTcpBinding" contract="Jillzhang.Wcf.HostJIT.Dispatcher.IRounter" name="Calculator"></endpoint>
      <endpoint  address="net.tcp://127.0.0.1:8032/Activity" binding="netTcpBinding" contract="Jillzhang.Wcf.HostJIT.Dispatcher.IRounter" name="Activity"></endpoint>
      </client>
      </system.serviceModel>
      </configuration>

      而在這個項目中,我們開始只需要host IRounter契約。host代碼為:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.ServiceModel;
      namespace Jillzhang.Wcf.HostJIT.Dispatcher
      {
      class Program
      {
      static void Main(string[] args)
      {
      using (ServiceHost host = new ServiceHost(typeof(Dispatcher)))
      {
      host.Opened += new EventHandler(delegate(object sender, EventArgs arg)
      {
      Console.WriteLine("dispatcher service is opened!");
      });
      host.Open();
      Console.Read();
      }
      }
      }
      }

      建立客戶端程序Jillzhang.Wcf.HostJIT.Client,并且將app.config更改為:

      <?xml version="1.0" encoding="utf-8" ?>
      <configuration>
      <system.serviceModel>
      <client>
      <endpoint behaviorConfiguration="via" address="net.tcp://127.0.0.1:8031/Calculator" binding="netTcpBinding" contract="Jillzhang.Wcf.HostJIT.Contracts.ICalculator" name="Calculator"></endpoint>
      <endpoint behaviorConfiguration="via" address="net.tcp://127.0.0.1:8032/Activity" binding="netTcpBinding" contract="Jillzhang.Wcf.HostJIT.Contracts.IActivity" name="Activity"></endpoint>
      </client>
      <behaviors>
      <endpointBehaviors>
      <behavior name="via">
      <clientVia viaUri="net.tcp://127.0.0.1:8030/"/>
      </behavior>
      </endpointBehaviors>
      </behaviors>
      </system.serviceModel>
      </configuration>

      Programe.cs為:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.ServiceModel;
      using Jillzhang.Wcf.HostJIT.Contracts;
      namespace Jillzhang.Wcf.HostJIT.Client
      {
      class Program
      {
      static void Main(string[] args)
      {
      Console.WriteLine("press any key when dispatcher service is ok!");
      Console.Read();
      CallCalculator();
      CallActivity();
      CallCalculator();
      CallActivity();
      Console.ReadKey(true);
      }
      static void CallCalculator()
      {
      using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>("Calculator"))
      {
      var channel = channelFactory.CreateChannel();
      using (channel as IDisposable)
      {
      Console.WriteLine(channel.Add(1, 2).ToString());
      }
      }
      }
      static void CallActivity()
      {
      using (ChannelFactory<IActivity> channelFactory2 = new ChannelFactory<IActivity>("Activity"))
      {
      var channel = channelFactory2.CreateChannel();
      using (channel as IDisposable)
      {
      channel.Excute();
      }
      }
      }
      }
      }
      好了,在解決方案中設置多啟動項目,啟動Jillzhang.Wcf.HostJIT.Client和Jillzhang.Wcf.HostJIT.Dispatcher,f5,然后按照提示進行輸入
      會得到下面的效果:
      客戶端:
      image 
      服務端:
      image 
      最終驗證效果和原來想象中一致。OK!
      demo項目:https://files.cnblogs.com/jillzhang/Jillzhang.Wcf.HostJIT.rar
      posted @ 2008-10-27 02:05  Robin Zhang  閱讀(3632)  評論(10)    收藏  舉報
      主站蜘蛛池模板: 亚洲啪啪精品一区二区的| 精品久久久bbbb人妻| 夜夜添狠狠添高潮出水| 国产精品一线天粉嫩av| 久久国产成人午夜av影院| 漂亮人妻被强中文字幕久久| 天美麻花果冻视频大全英文版| 亚洲色最新高清AV网站| japanese丰满奶水| 狠狠躁夜夜人人爽天96| 国产一区二区三区内射高清| 女同另类激情在线三区| 国产热の有码热の无码视频| 久久亚洲精品成人av无| 少妇人妻综合久久中文字幕| 精品尤物国产尤物在线看| 91中文字幕在线一区| 无码人妻斩一区二区三区| 国产精品视频白浆免费视频| 男人狂桶女人高潮嗷嗷| 92国产精品午夜福利| 国产在线观看免费观看不卡| 久久久久四虎精品免费入口| 佳木斯市| 中文字幕久区久久中文字幕| 极品粉嫩小泬无遮挡20p| 精品午夜福利短视频一区| 文中字幕一区二区三区视频播放| 国产成人精品一区二区三区| 祥云县| 日本熟妇乱一区二区三区| bt天堂新版中文在线| 精品少妇av蜜臀av| 国产无遮挡又黄又爽不要vip软件| 国产精品久久久久9999| 91精品91久久久久久| 亚洲成aⅴ人片久青草影院| 加勒比无码人妻东京热| 国产成人午夜福利在线小电影| 麻豆精品一区二正一三区| 欧美精品国产综合久久|