123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- using System.Collections.Concurrent;
- using System.Net;
- using System.Net.WebSockets;
- using System.Text;
- namespace SimpleWebChat.ConHost
- {
- public static class SimpleVoiceChatServerModule
- {
- public class VoiceSession
- {
- public WebSocket Host { get; set; }
- public WebSocket Guest { get; set; }
- }
- private static readonly ConcurrentDictionary<string, VoiceSession> VoiceChatSessions = new();
- public static void ProcessRequest(HttpListenerContext context, int currentSessionId)
- {
- WebSocket sck = null;
- string num = null;
- var isHost = false;
- VoiceSession pair = null;
- try
- {
- sck = context.AcceptWebSocketAsync("svcp").Result.WebSocket;
- Console.WriteLine($"Request #{currentSessionId:00000} VoiceChat WebSocket Session Start");
- var buffer = new byte[16384];
- var r = sck.ReceiveAsync(buffer, default).Result;
- num = Encoding.UTF8.GetString(buffer, 0, r.Count);
- if (VoiceChatSessions.TryGetValue(num, out pair))
- {
- RunAsGuest(pair, sck, buffer);
- }
- else
- {
- pair = RunAsHost(num, sck, buffer);
- isHost = true;
- }
- }
- catch (Exception)
- {
- try
- {
- if (sck != null && sck.State != WebSocketState.Aborted)
- {
- sck.CloseAsync(WebSocketCloseStatus.InternalServerError, "Error", default).Wait();
- }
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- }
- }
- if (pair != null)
- {
- if (isHost)
- {
- VoiceChatSessions.TryRemove(num, out _);
- pair.Host = null;
- }
- else pair.Guest = null;
- }
- }
- private static VoiceSession RunAsHost(string num, WebSocket sck, byte[] buffer)
- {
- var pair = VoiceChatSessions[num] = new VoiceSession { Host = sck };
- sck.Send("CONNECTED AS HOST");
- while (true)
- {
- var r = sck.ReceiveAsync(buffer, default).Result;
- if (r.Count == 0) break;
- if (pair.Guest != null && pair.Guest.State == WebSocketState.Open)
- {
- pair.Guest
- .SendAsync(new ArraySegment<byte>(buffer, 0, r.Count), WebSocketMessageType.Binary, WebSocketMessageFlags.EndOfMessage, default)
- .AsTask().Wait();
- }
- }
- return pair;
- }
- private static void RunAsGuest(VoiceSession pair, WebSocket sck, byte[] buffer)
- {
- if (pair.Guest != null) { sck.Send("BUSY"); return; }
- pair.Guest = sck;
- var host = pair.Host;
- sck.Send("CONNECTED AS GUEST");
- host.Send("GUEST CONNECTED");
- while (true)
- {
- var r = sck.ReceiveAsync(buffer, default).Result;
- if (r.Count == 0) break;
- if (host.State == WebSocketState.Open)
- {
- host.Send(buffer, 0, r.Count);
- }
- else
- {
- sck.Send("HOST DISCONNECTED");
- return;
- }
- }
- host.Send("GUEST DISCONNECTED");
- }
- private static void Send(this WebSocket sck, string text) => sck.SendAsync(Encoding.UTF8.GetBytes(text), WebSocketMessageType.Text, true, default).Wait();
- private static void Send(this WebSocket sck, byte[] bin) => sck.SendAsync(bin, WebSocketMessageType.Binary, true, default).Wait();
- private static void Send(this WebSocket sck, byte[] bin, int offset, int count) => sck.SendAsync(new ArraySegment<byte>(bin, offset, count), WebSocketMessageType.Binary, true, default).Wait();
- }
- }
|