IDeliveryProtocol Interface
カスタム配信プロトコルを開発するためのフレームワークです。作成されたプロトコルは、1 つ以上の配信チャネルが使用できます。配信プロトコルは、通知メッセージを生成し、外部配信システムに送信するときに使用します。
名前空間: Microsoft.SqlServer.NotificationServices
アセンブリ: Microsoft.SqlServer.NotificationServices (microsoft.sqlserver.notificationservices.dll 内)
構文
'宣言
Public Interface IDeliveryProtocol
public interface IDeliveryProtocol
public interface class IDeliveryProtocol
public interface IDeliveryProtocol
public interface IDeliveryProtocol
解説
このインターフェイスは、カスタム配信プロトコルを開発するためのフレームワークです。カスタム配信プロトコルを作成するには、このインターフェイスを実装するクラスを作成してから、アプリケーションに適切なインターフェイスのメソッドを実装する必要があります。
IDeliveryProtocol インターフェイスには、次のメソッドが用意されています。
Initialize: 実行前にディストリビュータによって配信プロトコルを初期化します。
DeliverNotification: ディストリビュータによって、フォーマット済み通知データが配信プロトコルに渡され、その後、配信プロトコルが通知メッセージを作成して、それを外部の配信システムにルーティングできるようにします。このメソッドは、作成および配信が必要な通知メッセージごとに 1 回、呼び出されます。
Flush: ディストリビュータから、保留中の配信の処理を完了するよう配信プロトコルに要求できます。
Close: 使用中のリソースを解放し、シャットダウンするよう、ディストリビュータから配信プロトコルに指示します。
呼び出しのシーケンスは、Initialize で始まり、送信されるメッセージごとに一連の DeliverNotification が呼び出されます。Flush は、DeliverNotification を呼び出す前または後に呼び出すことができます (ただし、DeliverNotification の呼び出しと並行して呼び出すことはできません)。Close は、このシーケンスで呼び出される最後のメソッドです。Close が完了した後、新しい Initialize を使用して一連のメソッド呼び出しをやり直さない限り、DeliverNotification と Flush が再度呼び出されることはありません。
1 つの配信プロトコル インスタンスに対するメソッドは、1 つのスレッドから呼び出されるため、インスタンス データへのアクセスをスレッドセーフにする必要はありません。複数のプロトコル インスタンスの場合、複数のスレッド上で呼び出される可能性があるため、共有クラス全体のデータはスレッドセーフでなければなりません。
メモ : |
---|
ディストリビュータでは、IDeliveryProtocol メソッドでのタイムアウトは強制されません。配信プロトコルのクラスは、信頼関係のある、テスト済みのコードであると見なされます。いずれかのメソッドが応答を停止した場合、そのメソッドを呼び出したディストリビュータ スレッドも応答を停止します。この状態が多数のスレッドで発生した場合、ディストリビュータの処理が中止される可能性があります。 |
メモ : |
---|
カスタム開発されることが多い HTTP ベースの配信プロトコルは、IHttpProtocolProvider インターフェイスを使用すると迅速に開発できます。IDeliveryProtocol インターフェイスは、他のプロトコルを実装するカスタム配信プロトコル、または IHttpProtocolProvider インターフェイスで開発されたものよりも柔軟な HTTP ベースの配信プロトコルを開発するときに使用します。 |
詳細については、「カスタム配信プロトコルの開発」を参照してください。
使用例
次の例では、新しいカスタム配信プロトコルを作成する場合のインターフェイス宣言の使用方法、ストアド プロシージャを使用して通知データを処理する配信プロトコルのサンプル、およびカスタム配信プロトコルを宣言し、使用するためのアプリケーション定義ファイル (ADF) とインスタンス構成ファイル (ICF) コードのサンプルについて説明します。
カスタム配信プロトコルを作成するには、次のインターフェイス宣言を使用します。
public interface IDeliveryProtocol
{
void Initialize(
StringDictionary channelArgs,
Boolean multicast,
NotificationStatusCallback nsc);
void DeliverNotification(
NotificationHeaders[] headersList,
String body);
void Flush();
void Close();
}
次のコード例では、配信チャネルにより Microsoft SQL Server データベースのストアド プロシージャに通知が送信されています。
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Text;
using Microsoft.SqlServer.NotificationServices;
namespace AdventureWorks.Notifications.MyDeliveryProtocol
{
// Create a class for the delivery protocol
public class StoredProcProtocol : IDeliveryProtocol
{
private bool multicast = false;
private NotificationStatusCallback
notificationStatusCallback = null;
private string server = null;
private string database = null;
private string storedProc = null;
private string appName = null;
private int commandTimeout = 0;
private string connectionString = null;
public StoredProcProtocol()
{
// Add constructor logic here if required.
}
// Implement the IDeliveryProtocol.Initialize method.
public void Initialize(
StringDictionary channelArgs,
bool multicast,
NotificationStatusCallback notificationStatusCallback )
{
this.multicast = multicast;
this.notificationStatusCallback =
notificationStatusCallback;
// This delivery protocol requires five arguments:
// The Database Engine instance to connect to.
// The database to use.
// The stored procedure to receive notifications.
// The name of the application making the connection.
// The time-out period for the command.
if (5 == channelArgs.Count)
{
this.server = channelArgs["Server"];
this.database = channelArgs["Database"];
this.storedProc = channelArgs["storedProc"];
this.appName = channelArgs["AppName"];
this.commandTimeout = int.Parse(
channelArgs["CommandTimeout"]);
}
else
{
throw new ArgumentException(
"Inadequate number of arguments supplied.");
}
// Validate the values of the arguments here if needed.
// Build the connection string.
StringBuilder connectBuilder = new StringBuilder();
connectBuilder.AppendFormat("Data Source={0};", server);
connectBuilder.AppendFormat(
"Initial Catalog={0};", database);
connectBuilder.AppendFormat("Integrated Security=true;");
connectBuilder.AppendFormat("App={0}", appName);
connectionString = connectBuilder.ToString();
}
// Implement the IDeliveryProtocol.DeliverNotification method.
public void DeliverNotification(
NotificationHeaders[] notificationHeaders,
string body)
{
bool successfulDelivery = false;
Exception failureException = null;
try
{
// Get a connection to SQL Server.
using (SqlConnection databaseConnection =
new SqlConnection(connectionString))
{
// Prepare the SqlCommand object.
SqlCommand databaseCommand =
databaseConnection.CreateCommand();
databaseCommand.CommandTimeout = commandTimeout;
databaseCommand.CommandType =
CommandType.StoredProcedure;
databaseCommand.CommandText = storedProc;
// Call the stored procedure for each recipient.
foreach(NotificationHeaders header
in notificationHeaders)
{
// Reset the parameters.
databaseCommand.Parameters.Clear();
// Set the procedure parameters.
if (null != header.ProtocolFields)
{
foreach (string protocolField in
header.ProtocolFields.Keys)
{
databaseCommand.Parameters.AddWithValue(
String.Format("@" + protocolField),
header.ProtocolFields[protocolField]);
}
}
// Execute the command.
databaseConnection.Open();
databaseCommand.ExecuteNonQuery();
databaseCommand.Connection.Close();
successfulDelivery = true;
}
}
}
catch (Exception ex)
{
failureException = ex;
// Handle any exceptions here; for instance,
// write exception information to the event log.
}
finally
{
SendStatus(notificationHeaders, successfulDelivery,
body, failureException);
}
}
// Build a statusInfo message, create a NotificationStatus
// object, and call the notificationStatusCallback delegate.
private void SendStatus(
NotificationHeaders[] notificationHeaders,
bool successfulDelivery,
string body,
Exception failureException)
{
if (null != notificationStatusCallback)
{
ArrayList statusList = new ArrayList(
notificationHeaders.Length);
string statusInfo;
// Set some notification status parameters
// based on delivery success or failure.
string notificationText;
if (null == failureException)
{
statusInfo = "";
notificationText = "";
}
else
{
statusInfo = failureException.Message;
notificationText = body;
}
object timeStamp = DateTime.UtcNow;
// Create a NotificationStatus object for
// each notification and add it to an array.
for (int i = 0; i < notificationHeaders.Length; i++)
{
NotificationHeaders notificationHeader =
notificationHeaders[i];
statusList.Add(new NotificationStatus(
notificationHeader.NotificationState,
successfulDelivery, statusInfo,
notificationText, timeStamp));
}
// Pass the array of NotificationStatus objects
// to the NotificationStatusCallback delegate.
notificationStatusCallback(
(NotificationStatus[])statusList.ToArray(
typeof(NotificationStatus)));
}
}
// Implement the IDeliveryProtocol.Flush method.
public void Flush()
{
// Notification delivery by this protocol is synchronous
// and completes in the DeliverNotification call. There
// is nothing for Flush to do.
}
// Implement the IDeliveryProtocol.Close method.
public void Close()
{
// No resources are held beyond the sychronous call
// to DeliverNotification. There are no resources for
// Close to release.
}
}
}
このカスタム配信プロトコルを使用して問題が生じた場合には、Windows イベント ビューアを使用して配信障害情報を表示します。さらに、SQL Server Profiler を使用して、カスタム配信プロトコルによって SQL Server に送信されたコマンド テキストを表示します。
また、カスタム配信プロトコル用のアプリケーションおよびインスタンスのプロパティを定義する必要があります。インスタンス構成ファイル (ICF) にこのカスタム配信プロトコルを定義する一例を次に示します。
<Protocols>
<Protocol>
<ProtocolName>MyStoredProcProtocol</ProtocolName>
<ClassName>AdventureWorks.Notifications.MyDeliveryProtocol.StoredProcProtocol</ClassName>
<AssemblyName>%BaseDirectoryPath%\MyDeliveryProtocol.dll</AssemblyName>
</Protocol>
</Protocols>
このカスタム プロトコルの配信チャネルを ICF に定義する方法は次のとおりです。
<DeliveryChannel>
<DeliveryChannelName>StoredProcChannel</DeliveryChannelName>
<ProtocolName>MyStoredProcProtocol</ProtocolName>
<Arguments>
<Argument>
<Name>Server</Name>
<Value>%SqlServer%</Value>
</Argument>
<Argument>
<Name>Database</Name>
<Value>MyTestDB</Value>
</Argument>
<Argument>
<Name>storedProc</Name>
<Value>dbo.MyFlightSP</Value>
</Argument>
<Argument>
<Name>AppName</Name>
<Value>Flight</Value>
</Argument>
<Argument>
<Name>CommandTimeout</Name>
<Value>30</Value>
</Argument>
</Arguments>
</DeliveryChannel>
このカスタム配信プロトコルの通知クラス プロトコル フィールドを定義する方法は次のとおりです。
<Protocol>
<ProtocolName>MyStoredProcProtocol</ProtocolName>
<Fields>
<Field>
<FieldName>LeavingFrom</FieldName>
<FieldReference>LeavingFrom</FieldReference>
</Field>
<Field>
<FieldName>GoingTo</FieldName>
<FieldReference>GoingTo</FieldReference>
</Field>
<Field>
<FieldName>Carrier</FieldName>
<FieldReference>Carrier</FieldReference>
</Field>
<Field>
<FieldName>Price</FieldName>
<FieldReference>Price</FieldReference>
</Field>
<Field>
<FieldName>Conditions</FieldName>
<FieldReference>Conditions</FieldReference>
</Field>
</Fields>
</Protocol>
プラットフォーム
開発プラットフォーム
サポートされているプラットフォームの一覧については、「SQL Server 2005 のインストールに必要なハードウェアおよびソフトウェア」を参照してください。
対象プラットフォーム
サポートされているプラットフォームの一覧については、「SQL Server 2005 のインストールに必要なハードウェアおよびソフトウェア」を参照してください。
参照
関連項目
IDeliveryProtocol Members
Microsoft.SqlServer.NotificationServices Namespace