LoginSignup
1
0

cscの作法 その309

Posted at

概要

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();
			}
		}
	}
}





以上。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0