创建类库工程RequestResponse.Messages:
namespace RequestResponse.Messages
{
public class MyMessage
{
public string Text { get; set; }
}
}
创建类库工程RequestResponse.Server:
using System;
using log4net;
using log4net.Config;
using Shuttle.Core.Host;
using Shuttle.Core.Infrastructure;
using Shuttle.Core.Infrastructure.Log4Net;
using Shuttle.ESB.Core;
using Shuttle.ESB.Modules.ActiveTimeRange;
namespace RequestResponse.Server
{
public class ServiceBusHost : IHost, IDisposable
{
private static IServiceBus bus;
public void Start()
{
Log.Assign(new Log4NetLog(LogManager.GetLogger(typeof(ServiceBusHost))));
bus = ServiceBus.Create().Start();
Console.WriteLine("#########server-end bus instance has started");
}
public void Dispose()
{
bus.Dispose();
LogManager.Shutdown();
}
}
}
using System;
using System.Text;
using RequestResponse.Messages;
using Shuttle.Core.Infrastructure;
using Shuttle.ESB.Core;
namespace RequestResponse.Server
{
public class ServerMessageHandler : IMessageHandler<MyMessage>
{
private int received;
public void ProcessMessage(HandlerContext<MyMessage> context)
{
//服务器端接受到消息
Console.WriteLine("【SERVER-END RECEIVE A MSG,Content:"+ context.Message.Text+ "】");
//服务器端发送回应消息
context.Bus.SendReply(new MyMessage
{
Text = "I have recwived your msg"
});
}
public bool IsReusable
{
get { return true; }
}
}
}
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="serviceBus" type="Shuttle.ESB.Core.ServiceBusSection, Shuttle.ESB.Core"/>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<serviceBus>
<control workQueueUri="msmq://./requestresponse-server-control-inbox-work" errorQueueUri="msmq://./shuttle-samples-error" durationToSleepWhenIdle="250ms*25,500ms*10,1s" threadCount="1"/>
<inbox workQueueUri="msmq://./requestresponse-server-inbox-work" errorQueueUri="msmq://./shuttle-samples-error" durationToSleepWhenIdle="250ms,1s" durationToIgnoreOnFailure="1s" threadCount="1"/>
</serviceBus>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p %c - %m%n"/>
</layout>
</appender>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="logs\request-response-server"/>
<appendToFile value="true"/>
<rollingStyle value="Date"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="100000KB"/>
<datePattern value="-yyyyMMdd.'log'"/>
<param name="StaticLogFileName" value="false"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p %c - %m%n"/>
</layout>
</appender>
<root>
<level value="TRACE"/>
<appender-ref ref="ConsoleAppender"/>
<appender-ref ref="RollingFileAppender"/>
</root>
</log4net>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
创建控制台应用程序RequestResponse.Client:
using System;
using log4net;
using RequestResponse.Messages;
using Shuttle.Core.Infrastructure;
using Shuttle.Core.Infrastructure.Log4Net;
using Shuttle.ESB.Core;
namespace RequestResponse.Client
{
internal class Program
{
private static void Main()
{
Log.Assign(new Log4NetLog(LogManager.GetLogger(typeof(Program))));
var bus = ServiceBus.Create().Start();
Console.WriteLine("###### Client bus started. Press CTRL+C to stop.");
Console.WriteLine();
Console.WriteLine("@Press enter to send a message to the server.");
Console.WriteLine();
while (true)
{
Console.ReadLine();
//将消息发送出去
bus.Send(new MyMessage{Text = "Client Massage"});
}
}
}
}
using System;
using RequestResponse.Messages;
using Shuttle.Core.Infrastructure;
using Shuttle.ESB.Core;
namespace RequestResponse.Client
{
public class ClientMessageHandler : IMessageHandler<MyMessage>
{
public void ProcessMessage(HandlerContext<MyMessage> context)
{
//客户端接收到消息
Console.WriteLine("【Client-END RECEIVE A MSG, Content:"+ context.Message.Text +"】");
}
public bool IsReusable
{
get { return true; }
}
}
}
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="serviceBus" type="Shuttle.ESB.Core.ServiceBusSection, Shuttle.ESB.Core"/>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<serviceBus>
<messageRoutes>
<messageRoute uri="msmq://./requestresponse-server-inbox-work">
<add specification="StartsWith" value="RequestResponse"/>
</messageRoute>
</messageRoutes>
<inbox workQueueUri="msmq://./requestresponse-client-inbox-work" journalQueueUri="msmq://./requestresponse-client-inbox-journal" errorQueueUri="msmq://./shuttle-samples-error"/>
<outbox workQueueUri="msmq://./requestresponse-client-outbox-work" errorQueueUri="msmq://./shuttle-samples-error"/>
</serviceBus>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p %c - %m%n"/>
</layout>
</appender>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="logs\request-response-server"/>
<appendToFile value="true"/>
<rollingStyle value="Date"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="100000KB"/>
<datePattern value="-yyyyMMdd.'log'"/>
<param name="StaticLogFileName" value="false"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p %c - %m%n"/>
</layout>
</appender>
<root>
<level value="TRACE"/>
<appender-ref ref="ConsoleAppender"/>
<appender-ref ref="RollingFileAppender"/>
</root>
</log4net>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
一切就绪。
然后设置解决方案的启动顺序,将server放在client前面。
然后右击项目RequestResponse.Server,生成,再右击其属性,在启动外部程序中选择host.exe
然后便可以运行这个解决方案了。
三个问题:
1 内部运行原理?
2 适用场景?
If there is one thing that a service bus should never be used for it is querying. A service bus is geared towards instructing systems what to do (command
message); notifying systems of events that have taken place using a publish / subscribe mechanism (event message); and, less frequently,
transferring data (document message).
It is perfectly valid to send a command to a system to perform some calculation. The result could then be stored a result store and a notification sent that the calculation has been completed. This is quite different from sending a request for data.
Autonomous Components
With any system it is advisable to isolate tasks and decouple them. In this way each can be implemented independently and versioned independently. By using a specific endpoint / queue to handle a particular message type you have the ability to send a relevant
message for processing at any time.
For example, in a tightly-coupled system you may have a process that registers a new user. So after gathering the user information from some front-end the information is submitted for processing:
- check if the user is blacklisted
- register the user in the database
- send an activation e-mail
If this is done in a synchronous fashion the user presses thesubmitbutton and waits. Let's assume our mail server has gone down. Now the user cannot register. What's more is that sending e-mail by using our shared smtp server takes a couple
of seconds so during periods of heavy traffic this process takes quite some time.
We could change this process to gather the user information from the front-end and submit it for registration by sending aRegisterUserCommandto our user service. The call returns immediately informing the user that there registration request
has been received and they will be contact with the result via e-mail. Now our process will be as follows (autonomous components indicated byAC):
- User Registration Service (AC) - handlesRegisterUserCommand
- check blacklisting
- if user blacklisted sendSendEMailCommandto then e-mail service (AC) to notify user that the details provided (user name / e-mail address / contact numbers) have been blacklisted.
- if not blacklisted register user in database and sendSendEMailCommandto the e-mail server (AC) and publishesUserRegisteredEvent.
- E-Mail Service (AC) - handlesSendEMailCommand
- sends the requested e-mail via our smtp server; if the server is down the message will simply be retried until it goes through
- CRM User Registration Service (AC) - subscribes toUserRegisteredEvent
- registers the new user in our CRM
In this way each component can be developed, versioned, and deployed in isolation. Stopping any of the services for deployment would not result in any process breaking since the queues will continue receiving work. Even if the entire machine is brought down
Shuttle ESB will still store message on the sending machine when using anoutbox.
3 与MSMQ In WCF的异同?
Web Services / WCF
Some may argue that they use web services and therefore have a service oriented architecture. They would be correct in that they have exposed a service of some sort. There are however many properties of a SOA that are not present when using only web services:
- Noevent driven architecture(EDA)
- WS / WCF cannot subscribe to events
- No durability of messages
- A message goes across the wire and is not stored anywhere
- No recoverability
- Once a message is lost it is gone
- No lowtemporal coupling
- A WS must be running in order to invoke it
- No lowbehavioural coupling
- We have to know what the service will do in order to invoke it
- Nomessage routing
- We send messages to a specific WS to invoke some action
- No queuing
- Calls are synchronous and blocking
These are not necessarily bad but do represent some of the properties of a WS.
This does not mean that web services have no place in a SOA. In fact, there are instances where we definitely need them. For external integration they are fine; serving as an entry point into our systems.
这里是NServiceBus与WCF的对比:http://support.nservicebus.com/customer/portal/articles/861164-nservicebus-and-wcf
(转载请注明出处)
分享到:
相关推荐
MATLAB数字滤波器设计及其在语音信号去噪中的应用:源码详解与报告分享,MATLAB 数字滤波器设计 及其语音信号去噪应用。 (供学习交流)带源码,带注释。 有代码和报告。 ,核心关键词:MATLAB; 数字滤波器设计; 语音信号去噪应用; 源码; 注释; 代码与报告。,"MATLAB数字滤波器设计及其在语音信号去噪中的应用:带源码注释与报告"
COMSOL软件模拟三维电化学腐蚀过程的研究分析,comsol三维电化学腐蚀。 ,核心关键词:Comsol;三维电化学;腐蚀;模型模拟;电化学腐蚀过程。,"Comsol模拟:三维电化学腐蚀过程解析"
基于COMSOL的降雨入渗模型:边坡与渗流边界下的强度折减塑性形变研究,comsol降雨入渗模型,边坡降雨边界与渗流边界 强度折减塑性形变 ,comsol降雨入渗模型; 降雨边界; 渗流边界; 强度折减; 塑性形变,"COMSOL降雨入渗模型:边坡渗流与强度折减塑性形变分析"
2025员工安全意识培训试题及答案.docx
Python自动化办公源码-06在Word表格中将上下行相同内容的单元格自动合并
基于深度学习的神经网络技术在信息通信领域的应用研究.pdf
1.内容概要 通过KNN实现鸢尾花分类,即将新的数据点分配给已知类别中的某一类。该算法的核心思想是通过比较距离来确定最近邻的数据点,然后利用这些邻居的类别信息来决定待分类数据点的类别。 2.KNN算法的伪代码 对未知类别属性的数据集中的每个点依次执行以下操作: (1)计算已知类别数据集中的点与当前点之间的距离; (2)按照距离递增次序排序; (3)选取与当前点距离最小的k个点; (4)确定前k个点所在类别的出现频率; (5)返回前k个点出现频率最高的类别作为当前点的预测分类。 3.数据集说明 代码使用`pandas`库加载了一个名为`iris.arff.csv`的数据集 4.学习到的知识 通过鸢尾花分类学习了KNN算法,选择样本数据集中前k个最相似的数据,就是KNN算法中k的出处。k值过大,会出现分类结果模糊的情况;k值较小,那么预测的标签比较容易受到样本的影响。在实验过程中,不同的k值也会导致分类器的错误率不同。KNN算法精度高、无数据输入的假定,可以免去训练过程。但是对于数据量较多的训练样本,KNN必须保存全部数据集,可能会存在计算的时间复杂度、空间复杂度高的情况,存在维数灾难问
感应电机控制与矢量控制仿真:磁链闭环、转速闭环与电流闭环的综合应用研究,感应电机控制仿真,矢量控制,异步电机仿真,磁链闭环,转速闭环,电流闭环 ,核心关键词:感应电机控制仿真; 矢量控制; 异步电机仿真; 磁链闭环; 转速闭环; 电流闭环,"感应电机矢量控制仿真:磁链、转速、电流三闭环异步电机模拟"
威纶通TK6071IP触摸屏锁屏宏指令程序详解:注释清晰,便于理解与学习,威纶通触摸屏锁屏宏指令程序 ~ 威纶通触摸屏锁屏宏指令程序,TK6071IP触摸屏 利用宏指令程序来控制,宏指令注释清晰,方便理解程序。 具有很好的学习意义和借鉴价值。 ,关键词:威纶通触摸屏;锁屏宏指令程序;TK6071IP触摸屏;宏指令控制;注释清晰;学习借鉴。,威纶通触摸屏宏指令程序:清晰注释,学习借鉴之利器
2025输血相关法律法规试题考核试题及答案.docx
Python游戏编程源码-2048小游戏
2025最新康复医学概论考试题库(含答案).doc
Python自动化办公源码-09用Python批量往Word文档中指定位置添加图片
高品质车载充电器技术解决方案:含原理图、PCB图、C源代码及DSP控制器资料,附赠CDCDC模块资料,车载充电器 3Kw OBC 车载充电器 含原理图、PCB图、C源代码、变压器参数等生产资料。 附赠15kwdcdc模块资料 1、这款产品的方案采用的是dsp2803x系列。 2、原理图和Pcb采用AD绘制。 此方案仅供学习 ,车载充电器; 3Kw OBC; 原理图; PCB图; C源代码; 变压器参数; 生产资料; dsp2803x系列; AD绘制; 15kwdcdc模块资料,3Kw车载充电器方案:DSP2803x系列原理图、PCB图及C源学习包
2025最新康复医学考试题及答案.docx
内容概要:本文介绍了一种用于视频处理的新型卷积神经网络(CNN)加速器。主要创新点在于引入了混合精度计算、跨帧数据重用控制器及引擎,以及混合位宽差帧数据编码解码器。这些特性有效解决了视频帧间的时空相关性和稀疏性带来的挑战,提高了处理速度并降低了功耗和带宽需求。具体来说,通过对连续帧的数据相似度利用,可以在保持高精度的同时减少计算量和内存访问次数;通过多类型稀疏卷积聚类数组实现了对现代稀疏神经网络的支持;并通过混合位宽度编码减少了离芯片外的数据传输量,最高达到68%。 适用人群:从事深度学习硬件加速设计的研究人员和技术爱好者;关注AI边缘计算领域的从业者。 使用场景及目标:适用于自动驾驶汽车摄像头、监控系统等实时视频流应用场景。旨在为开发者提供高效的低能耗解决方案,在有限的时间和资源下完成大量的图像信号处理任务,如跟踪、分类等。 其他说明:文中还详细描述了芯片的设计细节,测试平台构建,以及不同模型(如MobileNet)在网络上的实际性能表现。
COMSOL电化学喷射腐蚀模拟与解析:技术原理及应用实践,comsol电化学喷射腐蚀 ,核心关键词:comsol; 电化学; 喷射腐蚀; 电化学腐蚀。,"电化学喷射腐蚀研究:comsol模拟与解析"
项目已获导师指导并通过的高分毕业设计项目,可作为课程设计和期末大作业,下载即用无需修改,项目完整确保可以运行。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载 技术组成 语言:java 开发环境:idea 数据库:MySql8.0 部署环境:Tomcat(建议用 7.x 或者 8.x 版本),maven 数据库工具:navicat
直流无刷电机调速控制模型:速度环与电流环联合调控,PWM调制精确控制转速,该模型为直流无刷电机的调速控制,外环为速度环,速度输出为电流,内环为电流环,电流环输出为pwm占空比,占空比最终输入至逆变器进行PWM调制。 最后控制电机的转速 ,核心关键词:直流无刷电机; 调速控制; 外环速度环; 速度输出电流; 内环电流环; pwm占空比; 逆变器PWM调制; 控制电机转速。,直流无刷电机调速控制模型:内外环联动,PWM占空比驱动逆变器调速
基于MATLAB的含风光柴储微网多目标优化调度策略与模型实现,含风光柴储微网多目标优化调度 MATLAB代码 关键词:微网调度 风光柴储 粒子群算法 多目标优化 参考文档:《基于多目标粒子群算法的微电网优化调度》 仿真平台:MATLAB 平台采用粒子群实现求解 优势:代码注释详实,适合参考学习,非目前烂大街的版本,程序非常精品,请仔细辨识 主要内容:代码构建了含风机、光伏、柴油发电机以及储能电站在内的微网优化运行模型,并且考虑与上级电网的购电交易,综合考虑了多方经济成本以及风光新能源消纳等多方面的因素,从而实现微网系统的经济运行,求解采用的是MOPSO算法(多目标粒子群算法),求解效果极佳,具体可以看图 ,关键词:微网优化调度; 风光柴储; 粒子群算法; 多目标优化; MATLAB代码; MOPSO算法。,基于MATLAB的微网风光柴储多目标优化调度与MOPSO算法的实践研究