cscの作法 その316

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

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

# サンプルコード

```

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;
using System.IO;
using LitJson;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Collections;


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(">");
				ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
				string _url = "https://api.openai.com/v1/chat/completions";
				string _token = "sk-＊＊＊＊";
				string json = "{\"model\": \"gpt-3.5-turbo\",\"messages\": [{\"role\": \"user\", \"content\": \"" + message + "\"}]}";
				Console.WriteLine(json);
				var content = new StringContent(json, Encoding.UTF8, "application/json");
				HttpClient client = new HttpClient();
				client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _token);
				var response = client.PostAsync(_url, content).Result;
				var responseString = response.Content.ReadAsStringAsync().Result;
				Console.WriteLine(responseString);
				LitJson.JsonData res = LitJson.JsonMapper.ToObject(responseString);
				Console.WriteLine(res["model"]);
				Console.WriteLine(res["choices"][0]["message"]["content"]);
				string str = " " + res["choices"][0]["message"]["content"];
				buffer = Encoding.UTF8.GetBytes(str);
				byteArray = new ArraySegment<byte>(buffer);
				await webSocket.SendAsync(byteArray, WebSocketMessageType.Text, true, CancellationToken.None);
				Console.WriteLine(str);
				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();
			}
		}
	}
}






```

以上。