SQLの窓

2013年09月26日


VS2010 Formアプリ(C#) : 通知領域で常駐し、ブラウザのフォームからデータを取得する HttpServer テンプレート

SkyDrive へ移動




Form へは、SynchronizationContext クラス を使用してスレッド内から UI スレッドへデータを転送しています。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Net;

namespace VS2010_HttpServer
{
	public partial class Form1 : Form
	{

		// メニュー用オブジェクト
		private ContextMenu myContextMenu = null;
		private MenuItem myMenuItem1 = null;
		private MenuItem myMenuItem2 = null;
		private MenuItem myMenuItem3 = null;
		private NotifyIcon myNotifyIcon = null;

		private SynchronizationContext sc = null;

		public Form1()
		{
			InitializeComponent();

			// メニュー用のインスタンス作成
			myContextMenu = new ContextMenu();
			myMenuItem1 = new MenuItem();
			myMenuItem2 = new MenuItem();
			myMenuItem3 = new MenuItem();
			// コンテキストメニューにメニュー項目を一つ追加
			myContextMenu.MenuItems.AddRange(new MenuItem[] {
				myMenuItem1, myMenuItem2,myMenuItem3
			});
			// ******************************************
			// メニュー項目1の設定
			// ******************************************
			myMenuItem1.Index = 0;		// 親メニュー内のメニュー項目の位置
			myMenuItem1.Text = "終了";
			// 終了処理
			myMenuItem1.Click +=  (Object sender,EventArgs e) => {
				WebClient client = new WebClient();
				try
				{
					client.DownloadString("http://localhost:8080/q");
				}
				catch (Exception ex)	{
					Debug.WriteLine(ex.Message);
				}
				client.Dispose();
				myNotifyIcon.Visible = false;
				myNotifyIcon.Dispose();
				Thread.Sleep(5000);
				System.Windows.Forms.Application.Exit(); 

			};
			// ******************************************
			// メニュー項目2の設定
			// ******************************************
			myMenuItem2.Index = 1;		// 親メニュー内のメニュー項目の位置
			myMenuItem2.Text = "非表示";
			// 終了処理
			myMenuItem2.Click += (Object sender, EventArgs e) =>
			{
				this.ShowInTaskbar = false;	// タスク バーに表示しない
				this.WindowState = FormWindowState.Minimized;	// 最小化
				this.Opacity = 0;	// 透明
			};
			// ******************************************
			// メニュー項目3の設定
			// ******************************************
			myMenuItem3.Index = 2;		// 親メニュー内のメニュー項目の位置
			myMenuItem3.Text = "表示";
			// 終了処理
			myMenuItem3.Click += (Object sender, EventArgs e) =>
			{
				this.ShowInTaskbar = true;	// タスク バーに表示
				this.WindowState = FormWindowState.Normal;	// 通常
				this.Opacity = 100;	// 不透明
			};

			// NotifyIcon : 通知領域にアイコンを作成するコンポーネント
			myNotifyIcon = new NotifyIcon(new Container());
			Assembly myAssembly = Assembly.GetExecutingAssembly();
			// リソースに定義したアイコンを取得
			myNotifyIcon.Icon = Properties.Resources.Server;
			myNotifyIcon.Text = "lightbox コマンドサーバー";
			myNotifyIcon.Visible = true;
			// メニューをセット
			myNotifyIcon.ContextMenu = myContextMenu ;

		}

		// フォームの初期処理
		private void Form1_Load(object sender, EventArgs e)
		{
			sc = SynchronizationContext.Current;
	        // スレッド開始  
			new Thread( () =>
			{

				// HTTP プロトコル用リスナー
				TcpListener tl = new TcpListener(System.Net.IPAddress.Any, 8080);
				tl.Start();

				TcpClient tcp = null;
				NetworkStream stream = null;
				StreamReader reader = null;
				StreamWriter writer = null;
				string line = null;
				string lineall = null;

				while (true)
				{
					// HTTP の受信待ち
					tcp = tl.AcceptTcpClient();

					// 以下は、受信した場合に処理されます
					// データの入り口 ( NetworkStream )
					stream = tcp.GetStream();

					// これが無いと Google Chrome は読み込まなかった
					Thread.Sleep(500);

					// ストリームを読み込むオブジェクトを取得
					reader = new StreamReader(stream);
					// writer = new StreamWriter(stream, Encoding.GetEncoding("shift_jis"));
					writer = new StreamWriter(stream, new UTF8Encoding(false));

					// 一回の受信で取得した全文字列
					lineall = "";

					if (stream.DataAvailable)
					{
						// 非同期で一行取得
						while (true)
						{
							line = reader.ReadLine();
							// 空でチェックするしかないようです。
							if (line == "")
							{
								break;
							}
							lineall += line + "\n";
						}
					}
					Debug.WriteLine(lineall);

					// HTTP プロトコルに従って、ヘッダと本文を返す
					writer.WriteLine("HTTP/1.1 200 OK");
					writer.WriteLine("Content-Type: text/plain; charset=utf-8");
					int length = Encoding.GetEncoding("utf-8").GetByteCount(lineall);
					writer.WriteLine("Content-Length: " + length);

					writer.WriteLine();
					writer.Write(lineall);

					// オブジェクトを閉じる
					writer.Close();
					reader.Close();
					stream.Close();
					if (lineall == "")
					{
						// Console.WriteLine("データがありません");
						continue;
					}

					String[] cmds = lineall.Split(new string[] { " ", "?", "=", "&" }, StringSplitOptions.None);
					String field = "";
					String query = "";
					string param = "スレッドより";
					try {
						// ブラウザからの必要の無い呼び出し
						if (cmds[1] == "/favicon.ico") {
							continue;
						}

						// UI スレッドでの実行
						sc.Post((object post_state) => {
							// スレッドより引き渡された引数の表示
							Console.WriteLine((string)post_state);
							this.textBox1.Text = cmds[0];
							this.textBox2.Text = cmds[1];
							this.textBox3.Text = cmds[2];
							this.textBox4.Text = cmds[3];
						}, param);
						// 入力フィールド
						field = cmds[2];
						// 入力フィールドの内容
						query = cmds[3];
						Debug.WriteLine(cmds[3]);
						if (cmds[1] == "/q") {
							query = "quit";
						}
					}
					catch (Exception ex) {
						Console.WriteLine(ex.Message);
						query = "";
					}
					// アドレスバーで、http://localhost:8080/q と入力した場合はスレッドを終了
					if (query == "quit") {
						tl.Stop();
						break;
					}

					// フォームからの GET コマンドでの呼び出しを想定した処理
					if (field == "sql") {
						query = query.Replace("+", " ");
						query = Uri.UnescapeDataString(query);
						sc.Post((object post_state) =>
						{
							// スレッドより引き渡された引数の表示
							Console.WriteLine((string)post_state);
							this.textBox5.Text = query;
						}, "SQLの表示");
					}

				}

				Debug.WriteLine("スレッドを終了します");
				myNotifyIcon.Visible = false;
				myNotifyIcon.Dispose();
				Thread.Sleep(5000);
				System.Windows.Forms.Application.Exit(); 

			}).Start();

		}
	}
}


以下のフォームから送信してテストします。実際は、戻すデータとして SQL に対応する JSON データを作成して、Windows ストア、Windows Phone、Android 等からのデータベースアクセス処理のテストを想定しています。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SQL送信</title>
<style>
</style>
</head>
<body>
<h3>SQL送信</a></h3>
<form method="get" action="http://localhost:8080/test">
<textarea name="sql" style="width:400px;height:100px;"></textarea>
<br />
<input type="submit" name="send" value="送信">
</form>
</body>
</html>

関連する記事

VS2012 Formアプリ(C#) : 通知領域で常駐する HttpServer テンプレート



【VS(C#)の最新記事】
posted by lightbox at 2013-09-26 23:41 | VS(C#) | このブログの読者になる | 更新情報をチェックする
バッチ処理

Microsoft Office
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

Android SDK ポケットリファレンス
改訂版 Webデザイナーのための jQuery入門
今すぐ使えるかんたん ホームページ HTML&CSS入門
CSS ドロップシャドウの参考デモ
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり