WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

MySQL をインストールしました(その 2)

by WebSurfer 2017年1月31日 21:00

先日買った Windows 10 Pro 64-bit のノート PC に MySQL をインストールしましたので、その顛末を備忘録として書いておきます。インストールしたのは現時点での最新版 MySQL Community Server 5.7.17 と Connector/Net 6.9.9 です。

先の記事「MySQL をインストールしました」で MySQL Community Server 5.5.11 と Connector/Net 6.3.6 をインストールした時の概略を書きましたが、6 年近く昔の話なので、その時とはかなりやり方が変わっていました。

まず、MySQL のダウンロードサイト MySQL Community Downloads に行き、そこから順次リンクをたどればインストーラーのダウンロードページ Download MySQL Installer が見つかると思います。

2017/1/27 時点では Generally Available (GA) Releases として MySQL Installer 5.7.17 というバージョンが表示されていました。このインストーラーを使って、Server 本体, Connector/NET はもちろんすべての製品をインストールできるそうです。

また、Windows (x86, 32-bit), MySQL Installer MSI とありますが、それは "Note: MySQL Installer is 32 bit, but will install both 32 bit and 64 bit binaries." というこで、64-bit OS にもこれを使ってインストールできます。

ダウンロードできるファイルは 2 種類あってネットに接続できる環境か否かで選ぶらしいです。自分は mysql-installer-web-community-5.7.17.0.msi(ネットに接続してダウンロードしながらインストールするバージョン)を使いました。

以下にインストールするときに表示された画像を貼って要点を書いておきます。

(1) ライセンス条項に合意

License Agreement

I accept the license terms にチェックを入れて Next をクリックします。

(2) セットアップ内容の選択

Choosing a Setup Type

Developer Default で十分かもしれませんが、万一不足していて後で追加インストールすることになるのも面倒なので Full を選択しました。

(3) 要件のチェック

Check Requirements

先の「(2) セットアップ内容の選択」画面で選んだ内容でインストール先の PC が要件を満たしているかをチェックしているようです。Python はインストールしてないので当然ですが、Python 3.4 is not installed という警告が出ます。無視して Next をクリックします。

(4) インストール開始

Installation

Execute をクリックするとダウンロードとインストールが始まります。

(5) インストール完了

Installation

ダウンロードとインストールには少々時間がかかります。完了すると上の画像のようにそれぞれの項目にチェックマークがつきます。

(6) 製品の構成

Product Configuration

インストールした製品の構成設定を行います。

(7) タイプとネットワーク

Type and Networking

開発マシンで使用するので Development Machine を選択します。Named Pipe と Shared Memory にはデフォルトではチェックが入ってませんが、入れておきました。ファイアウォールの穴あけはデフォルトでチェックが入っていて自動的にやってくれるようです。

(8) MySQL ユーザー詳細情報

MySQL User Details

設定したパスワードは忘れないように覚えておいてください。自分は開発マシンのログイン用と同じパスワードを入力したのですが Week だそうです。(汗) 無視してそのまま続けることはできます。

(9) MySQL サーバーへのアカウント登録

Accounts and Roles

先の「(8) MySQL ユーザー詳細情報」画面で入力したものと同じパスワードを入力し、Add User をクリックします。

(10) Windows Service

Windows Service

PC の Windows OS 上で MySQL を実行するサービス等の設定を行います。画面の通りのデフォルトでいいと思います。

(11) プラグインの設定

Plugins and Extensions

ドキュメントをオンラインで読んでくるための設定を行うようです。画面の通りの設定でいいと思います。

(12) 構成設定の適用

Apply Server Configuration

Execute をクリックすると画面に表示されている各項目の設定が自動的に行われます。

(13) 設定の完了

Apply Server Configuration

構成設定が完了すると各項目にチェックマークが入ります。

(14) サーバーへの接続

Connect to Server

先の「(8) MySQL ユーザー詳細情報」画面で設定したユーザー名とパスワードで接続を試みるということのようです。

(15) 接続の確認

Connect to Server

有効なユーザー名とパスワードを入力して Check をクリックすると Connection successful と表示されます。

(16) サーバー構成の適用

Apply Server Configuration

Execute をクリックすると画面に表示されている各項目が自動的に実行されます。

(17) サーバー構成の完了

Apply Server Configuration

構成設定が完了すると各項目にチェックマークが入ります。

(18) 製品の構成

Product Configuration

上の「(17) サーバー構成の完了」画面で Finish をクリックすると「(6) 製品の構成」画面に戻ります。

(19) 完了

Installation Complete

上の「(18) 製品の構成」画面で Next をクリックするとインストールと設定が完了します。一連の作業で記録されたログがクリップボードにコピーできますので、残しておいた方がよさそうです。

(20) インストールされた製品

MySQL Installer - Community というツールも一緒にインストールされるので、それを起動すると画面のように製品一覧がバージョンと共に表示されます。



最後に、インストールしてみて分かった新発見(というより自分が知らなかっただけですが)を書いておきます。

  1. Connector/NET は Any CPU でコンパイルされている。自分でも corflags.exe を使って確認しました。おかげで ODP.NET のように 32/64-bit の違いに悩むことはなさそうです。
  2. Connector/NET 6.9.9 には .NET 4+ 用の .dll しか含まれない。バージョン 6.4.x から .NET 3.5 以下用の .dll は含まれなくなったらしいです。自分が使っているレンタルサーバーは .NET 3.5 までにしか対応しておらず、それの保守環境を作るのにちょっと困りました。
  3. mysql というコマンドはなくなった模様。旧マシンで行ったようにコマンドラインから mysql と入力して立ち上げることはできなくなっています。代わりに MySQL 5.7 Command Line Client というのを起動して使うことになります。
  4. mysqldump というコマンドもなくなった模様。代わりに mysqldbexport というユーティリティを使うらしいです。その他 mysqldbimport など多々ユーティリティが用意されています。

Tags: ,

MySQL

クロスドメインの WCF サービス

by WebSurfer 2016年12月27日 21:58

先の記事「WCF と jQuery AJAX」で書いた ASP.NET がホストする WCF サービスを、クロスドメインで利用する方法について書きます。

プリフライトリクエスト

MSDN Blog の記事「JavaScript のクロス ドメイン (Cross-Domain) 問題の回避と諸注意」では以下の 3 つの方法が紹介されています。それぞれの概要が説明されていて分かりやすいので一読されるといいと思います。

  1. Cross Document Messaging (XDM)
  2. Cross-Origin Resource Sharing (CORS)
  3. JSONP

ここでは 2 番目の Cross-Origin Resource Sharing (CORS) という方法を使います。上の画像は CORS でのプリフライトリクエストとそれに対する応答を Fiddler で見たものです。

(最初は jQuery.ajax を利用した JSONP が一番簡単かと思ったのですが、jQuery.ajax では応答のスクリプトにコールバック jQuery1830...26( ... ) で囲んだ JSON 文字列を期待しているのに、WCF サービスは JSON 文字列しか返さないので使えませんでした)

CORS は HTML 5 の仕様なので依然として使えないブラウザがありますが、対応ブラウザが増えるにつれ今後の本命になるだろうということです。(ちなみに、IE9 は対応してませんでした。上に紹介した MSDN Blog の記事によると独自の XDomainRequest オブジェクトを使用するという回避方法はあるそうですが)

まず、この記事を書くに当たって自分が参考にさせていただいた記事へのリンクを張っておきます。私の説明では分からない場合はそちらを読まれるといいと思います。手抜きでスミマセン。(汗)

  1. HTTP アクセス制御 (CORS)
  2. CORS(Cross-Origin Resource Sharing)について整理してみた

ブラウザが CORS をサポートしていれば、クライアント側の処理はブラウザが自動的に行いますので、開発者はクライアント側の対応は何もする必要がないです。

サーバー側すなわち ASP.NET Web アプリで CORS に必要な応答ヘッダ返せるようにするだけで対応できます。基本的には Global.asax ファイルに以下のコードを記述してやれば可能になります。(厳格なセキュリティを要求せず無条件で応答するというような場合はもっと簡単になります)

protected void Application_BeginRequest(object sender, 
                                                 EventArgs e)
{
  CrossOriginResourceSharingSetting();
}

private void CrossOriginResourceSharingSetting()
{
  HttpRequest request = HttpContext.Current.Request;
  HttpResponse response = HttpContext.Current.Response;

  // プリフライトリクエストの場合
  if (request.HttpMethod == "OPTIONS")
  {
    // 要求ヘッダの origin フィールドを取得
    string origin = request.Headers["origin"];

    // ここで origin に指定されたドメインのチェックを行った
    // 方がいいかもしれないが省略。要求ヘッダの origin フィ
    // ールドで送信されてきたものをそのまま返す

    // 要求ヘッダに origin フィールドがなければ何もしない
    if (!string.IsNullOrEmpty(origin))
    {
      string method = 
       request.Headers["Access-Control-Request-Method"];
      string header = 
        request.Headers["Access-Control-Request-Headers"];

      // 要求ヘッダに Access-Control-Request-Method および
      // Access-Control-Request-Headers がなければ何もしない
      if (!string.IsNullOrEmpty(method) && 
          !string.IsNullOrEmpty(header))
      {
        // method が GET または POST 以外は対応しない
        // header もチェックした方がいいかもしれない・・・
        if (method.Contains("GET") || method.Contains("POST"))
        {                            
          response.
            AddHeader("Access-Control-Allow-Origin", origin);                            
          response.
            AddHeader("Access-Control-Allow-Methods", method);                            
          response.
            AddHeader("Access-Control-Allow-Headers", header);

          // Access-Control-Max-Age ヘッダも任意で追加できる。
          // 指定した時間(秒)プリフライトの結果をキャッシュで
          // きるので、実際に運用に移す際は追加する方がよさそう
          //response.AddHeader("Access-Control-Max-Age", "600");

          response.End();
        }
      }
    }                
  }
  else
  {
    // 要求ヘッダの origin フィールドを取得
    string origin = request.Headers["origin"];

    // ここで origin に指定されたドメインのチェックを行った方
    // がいいかもしれないが省略。要求ヘッダの origin フィール
    // ドで送信されてきたものをそのまま返す

    // 要求ヘッダに origin フィールドがなければ何もしない
    if (!string.IsNullOrEmpty(origin))
    {                    
      response.AddHeader("Access-Control-Allow-Origin", origin);
    }
  }            
}

上記のコードが何をしているかと言うと、要求が「プリフライトリクエスト」になる場合と「シンプルなリクエスト」になる場合とに処置を分けて、CORS に必要な応答ヘッダを設定しているだけです。詳しくはコード中のコメントに書きましたのでそれを見てください。

CORS をサポートしているブラウザがクロスドメインでどのような処置を行うかは、要求が「シンプルなリクエスト」になるか否かによって異なってきます。要求が「シンプルなリクエスト」になる条件は、上に紹介した記事「HTTP アクセス制御 (CORS)」を読んでください。

例えば、先の記事「WCF と jQuery AJAX」で言うと「(3) WCF AJAX サービスへのアクセス」のコードで getAllCars メソッドを使う方が「シンプルなリクエスト」になります。

getCarsByDoors メソッドを使う方は要求ヘッダに contentType: "application/json; charset=utf-8" が含まれるので「シンプルなリクエスト」にはならず、「プリフライトリクエスト」が事前に行われます。

シンプルなリクエスト

要求が「シンプルなリクエスト」になる場合、CORS をサポートしているブラウザからは origin: http://<要求元のドメイン> を追加する以外には普通にサーバーに要求を出します。(ただし、IE9 では要求さえ出ませんので注意)

サーバー側では origin フィールドを見て要求側のドメインがクロスドメインアクセスを許可する対象であるかを判定し、受け入れの判断をすることができます。

ただし、上の Global.asax のコードでは要求側のドメインのチェックは行っていません。要求ヘッダの origin フィールドのドメインをそのまま応答ヘッダの Access-Control-Allow-Origin に設定して返しています。それだけでも、* を設定するよりはよさそうです。

ブラウザは応答ヘッダの Access-Control-Allow-Origin: http://<求元のドメイン> を見てクロスドメインアクセスに成功したと判断し、応答に含まれる JSON 文字列などのコンテンツを処置します。

プリフライトリクエスト

要求が「シンプルなリクエスト」にならない場合、CORS をサポートしているブラウザからは実際のリクエストを送信しても安全かを確かめるための「プリフライトリクエスト」が事前に行われます。

上の画像はその要求と応答を Fiddler で見たものです。

左下のウィンドウはブラウザがクロスドメインに対する要求でかつ「シンプルなリクエスト」にならないと判定して自動的にプリフライトリクエストを要求した要求ヘッダの内容です。

赤枠で囲った部分を見てください。HTTP メソッドの OPTIONS、要求ヘッダに含まれる origin, Access-Control-Request-Method, Access-Control-Request-Headers に注目です。

サーバーがクロスドメインからのリクエストを受け、それがプリフライトリクエストであるかどうかを判断するにはそれらの情報をチェックします。

そして、プリフライトリクエストであると判断した場合は上の画像の右下のウィンドウの赤枠で囲ったような応答ヘッダを返します。ここでは、Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers は要求ヘッダで受けたものと同じ内容に設定しています。

ブラウザはそれらの情報を見て実際のリクエストを送信しても安全かを確認し、サーバーに要求を出して(上の画像で #3 がそれ)応答を取得し、コンテンツに含まれる JSON 文字列などの情報を処置します。

Tags: , , ,

AJAX

チャンク形式でダウンロード

by WebSurfer 2016年12月14日 23:49

ASP.NET Web Forms アプリにおいて、ファイルをチャンク形式エンコーディングしてブラウザにダウンロードするサンプルを備忘録として書いておきます。

Fiddler で見た応答

チャンク形式エンコーディングとは HTTP/1.1 で定義されている方式で、送信したいデータを任意のサイズのチャンク(塊)に分割し、各々のチャンクにサイズ情報を付与するエンコード方式です。

メリットは、送信するデータを動的に作成していて、作成中は全体のサイズが分からないが、部分的にでも作成でき次第送信を始められるというところにあるようです。(一旦全データをバッファして全体のサイズを調べ、Content-Length に設定するということをしなくても済みます)

サーバーにある既存のファイルをダウンロードするような場合はファイルのサイズは分かっていますので、チャンク形式エンコーディングせずに Content-Length を設定してダウンロードする方がよさそうです。(なので、自分的にはチャンク形式エンコーディングの使い道はあまりなさそうですが、せっかく調べたので書いておきます)

ASP.NET Web Forms アプリでは、HttpResponse.OutputStream にチャンクを書き込んだら Flush することでそのチャンクがクライアント(ブラウザ)に送信されます。

具体的には以下のコードのようにします。Sig552T8.jpg は 30,903 バイトの jpeg 画像ファイルで、以下の .aspx ページをブラウザから要求すると、その画像データを 10,000 バイトずつチャンクに分けて送信するようになっています。

この記事の一番上の画像を見てください。Fiddler を使ってサーバーからの応答をキャプチャしたものですが、応答ヘッダの赤線で示した部分にチャンク形式エンコーディングになっていること、コンテンツの最初の部分 32 37 31 30(UTF-8 で 2710 ⇒ 10 進数に直すと 10000)に最初に送信されたチャンクのサイズが示されていることが分かります。

<%@ Page Language="C#" %>
<%@ Import Namespace="System.IO" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
  protected void Page_Load(object sender, EventArgs e)
  {
    string folder = "~/images/";
    string filename = "Sig552T8.jpg";
    string path = Server.MapPath(folder + filename);
    FileInfo fileInfo = new FileInfo(path);

    if (fileInfo.Exists)
    {
      int chunkSize = 10000;
      Byte[] buffer = new Byte[chunkSize];
      Response.Clear();   

      using (FileStream stream = File.OpenRead(path))
      {
        long length = stream.Length;
        Response.ContentType = "image/jpeg";
        Response.AddHeader("Content-Disposition", 
                "attachment; filename=" + fileInfo.Name);

        // ここで Flush しても通知バーは表示されない。以下のコ
        // ードのコメントアウトを外すとそれが確認できます。
        // Response.Flush();
        // System.Threading.Thread.Sleep(10000);

        while (length > 0 && Response.IsClientConnected)
        {
          int lengthRead = stream.Read(buffer, 0, chunkSize);
          Response.OutputStream.Write(buffer, 0, lengthRead);

          // ここでの最初の Flush で通知バーが表示される
          Response.Flush();
          length -= lengthRead;

          // chunked ダウンロードされていることを確認するため
          // 試験的に入れたコード。コメントアウトを外すとここ
          // で 5 秒待つ。
          // System.Threading.Thread.Sleep(5000);
        }
      }

      // <!DOCTYPE html ... 以下の html ソースをダウンロード
      // させないために設定
      Response.SuppressContent = true;
    }        
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    </form>
</body>
</html>

ブラウザ上ではどういう動きになるかと言うと、IE9 を使った場合ですが、上記コードの中の while ループの最初の Flush で以下の画像のように通知バーが表示されます。

IE9 の通知バー

上の通知バーの[ファイルを開く(O)]または[保存(S)]をクリックすると通知バーは以下の画像のように変わります。(注:Thread.Sleep(5000) のコメントアウトを外して試してください)

ダウンロード中の通知バー

その後、最初に表示された通知バーで[ファイルを開く(O)]をクリックしていた場合はダウンロードが完了すると画像 Sig552T8.jpg がブラウザ上に表示されます。

最初に表示された通知バーで[保存(S)]をクリックしていた場合はダウンロードが完了すると通知バーは以下の画像のように変わります。

ダウンロード完了の通知バー

[ファイルを開く(O)]または[フォルダーを開く(P)]でダウンロードした画像ファイルを確認できます。

Tags:

Upload Download

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  2017年7月  >>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

View posts in large calendar