feat: websockets
This commit is contained in:
@@ -19,7 +19,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Ragon.SimpleServer-${{ github.ref }}
|
||||
release_name: Ragon.Relay-${{ github.ref }}
|
||||
prerelease: true
|
||||
|
||||
build:
|
||||
@@ -53,10 +53,10 @@ jobs:
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: |
|
||||
release_name="Ragon.SimpleServer-${{ env.TAG }}-${{ matrix.target }}"
|
||||
release_name="Ragon.Relay-${{ env.TAG }}-${{ matrix.target }}"
|
||||
|
||||
# Build everything
|
||||
dotnet publish Ragon.SimpleServer/Ragon.SimpleServer.csproj -c Release --runtime "${{ matrix.target }}" -p:PublishSingleFile=true -o "$release_name"
|
||||
dotnet publish Ragon.Relay/Ragon.Relay.csproj -c Release --runtime "${{ matrix.target }}" -p:PublishSingleFile=true -o "$release_name"
|
||||
|
||||
# Pack files
|
||||
7z a -tzip "${release_name}.zip" "./${release_name}/*"
|
||||
@@ -69,6 +69,6 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.release.outputs.upload_url }}
|
||||
asset_path: Ragon.SimpleServer-${{ env.TAG }}-${{ matrix.target }}.zip
|
||||
asset_name: Ragon.SimpleServer-${{ env.TAG }}-${{ matrix.target }}.zip
|
||||
asset_path: Ragon.Relay-${{ env.TAG }}-${{ matrix.target }}.zip
|
||||
asset_name: Ragon.Relay-${{ env.TAG }}-${{ matrix.target }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Diagnostics;
|
||||
using NLog;
|
||||
using Ragon.Common;
|
||||
using Ragon.Core.Lobby;
|
||||
using Ragon.Core.Server;
|
||||
using Ragon.Core.Time;
|
||||
using Ragon.Server;
|
||||
using Ragon.Server.ENet;
|
||||
@@ -13,6 +14,7 @@ public class Application : INetworkListener
|
||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly INetworkServer _server;
|
||||
private readonly Thread _dedicatedThread;
|
||||
private readonly Executor _executor;
|
||||
private readonly Configuration _configuration;
|
||||
private readonly HandlerRegistry _handlerRegistry;
|
||||
private readonly ILobby _lobby;
|
||||
@@ -22,6 +24,7 @@ public class Application : INetworkListener
|
||||
public Application(Configuration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
_executor = new Executor();
|
||||
_dedicatedThread = new Thread(Execute);
|
||||
_dedicatedThread.IsBackground = true;
|
||||
_contexts = new Dictionary<ushort, PlayerContext>();
|
||||
@@ -29,20 +32,24 @@ public class Application : INetworkListener
|
||||
_lobby = new LobbyInMemory();
|
||||
_loop = new Loop();
|
||||
|
||||
if (configuration.Socket == "enet")
|
||||
if (configuration.ServerType == "enet")
|
||||
_server = new ENetServer();
|
||||
|
||||
Debug.Assert(_server != null, $"Socket type not supported: {configuration.Socket}. Supported: [enet, websocket]");
|
||||
if (configuration.ServerType == "websocket")
|
||||
_server = new NativeWebSocketServer(_executor);
|
||||
|
||||
Debug.Assert(_server != null, $"Socket type not supported: {configuration.ServerType}. Supported: [enet, websocket]");
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
_executor.Execute();
|
||||
_loop.Tick();
|
||||
_server.Poll();
|
||||
|
||||
Thread.Sleep((int) 1000.0f / _configuration.SendRate);
|
||||
Thread.Sleep((int)1000.0f / _configuration.ServerTickRate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +58,7 @@ public class Application : INetworkListener
|
||||
var networkConfiguration = new NetworkConfiguration()
|
||||
{
|
||||
LimitConnections = _configuration.LimitConnections,
|
||||
Protocol = RagonVersion.Parse(_configuration.Protocol),
|
||||
Protocol = RagonVersion.Parse(_configuration.GameProtocol),
|
||||
Address = "0.0.0.0",
|
||||
Port = _configuration.Port,
|
||||
};
|
||||
@@ -89,6 +96,7 @@ public class Application : INetworkListener
|
||||
|
||||
_lobby.RemoveIfEmpty(room);
|
||||
}
|
||||
|
||||
context.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,11 @@ namespace Ragon.Core;
|
||||
[Serializable]
|
||||
public struct Configuration
|
||||
{
|
||||
public string Key;
|
||||
public string Protocol;
|
||||
public string Socket;
|
||||
public ushort SendRate;
|
||||
public string ServerKey;
|
||||
public string ServerType;
|
||||
public ushort ServerTickRate;
|
||||
public string GameProtocol;
|
||||
public ushort Port;
|
||||
public int SkipTimeout;
|
||||
public int ReconnectTimeout;
|
||||
public int LimitConnections;
|
||||
public int LimitPlayersPerRoom;
|
||||
public int LimitRooms;
|
||||
|
||||
@@ -54,7 +54,7 @@ public class Entity
|
||||
writer.WriteData(ref data);
|
||||
|
||||
var sendData = writer.ToArray();
|
||||
roomPlayer.Connection.ReliableChannel.Send(sendData);
|
||||
roomPlayer.Connection.Reliable.Send(sendData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public class Entity
|
||||
|
||||
var sendData = serializer.ToArray();
|
||||
foreach (var player in room.ReadyPlayersList)
|
||||
player.Connection.ReliableChannel.Send(sendData);
|
||||
player.Connection.Reliable.Send(sendData);
|
||||
}
|
||||
|
||||
public void Destroy(byte[] payload)
|
||||
@@ -91,7 +91,7 @@ public class Entity
|
||||
|
||||
var sendData = serializer.ToArray();
|
||||
foreach (var player in room.ReadyPlayersList)
|
||||
player.Connection.ReliableChannel.Send(sendData);
|
||||
player.Connection.Reliable.Send(sendData);
|
||||
}
|
||||
|
||||
public void ReplicateEvent(
|
||||
@@ -114,7 +114,7 @@ public class Entity
|
||||
serializer.WriteData(ref payload);
|
||||
|
||||
var sendData = serializer.ToArray();
|
||||
targetPlayer.Connection.ReliableChannel.Send(sendData);
|
||||
targetPlayer.Connection.Reliable.Send(sendData);
|
||||
}
|
||||
|
||||
public void ReplicateEvent(
|
||||
@@ -155,7 +155,7 @@ public class Entity
|
||||
{
|
||||
case RagonTarget.Owner:
|
||||
{
|
||||
Owner.Connection.ReliableChannel.Send(sendData);
|
||||
Owner.Connection.Reliable.Send(sendData);
|
||||
break;
|
||||
}
|
||||
case RagonTarget.ExceptOwner:
|
||||
@@ -163,7 +163,7 @@ public class Entity
|
||||
foreach (var roomPlayer in room.ReadyPlayersList)
|
||||
{
|
||||
if (roomPlayer.Connection.Id != Owner.Connection.Id)
|
||||
roomPlayer.Connection.ReliableChannel.Send(sendData);
|
||||
roomPlayer.Connection.Reliable.Send(sendData);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -173,7 +173,7 @@ public class Entity
|
||||
foreach (var roomPlayer in room.ReadyPlayersList)
|
||||
{
|
||||
if (roomPlayer.Connection.Id != caller.Connection.Id)
|
||||
roomPlayer.Connection.ReliableChannel.Send(sendData);
|
||||
roomPlayer.Connection.Reliable.Send(sendData);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -181,7 +181,7 @@ public class Entity
|
||||
case RagonTarget.All:
|
||||
{
|
||||
foreach (var roomPlayer in room.ReadyPlayersList)
|
||||
roomPlayer.Connection.ReliableChannel.Send(sendData);
|
||||
roomPlayer.Connection.Reliable.Send(sendData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ public class Room: IAction
|
||||
|
||||
var sendData = Writer.ToArray();
|
||||
foreach (var roomPlayer in ReadyPlayersList)
|
||||
roomPlayer.Connection.UnreliableChannel.Send(sendData);
|
||||
roomPlayer.Connection.Unreliable.Send(sendData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,6 +161,6 @@ public class Room: IAction
|
||||
public void Broadcast(byte[] data)
|
||||
{
|
||||
foreach (var readyPlayer in ReadyPlayersList)
|
||||
readyPlayer.Connection.ReliableChannel.Send(data);
|
||||
readyPlayer.Connection.Reliable.Send(data);
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ public sealed class AuthorizationHandler: IHandler
|
||||
writer.WriteString(playerName);
|
||||
|
||||
var sendData = writer.ToArray();
|
||||
context.Connection.ReliableChannel.Send(sendData);
|
||||
context.Connection.Reliable.Send(sendData);
|
||||
|
||||
_logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} authorized");
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public sealed class CreateHandler: IHandler
|
||||
writer.WriteString($"Room with id {roomId} already exists");
|
||||
|
||||
var sendData = writer.ToArray();
|
||||
context.Connection.ReliableChannel.Send(sendData);
|
||||
context.Connection.Reliable.Send(sendData);
|
||||
|
||||
_logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} join failed to room {roomId}, room already exist");
|
||||
return;
|
||||
@@ -79,6 +79,6 @@ public sealed class CreateHandler: IHandler
|
||||
writer.WriteString(room.Info.Map);
|
||||
|
||||
var sendData = writer.ToArray();
|
||||
player.Connection.ReliableChannel.Send(sendData);
|
||||
player.Connection.Reliable.Send(sendData);
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ public sealed class JoinHandler : IHandler
|
||||
writer.WriteString(room.Info.Map);
|
||||
|
||||
var sendData = writer.ToArray();
|
||||
player.Connection.ReliableChannel.Send(sendData);
|
||||
player.Connection.Reliable.Send(sendData);
|
||||
}
|
||||
|
||||
private void JoinFailed(LobbyPlayer player, RagonSerializer writer)
|
||||
@@ -57,6 +57,6 @@ public sealed class JoinHandler : IHandler
|
||||
writer.WriteString($"Room not exists");
|
||||
|
||||
var sendData = writer.ToArray();
|
||||
player.Connection.ReliableChannel.Send(sendData);
|
||||
player.Connection.Reliable.Send(sendData);
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,7 @@ public sealed class JoinOrCreateHandler : IHandler
|
||||
writer.WriteString(room.Info.Map);
|
||||
|
||||
var sendData = writer.ToArray();
|
||||
player.Connection.ReliableChannel.Send(sendData);
|
||||
player.Connection.Reliable.Send(sendData);
|
||||
|
||||
_logger.Trace($"Joined to room {room.Id}");
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ public sealed class SceneLoadedHandler : IHandler
|
||||
foreach (var awaiter in room.ReadyPlayersList)
|
||||
{
|
||||
if (awaiter != roomPlayer)
|
||||
awaiter.Connection.ReliableChannel.Send(sendData);
|
||||
awaiter.Connection.Reliable.Send(sendData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +118,6 @@ public sealed class SceneLoadedHandler : IHandler
|
||||
|
||||
var sendData = writer.ToArray();
|
||||
foreach (var player in receviersList)
|
||||
player.Connection.ReliableChannel.Send(sendData);
|
||||
player.Connection.Reliable.Send(sendData);
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ragon.Protocol\Ragon.Protocol.csproj" />
|
||||
<ProjectReference Include="..\Ragon.Server.ENet\Ragon.Server.ENet.csproj" />
|
||||
<ProjectReference Include="..\Ragon.Server.WebSockets\Ragon.Server.WebSockets.csproj" />
|
||||
<ProjectReference Include="..\Ragon.Server.NativeWebSockets\Ragon.Server.NativeWebSockets.csproj" />
|
||||
<ProjectReference Include="..\Ragon.Server\Ragon.Server.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -10,12 +10,17 @@ namespace Ragon.Relay
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var logger = LogManager.GetLogger("Ragon.Relay");
|
||||
|
||||
logger.Info("Relay Application");
|
||||
var configuration = Configuration.Load("config.json");
|
||||
|
||||
var configuration = Configuration.Load("relay.config.json");
|
||||
var relay = new Application(configuration);
|
||||
relay.Start();
|
||||
|
||||
logger.Info("Started");
|
||||
relay.Start();
|
||||
|
||||
Console.ReadKey();
|
||||
|
||||
relay.Stop();
|
||||
logger.Info("Stopped");
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<None Update="NLog.config">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="config.json">
|
||||
<None Update="relay.config.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"key": "defaultkey",
|
||||
"socket": "enet",
|
||||
"protocol": "1.0.0",
|
||||
"sendRate": 50,
|
||||
"port": 4444,
|
||||
"skipTimeout": 60,
|
||||
"reconnectTimeout": 300,
|
||||
"limitConnections": 4095,
|
||||
"limitPlayersPerRoom": 20,
|
||||
"limitRooms": 200
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"serverKey": "defaultkey",
|
||||
"serverType": "websocket",
|
||||
"serverTickRate": 20,
|
||||
"gameProtocol": "1.0.0",
|
||||
"port": 5000,
|
||||
"limitConnections": 4095,
|
||||
"limitPlayersPerRoom": 20,
|
||||
"limitRooms": 200
|
||||
}
|
||||
@@ -5,13 +5,13 @@ namespace Ragon.Server.ENet;
|
||||
public sealed class ENetConnection: INetworkConnection
|
||||
{
|
||||
public ushort Id { get; }
|
||||
public INetworkChannel ReliableChannel { get; private set; }
|
||||
public INetworkChannel UnreliableChannel { get; private set; }
|
||||
public INetworkChannel Reliable { get; private set; }
|
||||
public INetworkChannel Unreliable { get; private set; }
|
||||
|
||||
public ENetConnection(Peer peer)
|
||||
{
|
||||
Id = (ushort) peer.ID;
|
||||
ReliableChannel = new ENetReliableChannel(peer, 0);
|
||||
UnreliableChannel = new ENetUnreliableChannel(peer, 1);
|
||||
Reliable = new ENetReliableChannel(peer, 0);
|
||||
Unreliable = new ENetUnreliableChannel(peer, 1);
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,8 @@ namespace Ragon.Server.ENet
|
||||
{
|
||||
if (!IsValidProtocol(_event.Data))
|
||||
{
|
||||
_logger.Warn("Mismatched protocol, close connection");
|
||||
_logger.Warn($"Mismatched protocol Server: {RagonVersion.Parse(_protocol)} Client: {RagonVersion.Parse(_event.Data)}, close connection");
|
||||
_event.Peer.DisconnectNow(0);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -109,7 +110,6 @@ namespace Ragon.Server.ENet
|
||||
|
||||
private bool IsValidProtocol(uint protocol)
|
||||
{
|
||||
Console.WriteLine($"{protocol} {_protocol}");
|
||||
return protocol == _protocol;
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -7,4 +7,12 @@
|
||||
<RootNamespace>Ragon.WebSockets</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ragon.Server\Ragon.Server.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.Net.WebSockets;
|
||||
using NLog;
|
||||
|
||||
namespace Ragon.Server.NativeWebSockets;
|
||||
|
||||
public sealed class WebSocketConnection : INetworkConnection
|
||||
{
|
||||
private Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
public ushort Id { get; }
|
||||
public INetworkChannel Reliable { get; private set; }
|
||||
public INetworkChannel Unreliable { get; private set; }
|
||||
|
||||
public WebSocket Socket { get; private set; }
|
||||
private WebSocketReliableChannel[] _channels;
|
||||
|
||||
public WebSocketConnection(WebSocket webSocket, ushort peerId)
|
||||
{
|
||||
Id = peerId;
|
||||
Socket = webSocket;
|
||||
|
||||
var reliableChannel = new WebSocketReliableChannel(webSocket);
|
||||
var unreliableChannel = new WebSocketReliableChannel(webSocket);
|
||||
|
||||
_channels = new[] { reliableChannel, unreliableChannel };
|
||||
|
||||
Reliable = reliableChannel;
|
||||
Unreliable = unreliableChannel;
|
||||
}
|
||||
|
||||
public async Task Flush()
|
||||
{
|
||||
foreach (var channel in _channels)
|
||||
{
|
||||
try
|
||||
{
|
||||
await channel.Flush();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.Net.WebSockets;
|
||||
using Ragon.Server;
|
||||
|
||||
namespace Ragon.Server.NativeWebSockets;
|
||||
|
||||
public class WebSocketReliableChannel : INetworkChannel
|
||||
{
|
||||
private Queue<byte[]> _queue;
|
||||
private WebSocket _socket;
|
||||
|
||||
public WebSocketReliableChannel(WebSocket webSocket)
|
||||
{
|
||||
_socket = webSocket;
|
||||
_queue = new Queue<byte[]>(512);
|
||||
}
|
||||
|
||||
public void Send(byte[] data)
|
||||
{
|
||||
_queue.Enqueue(data);
|
||||
}
|
||||
|
||||
public async Task Flush()
|
||||
{
|
||||
while (_queue.TryDequeue(out var sendData) && _socket.State == WebSocketState.Open)
|
||||
await _socket.SendAsync(sendData, WebSocketMessageType.Binary, WebSocketMessageFlags.EndOfMessage, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Net.WebSockets;
|
||||
using NLog;
|
||||
using Ragon.Common;
|
||||
using Ragon.Core.Server;
|
||||
using Ragon.Server;
|
||||
using Ragon.Server.NativeWebSockets;
|
||||
|
||||
namespace Ragon.Core;
|
||||
|
||||
public class NativeWebSocketServer : INetworkServer
|
||||
{
|
||||
private ILogger _logger = LogManager.GetCurrentClassLogger();
|
||||
private INetworkListener _networkListener;
|
||||
private Stack<ushort> _sequencer;
|
||||
private Executor _executor;
|
||||
private HttpListener _httpListener;
|
||||
private WebSocketConnection[] _connections;
|
||||
private ushort _lastPeerId;
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
|
||||
public NativeWebSocketServer(Executor executor)
|
||||
{
|
||||
_sequencer = new Stack<ushort>();
|
||||
_connections = Array.Empty<WebSocketConnection>();
|
||||
_executor = executor;
|
||||
}
|
||||
|
||||
public async Task StartAccept(CancellationToken cancellationToken)
|
||||
{
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
var context = await _httpListener.GetContextAsync();
|
||||
if (!context.Request.IsWebSocketRequest) continue;
|
||||
|
||||
var webSocketContext = await context.AcceptWebSocketAsync(null);
|
||||
var webSocket = webSocketContext.WebSocket;
|
||||
|
||||
var peerId = _sequencer.Pop();
|
||||
var connection = new WebSocketConnection(webSocket, peerId);
|
||||
|
||||
_lastPeerId = peerId;
|
||||
_connections[peerId] = connection;
|
||||
_networkListener.OnConnected(connection);
|
||||
_executor.Run(StartListen(connection, cancellationToken));
|
||||
}
|
||||
}
|
||||
|
||||
async Task StartListen(WebSocketConnection connection, CancellationToken cancellationToken)
|
||||
{
|
||||
var webSocket = connection.Socket;
|
||||
var bytes = new byte[2048];
|
||||
var buffer = new Memory<byte>(bytes);
|
||||
while (
|
||||
webSocket.State == WebSocketState.Open ||
|
||||
!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await webSocket.ReceiveAsync(buffer, cancellationToken);
|
||||
var dataRaw = buffer.Slice(0, result.Count);
|
||||
|
||||
_networkListener.OnData(connection, dataRaw.ToArray());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_sequencer.Push(connection.Id);
|
||||
_networkListener.OnDisconnected(connection);
|
||||
}
|
||||
|
||||
public async void Poll()
|
||||
{
|
||||
foreach (var conn in _connections)
|
||||
{
|
||||
if (conn != null)
|
||||
{
|
||||
await conn.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Start(
|
||||
INetworkListener listener,
|
||||
NetworkConfiguration configuration
|
||||
)
|
||||
{
|
||||
_networkListener = listener;
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
var limit = (ushort) configuration.LimitConnections;
|
||||
for (ushort i = limit; i != 0; i--)
|
||||
_sequencer.Push(i);
|
||||
|
||||
_sequencer.Push(0);
|
||||
|
||||
_connections = new WebSocketConnection[configuration.LimitConnections];
|
||||
|
||||
_httpListener = new HttpListener();
|
||||
_httpListener.Prefixes.Add($"http://127.0.0.1:{configuration.Port}/");
|
||||
_httpListener.Start();
|
||||
|
||||
_executor.Run(StartAccept(_cancellationTokenSource.Token));
|
||||
|
||||
var protocolDecoded = RagonVersion.Parse(configuration.Protocol);
|
||||
_logger.Info($"Network listening on http://*:{configuration.Port}/");
|
||||
_logger.Info($"Protocol: {protocolDecoded}");
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_cancellationTokenSource.Cancel();
|
||||
_httpListener.Stop();
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,6 @@ namespace Ragon.Server;
|
||||
public interface INetworkConnection
|
||||
{
|
||||
public ushort Id { get; }
|
||||
public INetworkChannel ReliableChannel { get; }
|
||||
public INetworkChannel UnreliableChannel { get; }
|
||||
public INetworkChannel Reliable { get; }
|
||||
public INetworkChannel Unreliable { get; }
|
||||
}
|
||||
@@ -1,20 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
using NLog.LayoutRenderers.Wrappers;
|
||||
|
||||
namespace Ragon.Core;
|
||||
namespace Ragon.Core.Server;
|
||||
|
||||
public class Executor: TaskScheduler
|
||||
{
|
||||
private ChannelReader<Task> _reader;
|
||||
private ChannelWriter<Task> _writer;
|
||||
private Queue<Task> _pendingTasks;
|
||||
private TaskFactory _taskFactory;
|
||||
|
||||
public void Run(Task task)
|
||||
{
|
||||
task.Start(this);
|
||||
_taskFactory.StartNew(() => task);
|
||||
}
|
||||
|
||||
public Executor()
|
||||
@@ -23,6 +20,7 @@ public class Executor: TaskScheduler
|
||||
_reader = channel.Reader;
|
||||
_writer = channel.Writer;
|
||||
|
||||
_taskFactory = new TaskFactory(this);
|
||||
_pendingTasks = new Queue<Task>();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon.Server", "Ragon.Serve
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon.Core", "Ragon.Core\Ragon.Core.csproj", "{F4AA86B9-2486-4B53-BA77-43D958A2FDC3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon.Server.WebSockets", "Ragon.Server.WebSockets\Ragon.Server.WebSockets.csproj", "{81050343-A9B8-487B-86C8-7A5B7DD9C39B}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon.Server.NativeWebSockets", "Ragon.Server.NativeWebSockets\Ragon.Server.NativeWebSockets.csproj", "{81050343-A9B8-487B-86C8-7A5B7DD9C39B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon.Server.ENet", "Ragon.Server.ENet\Ragon.Server.ENet.csproj", "{DD79AC4F-9E5C-4938-850E-805D537E68D0}"
|
||||
EndProject
|
||||
|
||||
Reference in New Issue
Block a user