|
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- using Discord.API;
- using Discord.API.Gateway;
- using Discord.Logging;
- using System;
- using System.Net.WebSockets;
- using System.Threading;
- using System.Threading.Tasks;
- using WebSocketClient = System.Net.WebSockets.WebSocket;
-
- namespace Discord.Relay
- {
- public class RelayConnection
- {
- private readonly RelayServer _server;
- private readonly WebSocketClient _socket;
- private readonly CancellationTokenSource _cancelToken;
- private readonly byte[] _inBuffer, _outBuffer;
- private readonly Logger _logger;
-
- internal RelayConnection(RelayServer server, WebSocketClient socket, int id)
- {
- _server = server;
- _socket = socket;
- _cancelToken = new CancellationTokenSource();
- _inBuffer = new byte[4000];
- _outBuffer = new byte[4000];
- _logger = server.LogManager.CreateLogger($"Client #{id}");
- }
-
- internal async Task RunAsync()
- {
- await _logger.InfoAsync($"Connected");
- var token = _cancelToken.Token;
- try
- {
- var segment = new ArraySegment<byte>(_inBuffer);
-
-
- await SendAsync(GatewayOpCode.Hello, new HelloEvent { HeartbeatInterval = 15000 }).ConfigureAwait(false);
-
- while (_socket.State == WebSocketState.Open)
- {
- var result = await _socket.ReceiveAsync(segment, token).ConfigureAwait(false);
- if (result.MessageType == WebSocketMessageType.Close)
- await _logger.WarningAsync($"Received Close {result.CloseStatus} ({result.CloseStatusDescription ?? "No Reason"})").ConfigureAwait(false);
- else
- await _logger.InfoAsync($"Received {result.Count} bytes");
- }
- }
- catch (OperationCanceledException)
- {
- try { await _socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None).ConfigureAwait(false); }
- catch { }
- }
- catch (Exception ex)
- {
- try { await _socket.CloseAsync(WebSocketCloseStatus.InternalServerError, ex.Message, CancellationToken.None).ConfigureAwait(false); }
- catch { }
- }
- finally
- {
- await _logger.InfoAsync($"Disconnected");
- }
- }
-
- internal void Stop()
- {
- _cancelToken.Cancel();
- }
-
- private async Task SendAsync(GatewayOpCode opCode, object payload)
- {
- var frame = new SocketFrame { Operation = (int)opCode, Payload = payload };
- var bytes = _server.Serialize(frame, _outBuffer);
- var segment = new ArraySegment<byte>(_outBuffer, 0, bytes);
- await _socket.SendAsync(segment, WebSocketMessageType.Text, true, CancellationToken.None).ConfigureAwait(false);
- }
- }
- }
|