Added /shutdown and /restart commands for server maintenance.
This commit is contained in:
parent
e6dffe06e6
commit
6f50ec66a9
3 changed files with 49 additions and 12 deletions
|
@ -20,6 +20,8 @@ namespace SharpChat {
|
||||||
public DateTimeOffset LastPing { get; set; } = DateTimeOffset.MinValue;
|
public DateTimeOffset LastPing { get; set; } = DateTimeOffset.MinValue;
|
||||||
public ChatUser User { get; set; }
|
public ChatUser User { get; set; }
|
||||||
|
|
||||||
|
private static int CloseCode { get; set; } = 1000;
|
||||||
|
|
||||||
public string TargetName => @"@log";
|
public string TargetName => @"@log";
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,8 +29,8 @@ namespace SharpChat {
|
||||||
|
|
||||||
public IPAddress RemoteAddress {
|
public IPAddress RemoteAddress {
|
||||||
get {
|
get {
|
||||||
if (_RemoteAddress == null) {
|
if(_RemoteAddress == null) {
|
||||||
if ((Connection.ConnectionInfo.ClientIpAddress == @"127.0.0.1" || Connection.ConnectionInfo.ClientIpAddress == @"::1")
|
if((Connection.ConnectionInfo.ClientIpAddress == @"127.0.0.1" || Connection.ConnectionInfo.ClientIpAddress == @"::1")
|
||||||
&& Connection.ConnectionInfo.Headers.ContainsKey(@"X-Real-IP"))
|
&& Connection.ConnectionInfo.Headers.ContainsKey(@"X-Real-IP"))
|
||||||
_RemoteAddress = IPAddress.Parse(Connection.ConnectionInfo.Headers[@"X-Real-IP"]);
|
_RemoteAddress = IPAddress.Parse(Connection.ConnectionInfo.Headers[@"X-Real-IP"]);
|
||||||
else
|
else
|
||||||
|
@ -52,14 +54,14 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Send(IServerPacket packet) {
|
public void Send(IServerPacket packet) {
|
||||||
if (!Connection.IsAvailable)
|
if(!Connection.IsAvailable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IEnumerable<string> data = packet.Pack();
|
IEnumerable<string> data = packet.Pack();
|
||||||
|
|
||||||
if (data != null)
|
if(data != null)
|
||||||
foreach (string line in data)
|
foreach(string line in data)
|
||||||
if (!string.IsNullOrWhiteSpace(line))
|
if(!string.IsNullOrWhiteSpace(line))
|
||||||
Connection.Send(line);
|
Connection.Send(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +71,9 @@ namespace SharpChat {
|
||||||
public bool HasTimedOut
|
public bool HasTimedOut
|
||||||
=> DateTimeOffset.Now - LastPing > SessionTimeOut;
|
=> DateTimeOffset.Now - LastPing > SessionTimeOut;
|
||||||
|
|
||||||
|
public void PrepareForRestart()
|
||||||
|
=> CloseCode = 1012;
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
=> Dispose(true);
|
=> Dispose(true);
|
||||||
|
|
||||||
|
@ -76,13 +81,13 @@ namespace SharpChat {
|
||||||
=> Dispose(false);
|
=> Dispose(false);
|
||||||
|
|
||||||
private void Dispose(bool disposing) {
|
private void Dispose(bool disposing) {
|
||||||
if (IsDisposed)
|
if(IsDisposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
Connection.Close();
|
Connection.Close(CloseCode);
|
||||||
|
|
||||||
if (disposing)
|
if(disposing)
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace SharpChat {
|
||||||
Database.ReadConfig();
|
Database.ReadConfig();
|
||||||
|
|
||||||
using ManualResetEvent mre = new ManualResetEvent(false);
|
using ManualResetEvent mre = new ManualResetEvent(false);
|
||||||
using SockChatServer scs = new SockChatServer(PORT);
|
using SockChatServer scs = new SockChatServer(mre, PORT);
|
||||||
Console.CancelKeyPress += (s, e) => { e.Cancel = true; mre.Set(); };
|
Console.CancelKeyPress += (s, e) => { e.Cancel = true; mre.Set(); };
|
||||||
mre.WaitOne();
|
mre.WaitOne();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public class SockChatServer : IDisposable {
|
public class SockChatServer : IDisposable {
|
||||||
|
@ -58,9 +59,14 @@ namespace SharpChat {
|
||||||
HttpClient.DefaultRequestHeaders.UserAgent.ParseAdd(@"SharpChat");
|
HttpClient.DefaultRequestHeaders.UserAgent.ParseAdd(@"SharpChat");
|
||||||
}
|
}
|
||||||
|
|
||||||
public SockChatServer(ushort port) {
|
private ManualResetEvent Shutdown { get; }
|
||||||
|
private bool IsShuttingDown = false;
|
||||||
|
|
||||||
|
public SockChatServer(ManualResetEvent mre, ushort port) {
|
||||||
Logger.Write("Starting Sock Chat server...");
|
Logger.Write("Starting Sock Chat server...");
|
||||||
|
|
||||||
|
Shutdown = mre ?? throw new ArgumentNullException(nameof(mre));
|
||||||
|
|
||||||
Context = new ChatContext(this);
|
Context = new ChatContext(this);
|
||||||
|
|
||||||
Context.Channels.Add(new ChatChannel(@"Lounge"));
|
Context.Channels.Add(new ChatChannel(@"Lounge"));
|
||||||
|
@ -75,6 +81,11 @@ namespace SharpChat {
|
||||||
Server = new SharpChatWebSocketServer($@"ws://0.0.0.0:{port}");
|
Server = new SharpChatWebSocketServer($@"ws://0.0.0.0:{port}");
|
||||||
|
|
||||||
Server.Start(sock => {
|
Server.Start(sock => {
|
||||||
|
if(IsShuttingDown || IsDisposed) {
|
||||||
|
sock.Close(1013);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sock.OnOpen = () => OnOpen(sock);
|
sock.OnOpen = () => OnOpen(sock);
|
||||||
sock.OnClose = () => OnClose(sock);
|
sock.OnClose = () => OnClose(sock);
|
||||||
sock.OnError = err => OnError(sock, err);
|
sock.OnError = err => OnError(sock, err);
|
||||||
|
@ -821,6 +832,25 @@ namespace SharpChat {
|
||||||
user.Send(new LegacyCommandResponse(LCR.IP_ADDRESS, false, ipUser.Username, ip));
|
user.Send(new LegacyCommandResponse(LCR.IP_ADDRESS, false, ipUser.Username, ip));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case @"shutdown":
|
||||||
|
case @"restart":
|
||||||
|
if(user.UserId != 1) {
|
||||||
|
user.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $@"/{commandName}"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(IsShuttingDown)
|
||||||
|
break;
|
||||||
|
IsShuttingDown = true;
|
||||||
|
|
||||||
|
if(commandName == @"restart")
|
||||||
|
lock(SessionsLock)
|
||||||
|
Sessions.ForEach(s => s.PrepareForRestart());
|
||||||
|
|
||||||
|
Context.Update();
|
||||||
|
Shutdown.Set();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
user.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_FOUND, true, commandName));
|
user.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_FOUND, true, commandName));
|
||||||
break;
|
break;
|
||||||
|
@ -840,7 +870,9 @@ namespace SharpChat {
|
||||||
return;
|
return;
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
|
|
||||||
Sessions?.Clear();
|
lock(SessionsLock)
|
||||||
|
Sessions.ForEach(s => s.Dispose());
|
||||||
|
|
||||||
Server?.Dispose();
|
Server?.Dispose();
|
||||||
Context?.Dispose();
|
Context?.Dispose();
|
||||||
HttpClient?.Dispose();
|
HttpClient?.Dispose();
|
||||||
|
|
Loading…
Reference in a new issue