とりあえずこんな感じでできた。呼ばれるまで接続したまま待つハンドラー。
- staticフィールドでTaskCompletionSourceとGUIDのリストを持つ。
- リクエストがきたらGUIDとTaskCompletionSourceを作ってリストに追加して待機。
- 別のリクエストでGUIDを指定してリストからTaskCompletionSourceをSetResultする。
- 再開されてレスポンスが返る。
とりあえずこんな感じでできた。呼ばれるまで接続したまま待つハンドラー。
CMS(コンテンツマネジメントシステム)の開発をしている。
ASP.NETとSQLServer
MSDNマガジン2008年7月 トランザクション:データを失うことなく障害に対処するスケーラブルなシステムを構築する Udi Dahan
現状はWebアプリケーションとデータベースがべったりくっついていることが前提になっている。管理ページのaspxでトランザクションを実行して同期的に結果を返す。 更新プロセスのプログラミングが窮屈なので開発の機動性、発想の柔軟性を鈍らせる。
ビジネスプロセスの実行主体を独立させる。今後のシステム開発の可能性を広げる。AWSやAzureで提供されるPaaSを段階的に利用していくための準備でもある。
管理ページで受付をした更新要求をWebアプリケーションとは切り離されたプロセスに投入する。結果は投入したプロセスからは受け取らない。 結果は結果を待つプロセスへ通知される。
今のWebアプリケーションから小さく変更を入れていく。管理ページでは結果をロングポーリングで待つ。HTTPの接続は結果の通知を受けるかタイムアウトまで持続する。
ASP.NETで待機するやりかた。 ASP.NETでCometを利用したチャットを実装する:CodeZine(コードジン) HttpContextの参照をStaticで保持して待てばいいことがわかった。
いまからやること
>msbuild @file
<BuildDependOn>
$(BuildDependsOn)
Package
</BuildDependOn>
-source:contentPath=[フォルダのパス] -dest:contentPath=[Webアプリケーションの名前]
Management StudioでリモートのSQLServerを再起動できなかった。
"sa"アカウントで接続してもメニューにある"再起動"がグレーアウトしていて選択できない。
SQLServerのあるローカルから"sa"で接続すると再起動できる。
クライアント側のイベントログにエラーも出てる
DistributedCOM
構成されているどのプロトコルを使っても、DCOM がコンピューター [リモートのコンピューター名] と通信できませんでした。要求元 PID 25f8 (C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\ManagementStudio\Ssms.exe)。
SQLServerの再起動はWMIという仕組みで使える機能だそうで、SQLServerとの接続とは別の仕組みでリモートのWindowsと通信する必要があるみたい。SQLServerの状態アイコンも同じ。
SQL Server ツールでサーバーの状態を表示できるようにする WMI の構成
ManagementStudioでは起動したwindowsアカウントで接続をするのかな だとしたら、ワークグループ環境では接続先にも同じ名前とパスワードのアカウントを作って...ってやる必要があるかも あとファイアウォールの設定とかも必要か。
いま扱ってるのはAWS EC2だからRunCommandでやることにする。
AWS EC2でSQLServerのインスタンスを作ったときにExpressエディションではリモートからアクセスできなかった。 Webエディションではできたのに。
エディションによって、ネットワーク構成の既定値が違うらしい。Expressエディションでは、TCP/IPが無効になっている。
SQL Server の既定のネットワーク構成
GUIの構成マネージャーから有効にすればOK。 でもコマンドラインからしたい。
SQLServer管理オブジェクト(SMO)が用意されているのでこれを使えばいいらしい。 SMOは.NET Framework アセンブリなのでPowerShellから使える。
サーバー ネットワーク プロトコルを有効または無効にする方法 (SQL Server PowerShell)
SQL Server 管理オブジェクト (SMO) プログラミング ガイド
SQL Server PowerShell
#TCP/IPでの接続を有効にする(SQLServerの再起動が必要) Set-ExecutionPolicy -Scope Process RemoteSigned -Force Impoert-Module 'sqlps' $wmi = New-Object 'Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer' $tcp = $wmi.GetSmoObject("ManagedComputer[@Name='computerName']/ServerInstance[@Name='MSSQLSERVER']/ServerProtocol[@Name='Tcp']") $tcp.IsEnabled = $true $tcp.Alter()
今回は必要なSMOアセンブリだけを読み込めば十分なんだけど、sqlpsモジュールをインポートしとけばロードされるアセンブリに必要なものが含まれてるから便利。
初期値がListenAll=yesになっているので、IsEnable=trueにすれば全部のIPアドレスが有効になる。
ServerProtocol クラス (Microsoft.SqlServer.Management.Smo.Wmi)
::SQLServerを再起動する net stop MSSQLSERVER /y net start SQLSERVERAGENT
停止するときは、/yオプションでエージェントも停止させる。 エージェントを起動するとSQLServer本体も起動する。