mirror of
https://github.com/cadmium-im/zirconium-sharp.git
synced 2024-09-07 22:16:17 +00:00
Implement running websocket server and add handling messages in ConnectionHandler
This commit is contained in:
parent
f34b4e3596
commit
394f9ab908
4
.vscode/launch.json
vendored
4
.vscode/launch.json
vendored
@ -11,11 +11,11 @@
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceFolder}/src/Zirconium/bin/Debug/netcoreapp3.1/Zirconium.dll",
|
||||
"args": [],
|
||||
"args": ["--config", "${workspaceFolder}/.config.toml"],
|
||||
"cwd": "${workspaceFolder}/src/Zirconium",
|
||||
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
|
||||
"console": "internalConsole",
|
||||
"stopAtEntry": false
|
||||
"stopAtEntry": false,
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Attach",
|
||||
|
@ -8,4 +8,10 @@ ServerDomains = []
|
||||
PluginsDirPath = ""
|
||||
|
||||
# ID of this server in terms of Cadmium federation network. WARNING! This ID should be maximally unique.
|
||||
ServerID = ""
|
||||
ServerID = ""
|
||||
|
||||
# Websocket server settings
|
||||
[Websocket]
|
||||
Host = "localhost"
|
||||
Port = 8000
|
||||
Endpoint = ""
|
@ -1,6 +1,7 @@
|
||||
using Zirconium.Core.Modules;
|
||||
using Zirconium.Core.Modules.Interfaces;
|
||||
using Zirconium.Core.Logging;
|
||||
using WebSocketSharp.Server;
|
||||
|
||||
namespace Zirconium.Core
|
||||
{
|
||||
@ -12,15 +13,28 @@ namespace Zirconium.Core
|
||||
public ModuleManager ModuleManager { get; }
|
||||
public IHostModuleAPI HostModuleAPI { get; }
|
||||
public AuthManager AuthManager { get; }
|
||||
private WebSocketServer _websocketServer;
|
||||
|
||||
public App(Config config)
|
||||
{
|
||||
Config = config;
|
||||
_websocketServer = new WebSocketServer($"ws://{config.Websocket.Host}:{config.Websocket.Port}");
|
||||
_websocketServer.AddWebSocketService<ConnectionHandler>(config.Websocket.Endpoint, () => new ConnectionHandler(this));
|
||||
SessionManager = new SessionManager();
|
||||
Router = new Router(this);
|
||||
HostModuleAPI = new HostModuleAPI(this, Router);
|
||||
AuthManager = new AuthManager(this);
|
||||
Log.Info("Zirconium is initialized successfully");
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
_websocketServer.Start();
|
||||
}
|
||||
|
||||
public void Destroy() {
|
||||
Log.Info("Shutting down Zirconium...");
|
||||
_websocketServer.Stop();
|
||||
}
|
||||
}
|
||||
}
|
@ -3,15 +3,25 @@ namespace Zirconium.Core
|
||||
public class Config
|
||||
{
|
||||
// A list of enabled plugins (or extensions) in server
|
||||
public string[] EnabledPlugins {get; set;}
|
||||
public string[] EnabledPlugins { get; set; }
|
||||
|
||||
// Server domain names (e.g. example.com)
|
||||
public string[] ServerDomains {get; set;}
|
||||
public string[] ServerDomains { get; set; }
|
||||
|
||||
// Path to directory with plugin assemblies
|
||||
public string PluginsDirPath {get; set;}
|
||||
public string PluginsDirPath { get; set; }
|
||||
|
||||
// ID of this server in terms of Cadmium federation network
|
||||
public string ServerID {get; set;}
|
||||
public string ServerID { get; set; }
|
||||
|
||||
// Websocket server settings
|
||||
public Websocket Websocket { get; set; }
|
||||
}
|
||||
|
||||
public class Websocket
|
||||
{
|
||||
public string Host { get; set; }
|
||||
public int Port { get; set; }
|
||||
public string Endpoint { get; set; }
|
||||
}
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using WebSocketSharp.Server;
|
||||
using WebSocketSharp;
|
||||
using Zirconium.Core.Models;
|
||||
using Zirconium.Utils;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Zirconium.Core
|
||||
{
|
||||
@ -19,18 +21,49 @@ namespace Zirconium.Core
|
||||
protected override void OnClose(CloseEventArgs e)
|
||||
{
|
||||
_app.SessionManager.DeleteSession(ID);
|
||||
Console.WriteLine($"Connection {ID} was closed (reason: {e.Reason})"); // TODO implement normal logging
|
||||
Logging.Log.Info($"Connection {ID} was closed (reason: {e.Reason})");
|
||||
// TODO implement closing connection
|
||||
}
|
||||
|
||||
protected override void OnError(ErrorEventArgs e)
|
||||
{
|
||||
Console.WriteLine($"Error occurred: {e.Exception}"); // TODO implement normal logging
|
||||
Logging.Log.Error($"Error occurred: {e.Exception}");
|
||||
}
|
||||
|
||||
protected override void OnMessage(MessageEventArgs e)
|
||||
{
|
||||
// TODO implement message parsing and routing
|
||||
try
|
||||
{
|
||||
if (e.IsText)
|
||||
{
|
||||
var msg = JsonConvert.DeserializeObject<BaseMessage>(e.Data);
|
||||
_app.Router.RouteMessage(_app.SessionManager.GetConnectionInfo(ID), msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
var errMsg = OtherUtils.GenerateProtocolError(
|
||||
null,
|
||||
"parseError",
|
||||
$"Server cannot parse this message yet because it is not JSON",
|
||||
new Dictionary<string, object>()
|
||||
);
|
||||
errMsg.From = _app.Config.ServerID;
|
||||
var msgStr = JsonConvert.SerializeObject(errMsg);
|
||||
this.SendMessage(msgStr);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var errMsg = OtherUtils.GenerateProtocolError(
|
||||
null,
|
||||
"parseError",
|
||||
$"Server cannot parse this message! {ex.Message}",
|
||||
new Dictionary<string, object>()
|
||||
);
|
||||
errMsg.From = _app.Config.ServerID;
|
||||
var msgStr = JsonConvert.SerializeObject(errMsg);
|
||||
this.SendMessage(msgStr);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnOpen()
|
||||
@ -40,12 +73,12 @@ namespace Zirconium.Core
|
||||
connInfo.ClientAddress = ip;
|
||||
connInfo.ConnectionHandler = this;
|
||||
_app.SessionManager.AddSession(ID, connInfo);
|
||||
Console.WriteLine($"Connection {ID} was created"); // TODO implement normal logging
|
||||
Logging.Log.Info($"Connection {ID} was created");
|
||||
}
|
||||
|
||||
public Task SendMessage(string message) {
|
||||
this.Send(message.ToByteArray());
|
||||
return Task.CompletedTask;
|
||||
public void SendMessage(string message)
|
||||
{
|
||||
this.Send(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ namespace Zirconium.Core
|
||||
}
|
||||
class Program
|
||||
{
|
||||
private static bool keepRunning = true;
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
string configPath = null;
|
||||
@ -38,6 +40,14 @@ namespace Zirconium.Core
|
||||
Log.Fatal($"Error occured when parsing config - {e.Message}");
|
||||
}
|
||||
App app = new App(config);
|
||||
app.Run();
|
||||
Console.CancelKeyPress += delegate (object sender, ConsoleCancelEventArgs e)
|
||||
{
|
||||
e.Cancel = true;
|
||||
app.Destroy();
|
||||
keepRunning = false;
|
||||
};
|
||||
while(keepRunning) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,16 +11,16 @@ namespace Zirconium.Core.Models
|
||||
[JsonProperty("type")]
|
||||
public string MessageType { get; set; }
|
||||
|
||||
[JsonProperty("from")]
|
||||
[JsonProperty("from", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string From { get; set; }
|
||||
|
||||
[JsonProperty("to")]
|
||||
[JsonProperty("to", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string To { get; set; }
|
||||
|
||||
[JsonProperty("ok")]
|
||||
public bool Ok { get; set; }
|
||||
|
||||
[JsonProperty("authToken")]
|
||||
[JsonProperty("authToken", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string AuthToken { get; set; }
|
||||
|
||||
[JsonProperty("payload")]
|
||||
@ -30,22 +30,25 @@ namespace Zirconium.Core.Models
|
||||
|
||||
public BaseMessage(BaseMessage message, bool reply)
|
||||
{
|
||||
ID = message.ID;
|
||||
MessageType = message.MessageType;
|
||||
if (reply)
|
||||
if (message != null)
|
||||
{
|
||||
From = message.To;
|
||||
To = message.From;
|
||||
}
|
||||
else
|
||||
{
|
||||
From = message.From;
|
||||
To = message.To;
|
||||
}
|
||||
ID = message.ID;
|
||||
MessageType = message.MessageType;
|
||||
if (reply)
|
||||
{
|
||||
From = message.To;
|
||||
To = message.From;
|
||||
}
|
||||
else
|
||||
{
|
||||
From = message.From;
|
||||
To = message.To;
|
||||
}
|
||||
|
||||
Ok = message.Ok;
|
||||
AuthToken = message.AuthToken;
|
||||
Payload = message.Payload;
|
||||
Ok = message.Ok;
|
||||
AuthToken = message.AuthToken;
|
||||
Payload = message.Payload;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -25,18 +25,18 @@ namespace Zirconium.Core
|
||||
|
||||
public void RouteMessage(ConnectionInfo connInfo, BaseMessage message)
|
||||
{
|
||||
var handlers = _c2sMessageHandlers[message.MessageType];
|
||||
var handlers = _c2sMessageHandlers.GetValueOrDefault(message.MessageType, null);
|
||||
if (handlers == null)
|
||||
{
|
||||
Log.Warning($"Drop message with type {message.MessageType} because server hasn't proper handlers");
|
||||
var serializedMsg = JsonConvert.SerializeObject(
|
||||
OtherUtils.GenerateProtocolError(
|
||||
message,
|
||||
"unhandled",
|
||||
$"Server doesn't implement message type {message.MessageType}",
|
||||
new Dictionary<string, object>()
|
||||
)
|
||||
Log.Warning($"Drop message with type \"{message.MessageType}\" because server hasn't proper handlers");
|
||||
var msg = OtherUtils.GenerateProtocolError(
|
||||
message,
|
||||
"unhandled",
|
||||
$"Server doesn't implement message type \"{message.MessageType}\"",
|
||||
new Dictionary<string, object>()
|
||||
);
|
||||
msg.From = _app.Config.ServerID;
|
||||
var serializedMsg = JsonConvert.SerializeObject(msg);
|
||||
connInfo.ConnectionHandler.SendMessage(serializedMsg);
|
||||
return;
|
||||
}
|
||||
@ -113,7 +113,8 @@ namespace Zirconium.Core
|
||||
|
||||
public void RemoveC2SHandler(string messageType, IC2SMessageHandler handler)
|
||||
{
|
||||
if (!this._c2sMessageHandlers[messageType].Remove(handler)) {
|
||||
if (!this._c2sMessageHandlers[messageType].Remove(handler))
|
||||
{
|
||||
Log.Warning("attempt to remove c2s handler which doesn't exist in router");
|
||||
}
|
||||
}
|
||||
@ -129,7 +130,8 @@ namespace Zirconium.Core
|
||||
|
||||
public void RemoveCoreEventHandler(string eventType, ICoreEventHandler handler)
|
||||
{
|
||||
if (!this._coreEventsHandlers[eventType].Remove(handler)) {
|
||||
if (!this._coreEventsHandlers[eventType].Remove(handler))
|
||||
{
|
||||
Log.Warning("attempt to remove core handler which doesn't exist in router");
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Zirconium.Core.Models;
|
||||
|
||||
@ -13,6 +14,9 @@ namespace Zirconium.Utils
|
||||
err.ErrPayload = errPayload;
|
||||
|
||||
BaseMessage msg = new BaseMessage(parentMessage, true);
|
||||
if (parentMessage == null) {
|
||||
msg.ID = Guid.NewGuid().ToString();
|
||||
}
|
||||
msg.Ok = false;
|
||||
msg.Payload = err.ToDictionary();
|
||||
return msg;
|
||||
|
Loading…
Reference in New Issue
Block a user