我是NServiceBus的新手,在我们的一个项目中,我们希望完成以下任务 -
现在是第2点,我没有太多线索,如何完成它。
我已经引用了以下帖子,之后我能够在代理队列中输入消息,但无法在我们的项目中与NServiceBus集成,因为NServiceBus库是旧版本,并且不推荐使用许多方法。因此,将它们与当前版本一起使用会变得非常麻烦,或者如果我以不正当的方式使用它们。
http://www.nullreference.se/2010/12/06/using-nservicebus-and-servicebroker-net-part-2 https://github.com/jdaigle/servicebroker.net
任何有关正确方法的帮助都是非常宝贵的。
感谢。
答案 0 :(得分:2)
我正在使用当前版本的nServiceBus(5),VS2013和SQL Server 2008.我使用this tutorial创建了一个数据库更改侦听器,它使用SQL Server对象代理和SQLDependency来监视对特定的更改表。 (注意:在SQL Server的更高版本中可能会弃用此选项。)
SQL依赖关系允许您使用所有基本SQL功能的广泛选择,尽管您需要了解some restrictions。我稍微修改了教程中的代码,以提供更好的错误信息:
void NotifyOnChange(object sender, SqlNotificationEventArgs e)
{
// Check for any errors
if (@"Subscribe|Unknown".Contains(e.Type.ToString())) { throw _DisplayErrorDetails(e); }
var dependency = sender as SqlDependency;
if (dependency != null) dependency.OnChange -= NotifyOnChange;
if (OnChange != null) { OnChange(); }
}
private Exception _DisplayErrorDetails(SqlNotificationEventArgs e)
{
var message = "useful error info";
var messageInner = string.Format("Type:{0}, Source:{1}, Info:{2}", e.Type.ToString(), e.Source.ToString(), e.Info.ToString());
if (@"Subscribe".Contains(e.Type.ToString()) && @"Invalid".Contains(e.Info.ToString()))
messageInner += "\r\n\nThe subscriber says that the statement is invalid - check your SQL statement conforms to specified requirements (http://stackoverflow.com/questions/7588572/what-are-the-limitations-of-sqldependency/7588660#7588660).\n\n";
return new Exception(messageMain, new Exception(messageInner));
}
我还创建了一个带有“数据库优先”实体框架数据模型的项目,以便我可以对已更改的数据执行某些操作。
[我的nServiceBus项目的相关部分]包含两个“Run as Host”端点,其中一个端点发布事件消息。第二个端点处理消息。发布者已经设置为IWantToRunAtStartup,它实例化DBListener并将它想要作为我的更改监视器运行的SQL语句传递给它。 onChange()函数传递一个匿名函数来读取已更改的数据并发布消息:
using statements
namespace Sample4.TestItemRequest
{
public partial class MyExampleSender : IWantToRunWhenBusStartsAndStops
{
private string NOTIFY_SQL = @"SELECT [id] FROM [dbo].[Test] WITH(NOLOCK) WHERE ISNULL([Status], 'N') = 'N'";
public void Start() { _StartListening(); }
public void Stop() { throw new NotImplementedException(); }
private void _StartListening()
{
var db = new Models.TestEntities();
// Instantiate a new DBListener with the specified connection string
var changeListener = new DatabaseChangeListener(ConfigurationManager.ConnectionStrings["TestConnection"].ConnectionString);
// Assign the code within the braces to the DBListener's onChange event
changeListener.OnChange += () =>
{
/* START OF EVENT HANDLING CODE */
//This uses LINQ against the EF data model to get the changed records
IEnumerable<Models.TestItems> _NewTestItems = DataAccessLibrary.GetInitialDataSet(db);
while (_NewTestItems.Count() > 0)
{
foreach (var qq in _NewTestItems)
{
// Do some processing, if required
var newTestItem = new NewTestStarted() { ... set properties from qq object ... };
Bus.Publish(newTestItem);
}
// Because there might be a number of new rows added, I grab them in small batches until finished.
// Probably better to use RX to do this, but this will do for proof of concept
_NewTestItems = DataAccessLibrary.GetNextDataChunk(db);
}
changeListener.Start(string.Format(NOTIFY_SQL));
/* END OF EVENT HANDLING CODE */
};
// Now everything has been set up.... start it running.
changeListener.Start(string.Format(NOTIFY_SQL));
}
}
}
重要 OnChange事件触发会导致侦听器停止监听。它基本上是一个单一的事件通知器。处理完事件后,最后要做的就是重启DBListener。 (您可以在END OF EVENT HANDLING评论之前的行中看到这一点。)
您需要添加对System.Data和System.Data.DataSetExtensions的引用。
目前这个项目仍然是概念证明,所以我很清楚上面的内容可以有所改善。另外请记住,我必须删除公司特定的代码,因此可能存在错误。将其视为模板,而不是工作示例。
我也不知道这是否是放置代码的正确位置 - 这也是我今天使用StackOverflow的部分原因;寻找更好的ServiceBus主机代码示例。无论我的代码有什么缺陷,解决方案都能非常有效地工作 - 到目前为止 - 并且也符合您的目标。
不要过于担心ServiceBroker方面的问题。一旦你完成了设置,根据教程,SQLDependency会为你处理细节。
答案 1 :(得分:0)
ServiceBroker Transport非常陈旧,不再支持,据我记忆所及。 一个可能的解决方案是&#34;监控&#34;使用类似SqlDependency(http://msdn.microsoft.com/en-us/library/62xk7953(v=vs.110).aspx)之类的端点代码中的有趣表格,然后将消息推送到相关队列中。
的.m