-
Notifications
You must be signed in to change notification settings - Fork 0
/
easychat.cs
89 lines (68 loc) · 2.81 KB
/
easychat.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using System.Collections.Concurrent;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
namespace EasyChat
{
public class EasyChatService
{
public EasyChatService(RequestDelegate requestDelegate)
{
this.requestDelegate = requestDelegate;
}
public async Task Invoke(HttpContext context)
{
if (!context.WebSockets.IsWebSocketRequest)
{
await requestDelegate.Invoke(context);
return;
}
var token = context.RequestAborted;
var socket = await context.WebSockets.AcceptWebSocketAsync();
var guid = Guid.NewGuid().ToString();
sockets.TryAdd(guid, socket);
while (true)
{
if (token.IsCancellationRequested)
break;
var message = await GetMessageAsync(socket, token);
System.Console.WriteLine($"Received message - {message} at {DateTime.Now}");
if (string.IsNullOrEmpty(message))
{
if (socket.State != WebSocketState.Open)
break;
continue;
}
foreach (var s in sockets.Where(p => p.Value.State == WebSocketState.Open))
await SendMessageAsync(s.Value, message, token);
}
sockets.TryRemove(guid, out WebSocket redundantSocket);
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Session ended", token);
socket.Dispose();
}
async Task<string> GetMessageAsync(WebSocket socket, CancellationToken token)
{
WebSocketReceiveResult result;
var message = new ArraySegment<byte>(new byte[4096]);
string receivedMessage = string.Empty;
do
{
token.ThrowIfCancellationRequested();
result = await socket.ReceiveAsync(message, token);
var messageBytes = message.Skip(message.Offset).Take(result.Count).ToArray();
receivedMessage = Encoding.UTF8.GetString(messageBytes);
} while (!result.EndOfMessage);
if (result.MessageType != WebSocketMessageType.Text)
return null;
return receivedMessage;
}
Task SendMessageAsync(WebSocket socket, string message, CancellationToken token)
{
var byteMessage = Encoding.UTF8.GetBytes(message);
var segmnet = new ArraySegment<byte>(byteMessage);
return socket.SendAsync(segmnet, WebSocketMessageType.Text, true, token);
}
readonly RequestDelegate requestDelegate;
ConcurrentDictionary<string, WebSocket> sockets = new ConcurrentDictionary<string, WebSocket>();
}
}