mirror of
https://github.com/cadmium-im/zirconium-sharp.git
synced 2024-11-09 20:21:04 +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;
|
||||||
using Zirconium.Core.Modules.Interfaces;
|
using Zirconium.Core.Modules.Interfaces;
|
||||||
|
using Zirconium.Core.Logging;
|
||||||
|
|
||||||
namespace Zirconium.Core
|
namespace Zirconium.Core
|
||||||
{
|
{
|
||||||
@ -9,12 +10,15 @@ namespace Zirconium.Core
|
|||||||
public Router Router { get; }
|
public Router Router { get; }
|
||||||
public ModuleManager ModuleManager { get; }
|
public ModuleManager ModuleManager { get; }
|
||||||
public IHostModuleAPI HostModuleAPI { get; }
|
public IHostModuleAPI HostModuleAPI { get; }
|
||||||
|
public AuthManager AuthManager { get; }
|
||||||
|
|
||||||
public App()
|
public App()
|
||||||
{
|
{
|
||||||
SessionManager = new SessionManager();
|
SessionManager = new SessionManager();
|
||||||
Router = new Router(this);
|
Router = new Router(this);
|
||||||
HostModuleAPI = new HostModuleAPI(Router);
|
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.Server;
|
||||||
using WebSocketSharp;
|
using WebSocketSharp;
|
||||||
using Zirconium.Core.Models;
|
using Zirconium.Core.Models;
|
||||||
|
using Zirconium.Utils;
|
||||||
|
|
||||||
namespace Zirconium.Core
|
namespace Zirconium.Core
|
||||||
{
|
{
|
||||||
@ -36,9 +37,14 @@ namespace Zirconium.Core
|
|||||||
var ip = Context.UserEndPoint.Address;
|
var ip = Context.UserEndPoint.Address;
|
||||||
var connInfo = new ConnectionInfo();
|
var connInfo = new ConnectionInfo();
|
||||||
connInfo.ClientAddress = ip;
|
connInfo.ClientAddress = ip;
|
||||||
|
connInfo.ConnectionHandler = this;
|
||||||
_app.SessionManager.AddSession(ID, connInfo);
|
_app.SessionManager.AddSession(ID, connInfo);
|
||||||
Console.WriteLine($"Connection {ID} was created"); // TODO implement normal logging
|
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)
|
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 string LastTokenHash { get; set; }
|
||||||
public JWTPayload LastTokenPayload { get; set; }
|
public JWTPayload LastTokenPayload { get; set; }
|
||||||
public IPAddress ClientAddress { 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 System.Collections.Generic;
|
||||||
using Zirconium.Core.Models;
|
using Zirconium.Core.Models;
|
||||||
using Zirconium.Core.Modules.Interfaces;
|
using Zirconium.Core.Modules.Interfaces;
|
||||||
using Zirconium.Utils;
|
using Zirconium.Utils;
|
||||||
|
using Zirconium.Core.Logging;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace Zirconium.Core
|
namespace Zirconium.Core
|
||||||
{
|
{
|
||||||
@ -18,19 +23,99 @@ namespace Zirconium.Core
|
|||||||
_coreEventsHandlers = new Dictionary<string, List<ICoreEventHandler>>();
|
_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddC2SHandler(string messageType, IC2SMessageHandler handler) {
|
if (connInfo.LastTokenHash == "" || connInfo.LastTokenHash == null)
|
||||||
if (_c2sMessageHandlers.GetValueOrDefault(messageType, null) == 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 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>();
|
_c2sMessageHandlers[messageType] = new List<IC2SMessageHandler>();
|
||||||
}
|
}
|
||||||
this._c2sMessageHandlers[messageType].Add(handler);
|
this._c2sMessageHandlers[messageType].Add(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCoreEventHandler(string eventType, ICoreEventHandler handler) {
|
public void AddCoreEventHandler(string eventType, ICoreEventHandler handler)
|
||||||
if (_coreEventsHandlers.GetValueOrDefault(eventType, null) == null) {
|
{
|
||||||
|
if (_coreEventsHandlers.GetValueOrDefault(eventType, null) == null)
|
||||||
|
{
|
||||||
_coreEventsHandlers[eventType] = new List<ICoreEventHandler>();
|
_coreEventsHandlers[eventType] = new List<ICoreEventHandler>();
|
||||||
}
|
}
|
||||||
this._coreEventsHandlers[eventType].Add(handler);
|
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