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();
}
}
}
}
}
 
 
 
 
 
服务端:
 
最终验证效果和原来想象中一致。OK!
demo项目:http://files.cnblogs.com/jillzhang/Jillzhang.Wcf.HostJIT.rar

转载于:https://www.cnblogs.com/jillzhang/archive/2008/10/27/1320086.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值