如何使用 WCF SOA 技术和 netTCPBinding、netNamedPipeBinding 和 wsdualHTTPBinding 接收 Oracle 数据库更改通知






4.79/5 (15投票s)
WCF Oracle 数据库更改通知应用程序。
必备组件
- .NET 3.5
- Visual Studio 2008
- ODP.NET 11g 最新客户端
引言
此应用程序展示了如何使用 Oracle 的数据库更改通知技术与 WCF 结合,回调到 WCF 服务,然后 WCF 服务通过 TCP、IPC 和 HTTP 等不同协议回调到多个已注册的客户端,从而刷新网格中的数据。
背景
我尝试在 Google 上搜索一个使用 WCF 技术订阅 Oracle 10g/11g 数据库更改通知技术的示例。但是,我没有找到使用 ODP.NET 的示例,所以这里为你们提供一个。与每隔几分钟/秒或几小时轮询数据库以获取最新可用数据相比,数据库更改通知技术提高了应用程序的性能,提供了可伸缩性等。
Using the Code
WCF 服务详细信息
这里需要注意的重要一点是 Callback Contract 属性,它指定了 WCF 服务应使用该合同回调到客户端,以及两个合同上的 IsOneWay
属性,用于指定异步双向合同。
由于每次数据更改时我们都会回调客户端,因此每次回调都会发送新的数据集。客户端订阅数据,在 Subscribe 调用中不会收到任何数据,但 WCF 服务会立即在提供的回调上回调客户端,提供当前数据状态的数据集。之后,每次数据更改时,WCF 服务都会再次使用新的数据集回调客户端。
[ServiceContract(
Name="WCFQNTableSubscribe",
Namespace="WCFOracleDatabaseChangeNotification",
CallbackContract=typeof(IWCFQNTableCallback),
SessionMode=SessionMode.Required)]
public interface IWCFQNTableSubscribe
{
[OperationContract(IsOneWay=true)]
void Subscribe();
}
/// <summary>
/// The callback contract. The dataset is
/// sent back to client using this contract
/// </summary>
public interface IWCFQNTableCallback
{
[OperationContract(IsOneWay = true)]
void Callback( DataSet data);
}
WCFQNTableSubscription 类
有一个名为 WCFQNTableSubscription
的类,它实现了 subscribe
方法。
Subscribe() 过程
- 此方法使用调用者客户端在服务器端注册。
- 然后,它通过传递客户端的回调信息来实例化一个名为
WCFQNRequestState
的类。 - 最后,它调用该类的
SubmitDataRequest
方法来注册硬编码的查询,以通知 Oracle 数据库发生的任何INSERT
、UPDATE
、DELETE
等更改,然后将这些更改发送回调用客户端,并刷新前端的 datagrid。
public void Subscribe()
{
IWCFQNTableCallback callback =
OperationContext.Current.GetCallbackChannel<IWCFQNTableCallback>();
WCFQNRequestState subscription = new WCFQNRequestState(callback);
subscription.SubmitDataRequest();
}
WCFQNRequestState 类
有一个内部类名为 WCFQNRequestState
,它包含一个接收客户端回调信息的构造函数。
private IWCFQNTableCallback _callback;
public WCFQNRequestState(
IWCFQNTableCallback callback)
{
_callback = callback;
}
该类包含一个名为 SubmitDataRequest()
的过程。
SubmitDataRequest() 过程
- 它连接到 Oracle,并使用 OracleDependency 实例来处理 Oracle 数据库更改通知。
- 它添加了事件处理程序来处理通知。仅当注册的查询的行被更新、插入、删除等时,在数据库发送通知消息时,
OnMyNotification
方法才会被调用。 - 它还从查询中填充结果集到数据集中,并通过客户端回调刷新 datagrid。
public void SubmitDataRequest()
{
string constr = " your connection string for Oracle Database"
string sqlSelect = "select * from sched_generation_process ";
string sql = sqlSelect + "where sched_gen_sid = 3";
string tablename = "sched_generation_process";
DataSet ds = new DataSet();
OracleConnection con = new OracleConnection(constr);
OracleCommand cmd = new OracleCommand(sql, con);
con.Open();
cmd.AddRowid = true;
OracleDependency dep = new OracleDependency(cmd);
cmd.Notification.IsNotifiedOnce = false;
dep.OnChange += new OnChangeEventHandler(dep_OnChange);
OracleDataAdapter da = new OracleDataAdapter(cmd);
da.MissingSchemaAction = MissingSchemaAction.AddWithKey;
da.Fill(ds, tablename);
_callback.Callback( ds);
}
应用程序流程
- 当客户端上的“subscribe 按钮”被按下时(注意:我包含了 TCP、HTTP 和 IPC 的 3 个客户端项目),客户端会调用 WCF 服务的“
Subscribe
”方法。 - WCF 服务上的
subscribe
方法通过存储客户端回调详细信息来注册客户端。 - 然后,它将客户端的回调信息传递给
WCFQNRequestState
类,并调用名为SubmitDataRequest
的方法。 SubmitDataRequest
打开到 Oracle 的连接。- 然后,如果结果发生更改,它会使用命令对象注册通知。当
OracleDependency
实例绑定到OracleCommand
实例时,会创建一个OracleNotificationRequest
,并将其设置为OracleCommand
的Notification
属性。这表明后续命令的执行将注册通知。 - 允许数据库中的更改通知处理程序在第一次数据库更改后仍然有效。
cmd.Notification.IsNotifiedOnce = false;
- 然后它添加了事件处理程序来处理通知。
当数据库发送通知消息时,OnMyNotification
方法将被调用。 - 最后,当前查询结果集作为数据集通过客户端回调方法返回,然后数据集绑定到 datagrid。
- 现在,您可以在 datagrid 中看到结果集。
- 接下来,我将登录
SqlDeveloper
工具,打开 Oracle 数据库模式,然后打开一个表并手动更新一些行。
- 一旦我更新了 1 行或多行,客户端就会立即收到数据库更改通知系统的通知。datagrid 会使用新数据刷新。
- 去玩玩吧,玩得开心。
- 请不要忘记留下评分或评论。
历史记录
- 2009 年 3 月 6 日:首次发布