• 検索結果がありません。

第19回 エンバカデロ・デベロッパーキャンプ

N/A
N/A
Protected

Academic year: 2021

シェア "第19回 エンバカデロ・デベロッパーキャンプ"

Copied!
29
0
0

読み込み中.... (全文を見る)

全文

(1)

17

Th

Developer Camp

「C++BuilderによるWebサービス

&マルチスレッド対応リソースプー

ルの設計」

エンバカデロ・テクノロジーズ

エヴァンジェリスト

高橋智宏

【T4】 C++Builderテクニカルセッション

(2)

アジェンダ

Webサービス(CGI版)

BASIC認証(IIS)

SOAPクライアント

WSDLインポータ, BASIC認証対応

Webサービス(スタンドアロン版)

独自のBASIC認証を実装

リソースプール

データモジュール(データベース接続)

Win32 API

POSIXスレッド

Boost::Thread

(3)

17

Th

Developer Camp

Webサービスの構築

(4)

CGI版のWebサービス

[C++Builderプロジェクト]-[Webサービス]-[SOAPサー

バーアプリケーション]

CGI

実行形式

[C++Builderプロジェクト]-[Webサービス]-[SOAPサー

バーインターフェイス]

サービス名:

MyService

サンプルメソッドの生成:

On

注意点1: プロジェクトソース(例:Project1.cpp)が少し壊れることがある

注意点2:サンプルのTSampleStructクラスのメンバがAnsiString型

(5)

5

Webサービスメソッドの実装のポイント

echoStructメソッドの実装

TRemotableの派生

クラス

を処理する

クラスのインスタンスのconstポインタを受け取り

クラスのインスタンスのポインタを返す

• returnしたインスタンスは後でdeleteされる

• NULLを返すのも一応OK

• 例外はすべて捕捉して伝播させない(SOAPの例外機構は貧弱なので)

TSampleStruct* TMyServiceImpl::echoStruct(const TSampleStruct* pEmployee) {

TSampleStruct* retval = NULL; try {

retval = new TSampleStruct();

retval->LastName = pEmployee->LastName; retval->FirstName = pEmployee->FirstName; retval->Salary = pEmployee->Salary; } catch (...) { ; // do something } return retval;

(6)

IISにCGIを配布 - BASIC認証

CGIを利用できるように設定

ハンドラマッピング, CGIの制限 etc…

WebサイトでBASIC認証を有効にする

基本

認証(HTTP 401チャレンジ):

有効

• 既定のドメイン:

• 領域(Realm,レルム): 例として test を設定

匿名

認証:

無効

WSDLを確認

Webブラウザ

(7)

17

Th

Developer Camp

SOAPクライアントの構築

(8)

WSDLインポータ

C++アプリケーションプロジェクトの作成

[C++Builderプロジェクト]-[Webサービス]-[WSDLインポ

ータ]

WSDLソース

認証: ユーザー名

認証: パスワード

自動生成されるファイル

IMyService.h

IMyService.cpp

プロキシの取得

GetIMyService関数

(9)

クライアント側でのBASIC認証への対応

THTTPRIOクラスのHTTPWebNodeプロパティを使用

UserNameプロパティ

Passwordプロパティ

注意: C++Builder XE(Delphi XE)では、必要なら、認証ダイアログを自

前で用意して表示させる必要がある

以前のバージョンでは、自動で表示されてしまっていたので要注意

(10)

クライアントコードの実装のポイント - その1

プロキシの取得は

1回

だけ

メモリリークあり: QC#91160

THTTPRIOクラスのインスタンスは自前で用意

• BASIC認証のユーザー名・パスワードを設定

• deleteは不要

(11)

クライアントコードの実装のポイント - その2

Webサービスメソッドの呼び出しは常に失敗する可能性がある

try …

catch

を忘れずに!!

Webサービスメソッドの戻り値のNULLチェック

パラメータと戻り値のそれぞれのインスタンスをdelete

try …

__finally

を忘れずに!!

(12)

17

Th

Developer Camp

スタンドアロン版

Webサービスサーバー

(13)

スタンドアロン版のWebサービス

[C++Builderプロジェクト]-[Webサービス]-[SOAPサー

バーアプリケーション]

Indy VCL(

or

コンソール) アプリケーション

を選択

[C++Builderプロジェクト]-[Webサービス]-[SOAPサー

バーインターフェイス]

サービス名: MyService

サンプルメソッドの生成: On

注意点1: プロジェクトソース(例:Project1.cpp)が少し壊れることがある

注意点2:サンプルのTSampleStructクラスのメンバがAnsiString型

(14)

サービスアクティベーションモデル

単一プロセスのWebサーバーなので、クラスインスタンスのライフ

サイクルに注意が必要

グローバル:単一インスタンスですべて処理(スレッドセーフ必須)

(15)

スタンドアロン版 - BASIC認証

メインフォームで使用されているIndyクラスがポイント

TIdHTTPWebBrokerBridge

• DoCommandGet, DoCommandOther がHTTPリクエスト

を処理している

TIdHTTPWebBrokerBridgeの派生クラスに取り替える

DoCommandGet, DoCommandOtherをオーバーライド

BASIC認証を実装

メインフォームのOnCreateイベントで new する

void __fastcall TForm1::FormCreate(TObject *Sender)

{

//FServer = new TIdHTTPWebBrokerBridge(this);

FServer = new TIdHTTPWebBrokerBridge

Ex

(this);

}

(16)

スタンドアロン版 - BASIC認証(続き)

TIdHTTPWebBrokerBridgeExクラスの実装

#include <IdContext.hpp>

#include <IdCustomHTTPServer.hpp>

class TIdHTTPWebBrokerBridgeEx : public TIdHTTPWebBrokerBridge { public:

__fastcall TIdHTTPWebBrokerBridgeEx(TComponent* AOwner) : TIdHTTPWebBrokerBridge(AOwner){}

__fastcall virtual ~TIdHTTPWebBrokerBridgeEx(){} protected:

void __fastcall DoCommandGet(TIdContext* AThread,

TIdHTTPRequestInfo* ARequestInfo, TIdHTTPResponseInfo* AResponseInfo) { if( ARequestInfo->AuthExists &&

ARequestInfo->AuthUsername == "ken" &&

ARequestInfo->AuthPassword == "password" ) {

TIdHTTPWebBrokerBridge::DoCommandGet(AThread, ARequestInfo, AResponseInfo);

return; }

AResponseInfo->ResponseNo = 401;

AResponseInfo->ContentText = "auth error"; AResponseInfo->AuthRealm = "test";

}

void __fastcall DoCommandOther(TIdContext* AThread,

TIdHTTPRequestInfo* ARequestInfo, TIdHTTPResponseInfo* AResponseInfo) { DoCommandGet(AThread, ARequestInfo, AResponseInfo);

(17)

17

Th

Developer Camp

マルチスレッドへの対応

リソースプールの設計

(18)

有限個のリソースで対応する

CGIはパフォーマンスの点では劣る

スタンドアロン版

サービスアクティベーションモデルに関係なく、コネクションプール(or

データモジュールのプール)が必要

Webサービスメソッド内では…

1. プールからリソースを借りて

2. リソースを利用して

3. プールにリソースを返す

クライアント

Webサーバ

RDBMS

リクエスト レスポンス クエリー実行接続 切断 クラス インスタンスクラス インスタンスクラス インスタンスクラス インスタンス

(19)

スレッドセーフなプール - Win32 API版

CriticalSectionに関するAPI

リソースの排他制御(ロック)に使用

• InitializeCriticalSection(Ex)

• EnterCriticalSection

• LeaveCriticalSection

• DeleteCriticalSection

ConditionVariableに関するAPI

ビジーループや無駄なポーリングを回避するため

ただし、

Vista

/

Windows 7

/

Windows 2008 でのみ利用可

• InitializeConditionVariable

• SleepConditionVariableCS

• WakeAllConditionVariable

(20)

テストコード - 複数スレッドの起動

(21)

テストコード - リソースプールへのアクセス

(22)

スレッドセーフなプール - POSIXスレッド版

OSに依存しないPOSIXスレッドを利用

Open Source POSIX Threads for

Win32

• http://sourceware.org/pthreads-win32/

デベロッパーキャンプで紹介済みです

[gSOAP, Pthreads-Win32, OpenSSLを使ったSOAS C/Sアプリ開発]

• http://edn.embarcadero.com/article/images/33870/devcamp03_a

1.pdf

排他制御(ロック)に使用する関数

pthread_mutex_init, pthread_mutex_destroy

pthread_mutex_lock, pthread_mutex_unlock

条件による待機に使用する関数

pthread_cond_init, pthread_cond_destroy

pthread_cond_timewait, pthread_cond_broadcast

(23)

テストコード - 複数スレッドの起動

(24)
(25)

スレッドセーフなプール - Boost::Thread版

OSに依存しないスレッドライブラリ

C++Builder XE には、Boost 1.39 が付属

Boost::ThreadライブラリのDLLが必要

• リリース用: boost_thread-bcb-mt-1_39.dll

• デバッグ用: boost_thread-bcb-mt-d-1_39.dll

排他制御(ロック)のコードがキレイ

boost::unique_lockオブジェクトのスコープ

• Lockableには、boost::recursive_mutex を使用

Lockable, Condition Variable の初期化コードが不要

boost::condition_variable_anyクラス

• timed_waitメソッド

• notify_allメソッド

(26)

テストコード - 複数スレッドの起動

(27)
(28)

17

Th

Developer Camp

デモ

リソースプールの動作検証

(29)

17

Th

Developer Camp

参照

関連したドキュメント

今回の調壺では、香川、岡山、広島において、東京ではあまり許容されない名詞に接続する低接

フィールド試験で必要な機能を 1 台に集約 世界最小クラス 10GbE テスタ (AQ1300). AQ1301 10M

放射性廃棄物処理配管における接続調査結果 8福島第二原子力発電所1号機 原子炉建屋

[r]

接続対象計画差対応補給電力量は,30分ごとの接続対象電力量がその 30分における接続対象計画電力量を上回る場合に,30分ごとに,次の式

Ⅲ料金 19接続送電サービス (3)接続送電サービス料金 イ低圧で供給する場合 (イ) 電灯定額接続送電サービス d接続送電サービス料金

接続対象計画差対応補給電力量は,30分ごとの接続対象電力量がその 30分における接続対象計画電力量を上回る場合に,30分ごとに,次の式

笹川記念保健協力財団は、1974 年5月、日本財団創始者笹川良一氏と、日