Isolated Analyzers and Relay projects
This commit is contained in:
103
experiment/Discord.Net.Relay/RelayServer.cs
Normal file
103
experiment/Discord.Net.Relay/RelayServer.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using Discord.API;
|
||||
using Discord.Logging;
|
||||
using Discord.Net.Rest;
|
||||
using Discord.Net.WebSockets;
|
||||
using Discord.Rest;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using WebSocketClient = System.Net.WebSockets.WebSocket;
|
||||
|
||||
namespace Discord.Relay
|
||||
{
|
||||
public class RelayServer
|
||||
{
|
||||
public event Func<LogMessage, Task> Log { add { _logEvent.Add(value); } remove { _logEvent.Remove(value); } }
|
||||
internal readonly AsyncEvent<Func<LogMessage, Task>> _logEvent = new AsyncEvent<Func<LogMessage, Task>>();
|
||||
|
||||
private readonly HashSet<RelayConnection> _connections;
|
||||
private readonly SemaphoreSlim _lock;
|
||||
private readonly JsonSerializer _serializer;
|
||||
private readonly DiscordSocketApiClient _discord;
|
||||
private int _nextId;
|
||||
|
||||
internal LogManager LogManager { get; }
|
||||
|
||||
internal RelayServer(Action<RelayServer> configAction)
|
||||
{
|
||||
_connections = new HashSet<RelayConnection>();
|
||||
_lock = new SemaphoreSlim(1, 1);
|
||||
_serializer = new JsonSerializer();
|
||||
_discord = new DiscordSocketApiClient(
|
||||
DefaultRestClientProvider.Instance,
|
||||
DefaultWebSocketProvider.Instance,
|
||||
DiscordRestConfig.UserAgent);
|
||||
configAction?.Invoke(this);
|
||||
|
||||
LogManager = new LogManager(LogSeverity.Debug);
|
||||
LogManager.Message += async msg => await _logEvent.InvokeAsync(msg).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
internal async Task AcceptAsync(HttpContext context)
|
||||
{
|
||||
WebSocketClient socket;
|
||||
try
|
||||
{
|
||||
socket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false);
|
||||
}
|
||||
catch { return; }
|
||||
|
||||
var _ = Task.Run(async () =>
|
||||
{
|
||||
var conn = new RelayConnection(this, socket, Interlocked.Increment(ref _nextId));
|
||||
await AddConnection(conn).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await conn.RunAsync().ConfigureAwait(false);
|
||||
}
|
||||
finally { await RemoveConnection(conn).ConfigureAwait(false); }
|
||||
});
|
||||
}
|
||||
|
||||
internal void StartAsync()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await _discord.ConnectAsync().ConfigureAwait(false);
|
||||
});
|
||||
}
|
||||
|
||||
internal async Task AddConnection(RelayConnection conn)
|
||||
{
|
||||
await _lock.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
_connections.Add(conn);
|
||||
}
|
||||
finally { _lock.Release(); }
|
||||
}
|
||||
internal async Task RemoveConnection(RelayConnection conn)
|
||||
{
|
||||
await _lock.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
_connections.Remove(conn);
|
||||
}
|
||||
finally { _lock.Release(); }
|
||||
}
|
||||
|
||||
internal int Serialize(object obj, byte[] buffer)
|
||||
{
|
||||
using (var stream = new MemoryStream(buffer))
|
||||
using (var writer = new StreamWriter(stream))
|
||||
{
|
||||
_serializer.Serialize(writer, obj);
|
||||
return (int)stream.Position;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user