cscの作法 その309

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
websocket serverを実装せよ。
湯婆婆を返却、せよ。

# サンプルコード

```


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Globalization;

namespace WebSocketServer
{
	internal class Program : IDisposable {
		private static WebSocket webSocket;
		public async void Dispose() {
			if (webSocket != null)
			{
				Console.WriteLine("WebSocketサーバーからの切断");
				await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "WebSocketサーバーからの切断", CancellationToken.None);
				webSocket.Dispose();
			}
		}
		static async Task Receive() {
			while (true)
			{
				if (webSocket == null || (webSocket != null && webSocket.State != WebSocketState.Open))
				{
					Console.WriteLine("WebSocket接続がありません");
					Console.Write(">");
					return;
				}
				var buffer = new byte[1024];
				var byteArray = new ArraySegment<byte>(buffer);
				var ret = await webSocket.ReceiveAsync(byteArray, CancellationToken.None);
				if (ret.MessageType == WebSocketMessageType.Close)
				{
					Console.WriteLine("クライアントから切断されました");
					Console.Write(">");
					await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "クライアントから切断されました", CancellationToken.None);
					return;
				}
				if (ret.MessageType != WebSocketMessageType.Text)
				{
					Console.WriteLine("テキストデータではありません");
					Console.Write(">");
					await webSocket.CloseAsync(WebSocketCloseStatus.InvalidMessageType, "テキストデータではありません", CancellationToken.None);
					return;
				}
				int size = ret.Count;
				while (!ret.EndOfMessage)
				{
					if (buffer.Length <= size)
					{
						Console.WriteLine("バッファーオーバー");
						await webSocket.CloseAsync(WebSocketCloseStatus.InvalidPayloadData, "バッファーオーバー", CancellationToken.None);
						return;
					}
					byteArray = new ArraySegment<byte>(buffer, size, buffer.Length - size);
					ret = await webSocket.ReceiveAsync(byteArray, CancellationToken.None);
					size += ret.Count;
				}
				var message = Encoding.UTF8.GetString(buffer, 0, size);
				Console.WriteLine(message);
				Console.Write(">");
				string name = message;
				string res = String.Format("フン。{0}というのかい。贅沢な名だねぇ。", name);
				Random random = new Random();
				StringInfo nameInfo = new StringInfo(name);
				int newNameIndex = random.Next(nameInfo.LengthInTextElements);
				string newName = nameInfo.SubstringByTextElements(newNameIndex, 1);
				res += String.Format("今からお前の名前は{0}だ。いいかい、{0}だよ。分かったら返事をするんだ、{0}!!", newName);
				buffer = Encoding.UTF8.GetBytes(res);
				byteArray = new ArraySegment<byte>(buffer);
				await webSocket.SendAsync(byteArray, WebSocketMessageType.Text, true, CancellationToken.None);
				Console.WriteLine(res);
				Console.Write(">");
			}
		}
		static async Task CreateWebSocketServerAndReceive() {
			var httpListener = new HttpListener();
			httpListener.Prefixes.Add("http://localhost:50002/");
			httpListener.Start();
			Console.WriteLine("WebSocket受付開始");
			while (true)
			{
				var httpListenerContext = await httpListener.GetContextAsync();
				if (!httpListenerContext.Request.IsWebSocketRequest)
				{
					Console.WriteLine("WebSocketでの接続ではありません");
					httpListenerContext.Response.StatusCode = 400;
					httpListenerContext.Response.Close();
					return;
				}
				var taskHttpListenerContext = await httpListenerContext.AcceptWebSocketAsync(null);
				if (webSocket != null)
				{
					webSocket.Dispose();
				}
				webSocket = taskHttpListenerContext.WebSocket;
				Console.WriteLine("WebSocket接続");
				Console.Write(">");
				var nowait = Receive();
			}
		}
		static void Main(string[] args) {
			Console.WriteLine("開始:CTRL+Cで停止してください");
			var nowait1 = CreateWebSocketServerAndReceive();
			using (var manualResetEvent = new ManualResetEvent(false))
			{
				manualResetEvent.WaitOne();
			}
		}
	}
}





```

以上。