1
0
Fork 0
Nibriboard/Nibriboard/NibriboardServer.cs

130 lines
3.7 KiB
C#
Raw Normal View History

using System;
2017-01-21 18:13:42 +00:00
using System.Threading.Tasks;
2017-07-20 12:15:11 +00:00
using System.Threading;
using IotWeb.Server;
using IotWeb.Common.Http;
using Nibriboard.RippleSpace;
2017-01-21 18:13:42 +00:00
using Nibriboard.Client;
2017-07-20 12:15:11 +00:00
using System.Net.Sockets;
using System.Net;
using System.IO;
namespace Nibriboard
{
/// <summary>
/// The main Nibriboard server.
/// This class manages not only the connected clients, but also holds the master reference to the <see cref="Nibriboard.RippleSpace.RippleSpaceManager"/>.
/// </summary>
public class NibriboardServer
{
2017-07-20 12:15:11 +00:00
private TcpListener commandServer;
private HttpServer httpServer;
2017-01-21 18:13:42 +00:00
private ClientSettings clientSettings;
2017-07-23 18:36:15 +00:00
private RippleSpaceManager planeManager = new RippleSpaceManager() { SourceFilename = "./test.ripplespace.zip" };
private readonly CancellationTokenSource clientManagerCanceller = new CancellationTokenSource();
private NibriClientManager clientManager;
2017-07-20 12:15:11 +00:00
public readonly int CommandPort = 31587;
public readonly int Port = 31586;
public NibriboardServer(int inPort = 31586)
{
Port = inPort;
2017-01-21 18:13:42 +00:00
clientSettings = new ClientSettings() {
SecureWebSocket = false,
WebSocketHost = "192.168.0.56",
WebSocketPort = Port,
WebSocketPath = "/RipplespaceLink"
2017-01-21 18:13:42 +00:00
};
// HTTP Server setup
httpServer = new HttpServer(Port);
httpServer.AddHttpRequestHandler(
2017-01-10 19:51:49 +00:00
"/",
new HttpEmbeddedFileHandler("Nibriboard.ClientFiles")
/*new HttpResourceHandler(
2017-01-10 19:51:49 +00:00
Assembly.GetExecutingAssembly(),
"ClientFiles",
"index.html"
)*/
);
2017-01-21 18:13:42 +00:00
httpServer.AddHttpRequestHandler(
"/Settings.json",
new HttpClientSettingsHandler(clientSettings)
);
// Websocket setup
clientManager = new NibriClientManager(
clientSettings,
planeManager,
clientManagerCanceller.Token
);
httpServer.AddWebSocketRequestHandler(
clientSettings.WebSocketPath,
clientManager
);
}
public async Task Start()
{
2017-01-10 19:51:49 +00:00
httpServer.Start();
Log.WriteLine("[NibriboardServer] Started on port {0}", Port);
await planeManager.StartMaintenanceMonkey();
}
2017-07-20 12:15:11 +00:00
/// <summary>
/// Starts the command listener.
/// The command listener is a light tcp-based command console that allows control
/// of the Nibriboard server, since C# doesn't currently have support for signal handling.
/// It listeners on [::1] _only_, to avoid security issues.
/// In the future, a simple secret might be required to use it to aid security further.
/// </summary>
public async Task StartCommandListener()
{
commandServer = new TcpListener(IPAddress.IPv6Loopback, CommandPort);
commandServer.Start();
Log.WriteLine("[CommandConsole] Listening on {0}.", new IPEndPoint(IPAddress.IPv6Loopback, CommandPort));
while(true)
{
TcpClient nextClient = await commandServer.AcceptTcpClientAsync();
StreamReader source = new StreamReader(nextClient.GetStream());
StreamWriter destination = new StreamWriter(nextClient.GetStream()) { AutoFlush = true };
string rawCommand = await source.ReadLineAsync();
string[] commandParts = rawCommand.Split(" \t".ToCharArray());
2017-07-23 18:43:33 +00:00
Log.WriteLine("[CommandConsole] Client executing {0}", rawCommand);
2017-07-20 12:15:11 +00:00
try
{
switch(commandParts[0].Trim())
{
case "help":
await destination.WriteLineAsync("NibriboardServer Command Console");
await destination.WriteLineAsync("================================");
await destination.WriteLineAsync("Available commands:");
await destination.WriteLineAsync(" help Show this message");
await destination.WriteLineAsync(" save Save the ripplespace to disk");
break;
case "save":
await planeManager.Save();
break;
}
}
catch(Exception error)
{
await destination.WriteLineAsync(error.ToString());
}
nextClient.Close();
}
}
}
}