概要
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();
}
}
}
}
以上。