mirror of
https://github.com/cadmium-im/zirconium-sharp.git
synced 2024-12-22 17:01:50 +00:00
Implement message/core event routing (with pluggable handlers)
This commit is contained in:
parent
3a54c18af6
commit
fc609869eb
@ -1,5 +1,6 @@
|
||||
using Zirconium.Core.Modules;
|
||||
using Zirconium.Core.Modules.Interfaces;
|
||||
using Zirconium.Core.Logging;
|
||||
|
||||
namespace Zirconium.Core
|
||||
{
|
||||
@ -9,12 +10,15 @@ namespace Zirconium.Core
|
||||
public Router Router { get; }
|
||||
public ModuleManager ModuleManager { get; }
|
||||
public IHostModuleAPI HostModuleAPI { get; }
|
||||
public AuthManager AuthManager { get; }
|
||||
|
||||
public App()
|
||||
{
|
||||
SessionManager = new SessionManager();
|
||||
Router = new Router(this);
|
||||
HostModuleAPI = new HostModuleAPI(Router);
|
||||
AuthManager = new AuthManager(this);
|
||||
Log.Info("Zirconium is initialized successfully");
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ using System;
|
||||
using WebSocketSharp.Server;
|
||||
using WebSocketSharp;
|
||||
using Zirconium.Core.Models;
|
||||
using Zirconium.Utils;
|
||||
|
||||
namespace Zirconium.Core
|
||||
{
|
||||
@ -36,9 +37,14 @@ namespace Zirconium.Core
|
||||
var ip = Context.UserEndPoint.Address;
|
||||
var connInfo = new ConnectionInfo();
|
||||
connInfo.ClientAddress = ip;
|
||||
connInfo.ConnectionHandler = this;
|
||||
_app.SessionManager.AddSession(ID, connInfo);
|
||||
Console.WriteLine($"Connection {ID} was created"); // TODO implement normal logging
|
||||
}
|
||||
|
||||
public void SendMessage(string message) {
|
||||
this.Send(message.ToByteArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ namespace Zirconium.Core
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Hello World! Zirconium");
|
||||
App app = new App();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,5 +7,6 @@ namespace Zirconium.Core.Models
|
||||
public string LastTokenHash { get; set; }
|
||||
public JWTPayload LastTokenPayload { get; set; }
|
||||
public IPAddress ClientAddress { get; set; }
|
||||
public ConnectionHandler ConnectionHandler { get; set; }
|
||||
}
|
||||
}
|
@ -1,7 +1,12 @@
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Zirconium.Core.Models;
|
||||
using Zirconium.Core.Modules.Interfaces;
|
||||
using Zirconium.Utils;
|
||||
using Zirconium.Core.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Zirconium.Core
|
||||
{
|
||||
@ -18,19 +23,99 @@ namespace Zirconium.Core
|
||||
_coreEventsHandlers = new Dictionary<string, List<ICoreEventHandler>>();
|
||||
}
|
||||
|
||||
public void RouteMessage(ConnectionInfo connInfo, BaseMessage message) {
|
||||
public void RouteMessage(ConnectionInfo connInfo, BaseMessage message)
|
||||
{
|
||||
var handlers = _c2sMessageHandlers[message.MessageType];
|
||||
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>()
|
||||
)
|
||||
);
|
||||
connInfo.ConnectionHandler.SendMessage(serializedMsg);
|
||||
return;
|
||||
}
|
||||
foreach (var h in handlers)
|
||||
{
|
||||
if (h.IsAuthorizationRequired())
|
||||
{
|
||||
JWTPayload tokenPayload;
|
||||
try
|
||||
{
|
||||
tokenPayload = _app.AuthManager.ValidateToken(message.AuthToken);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Warning(e.Message);
|
||||
|
||||
var serializedMsg = JsonConvert.SerializeObject(
|
||||
OtherUtils.GenerateProtocolError(
|
||||
message,
|
||||
"unauthorized",
|
||||
"Unauthorized access",
|
||||
new Dictionary<string, object>()
|
||||
)
|
||||
);
|
||||
connInfo.ConnectionHandler.SendMessage(serializedMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (connInfo.LastTokenHash == "" || connInfo.LastTokenHash == null)
|
||||
{
|
||||
string hash;
|
||||
using (SHA512 shaM = new SHA512Managed())
|
||||
{
|
||||
hash = shaM.ComputeHash(message.AuthToken.ToByteArray()).ConvertToString();
|
||||
}
|
||||
connInfo.LastTokenHash = hash;
|
||||
// TODO implement comparing last token hash and if hash isn't changed then check payload
|
||||
// if payload already exists - then skip validating auth token
|
||||
}
|
||||
|
||||
connInfo.LastTokenPayload = tokenPayload;
|
||||
}
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
// probably need to wrap whole foreach body, not only HandleMessage call - need to investigate
|
||||
h.HandleMessage(message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void AddC2SHandler(string messageType, IC2SMessageHandler handler) {
|
||||
if (_c2sMessageHandlers.GetValueOrDefault(messageType, null) == null) {
|
||||
public void RouteCoreEvent(CoreEvent coreEvent)
|
||||
{
|
||||
var handlers = _coreEventsHandlers[coreEvent.Name];
|
||||
if (handlers == null) {
|
||||
Log.Warning($"Drop core event {coreEvent.Name} because server hasn't proper handlers");
|
||||
return;
|
||||
}
|
||||
foreach (var h in handlers) {
|
||||
Task.Run(() =>
|
||||
{
|
||||
h.HandleEvent(coreEvent);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void AddC2SHandler(string messageType, IC2SMessageHandler handler)
|
||||
{
|
||||
if (_c2sMessageHandlers.GetValueOrDefault(messageType, null) == null)
|
||||
{
|
||||
_c2sMessageHandlers[messageType] = new List<IC2SMessageHandler>();
|
||||
}
|
||||
this._c2sMessageHandlers[messageType].Add(handler);
|
||||
}
|
||||
|
||||
public void AddCoreEventHandler(string eventType, ICoreEventHandler handler) {
|
||||
if (_coreEventsHandlers.GetValueOrDefault(eventType, null) == null) {
|
||||
public void AddCoreEventHandler(string eventType, ICoreEventHandler handler)
|
||||
{
|
||||
if (_coreEventsHandlers.GetValueOrDefault(eventType, null) == null)
|
||||
{
|
||||
_coreEventsHandlers[eventType] = new List<ICoreEventHandler>();
|
||||
}
|
||||
this._coreEventsHandlers[eventType].Add(handler);
|
||||
|
21
src/Zirconium/Utils/OtherUtils.cs
Normal file
21
src/Zirconium/Utils/OtherUtils.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
using Zirconium.Core.Models;
|
||||
|
||||
namespace Zirconium.Utils
|
||||
{
|
||||
public static class OtherUtils
|
||||
{
|
||||
public static BaseMessage GenerateProtocolError(BaseMessage parentMessage, string errCode, string errText, IDictionary<string, object> errPayload)
|
||||
{
|
||||
ProtocolError err = new ProtocolError();
|
||||
err.ErrCode = errCode;
|
||||
err.ErrText = errText;
|
||||
err.ErrPayload = errPayload;
|
||||
|
||||
BaseMessage msg = new BaseMessage(parentMessage, true);
|
||||
msg.Ok = false;
|
||||
msg.Payload = err.ToDictionary();
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user