Refactor session manager: expose API for plugins

This commit is contained in:
ChronosX88 2020-09-14 20:59:42 +04:00
parent 11379cd6c2
commit 282e14ae96
Signed by: ChronosXYZ
GPG Key ID: 085A69A82C8C511A
10 changed files with 61 additions and 28 deletions

View File

@ -23,6 +23,7 @@ namespace Zirconium.Core
_app.SessionManager.DeleteSession(ID); _app.SessionManager.DeleteSession(ID);
Logging.Log.Info($"Connection {ID} was closed (reason: {e.Reason})"); Logging.Log.Info($"Connection {ID} was closed (reason: {e.Reason})");
// TODO implement closing connection // TODO implement closing connection
} }
protected override void OnError(ErrorEventArgs e) protected override void OnError(ErrorEventArgs e)
@ -37,7 +38,7 @@ namespace Zirconium.Core
if (e.IsText) if (e.IsText)
{ {
var msg = JsonConvert.DeserializeObject<BaseMessage>(e.Data); var msg = JsonConvert.DeserializeObject<BaseMessage>(e.Data);
_app.Router.RouteMessage(_app.SessionManager.GetConnectionInfo(ID), msg); _app.Router.RouteMessage(_app.SessionManager.GetSession(ID), msg);
} }
else else
{ {
@ -69,17 +70,21 @@ namespace Zirconium.Core
protected override void OnOpen() protected override void OnOpen()
{ {
var ip = Context.UserEndPoint.Address; var ip = Context.UserEndPoint.Address;
var connInfo = new ConnectionInfo(); var session = new Session();
connInfo.ClientAddress = ip; session.ClientAddress = ip;
connInfo.ConnectionHandler = this; session.ConnectionHandler = this;
_app.SessionManager.AddSession(ID, connInfo); _app.SessionManager.AddSession(this.ID, session);
Logging.Log.Info($"Connection {ID} was created"); Logging.Log.Info($"Connection {this.ID} was created");
} }
public void SendMessage(string message) public void SendMessage(string message)
{ {
this.Send(message); this.Send(message);
} }
public void CloseConnection() {
this.Sessions.CloseSession(this.ID); // TODO need to clarify if CloseSession also calls OnClose callback
}
} }
} }

View File

@ -2,7 +2,7 @@ using System.Net;
namespace Zirconium.Core.Models namespace Zirconium.Core.Models
{ {
public class ConnectionInfo public class Session
{ {
public string LastTokenHash { get; set; } public string LastTokenHash { get; set; }
public JWTPayload LastTokenPayload { get; set; } public JWTPayload LastTokenPayload { get; set; }

View File

@ -4,7 +4,7 @@ namespace Zirconium.Core.Plugins.Interfaces
{ {
public interface IC2SMessageHandler { public interface IC2SMessageHandler {
string GetHandlingMessageType(); string GetHandlingMessageType();
void HandleMessage(ConnectionInfo connInfo, BaseMessage message); void HandleMessage(Session session, BaseMessage message);
bool IsAuthorizationRequired(); bool IsAuthorizationRequired();
string GetHandlerUniqueID(); string GetHandlerUniqueID();
} }

View File

@ -0,0 +1,12 @@
using Zirconium.Core.Models;
using System.Collections.Immutable;
namespace Zirconium.Core.Plugins.Interfaces
{
public interface IExposedSessionManager
{
Session GetSession(string sessionID);
IImmutableDictionary<string, Session> GetSessions();
void CloseSession(string connID);
}
}

View File

@ -12,9 +12,10 @@ namespace Zirconium.Core.Plugins.Interfaces
string GenerateAuthToken(string entityID, string deviceID, int tokenExpirationMillis); string GenerateAuthToken(string entityID, string deviceID, int tokenExpirationMillis);
string[] GetServerDomains(); string[] GetServerDomains();
string GetServerID(); string GetServerID();
void SendMessage(ConnectionInfo connInfo, BaseMessage message); void SendMessage(Session session, BaseMessage message);
dynamic GetSettings(IPluginAPI plugin); dynamic GetSettings(IPluginAPI plugin);
dynamic GetSettings(string pluginName); dynamic GetSettings(string pluginName);
void ProvideAuth(IAuthProvider provider); void ProvideAuth(IAuthProvider provider);
IExposedSessionManager GetSessionManager();
} }
} }

View File

@ -16,6 +16,10 @@ namespace Zirconium.Core.Plugins
_app = app; _app = app;
} }
public IExposedSessionManager GetSessionManager() {
return _app.SessionManager;
}
public void ProvideAuth(IAuthProvider provider) { public void ProvideAuth(IAuthProvider provider) {
_app.AuthManager.AddAuthProvider(provider); _app.AuthManager.AddAuthProvider(provider);
} }
@ -60,9 +64,9 @@ namespace Zirconium.Core.Plugins
_router.AddCoreEventHandler(handler.GetHandlingEventType(), handler); _router.AddCoreEventHandler(handler.GetHandlingEventType(), handler);
} }
public void SendMessage(ConnectionInfo connInfo, BaseMessage message) public void SendMessage(Session session, BaseMessage message)
{ {
connInfo.ConnectionHandler.SendMessage(JsonConvert.SerializeObject(message)); session.ConnectionHandler.SendMessage(JsonConvert.SerializeObject(message));
} }
public void Unhook(IC2SMessageHandler handler) public void Unhook(IC2SMessageHandler handler)

View File

@ -66,6 +66,7 @@ namespace Zirconium.Core.Plugins
typeof(IPluginHostAPI), typeof(IPluginHostAPI),
typeof(IPluginManager), typeof(IPluginManager),
typeof(IAuthProvider), typeof(IAuthProvider),
typeof(IExposedSessionManager),
typeof(IC2SMessageHandler), typeof(IC2SMessageHandler),
typeof(ICoreEventHandler), typeof(ICoreEventHandler),
typeof(BaseMessage), typeof(BaseMessage),

View File

@ -23,7 +23,7 @@ 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(Session session, BaseMessage message)
{ {
var handlers = _c2sMessageHandlers.GetValueOrDefault(message.MessageType, null); var handlers = _c2sMessageHandlers.GetValueOrDefault(message.MessageType, null);
if (handlers == null) if (handlers == null)
@ -37,7 +37,7 @@ namespace Zirconium.Core
); );
msg.From = _app.Config.ServerID; msg.From = _app.Config.ServerID;
var serializedMsg = JsonConvert.SerializeObject(msg); var serializedMsg = JsonConvert.SerializeObject(msg);
connInfo.ConnectionHandler.SendMessage(serializedMsg); session.ConnectionHandler.SendMessage(serializedMsg);
return; return;
} }
foreach (var h in handlers) foreach (var h in handlers)
@ -49,7 +49,7 @@ namespace Zirconium.Core
{ {
hash = shaM.ComputeHash(message.AuthToken.ToByteArray()).ConvertToString(); hash = shaM.ComputeHash(message.AuthToken.ToByteArray()).ConvertToString();
} }
if (connInfo.LastTokenHash != hash) if (session.LastTokenHash != hash)
{ {
JWTPayload tokenPayload; JWTPayload tokenPayload;
try try
@ -68,19 +68,19 @@ namespace Zirconium.Core
new Dictionary<string, object>() new Dictionary<string, object>()
) )
); );
connInfo.ConnectionHandler.SendMessage(serializedMsg); session.ConnectionHandler.SendMessage(serializedMsg);
return; return;
} }
connInfo.LastTokenHash = hash; session.LastTokenHash = hash;
connInfo.LastTokenPayload = tokenPayload; session.LastTokenPayload = tokenPayload;
} }
} }
Task.Run(() => Task.Run(() =>
{ {
// probably need to wrap whole foreach body, not only HandleMessage call - need to investigate // probably need to wrap whole foreach body, not only HandleMessage call - need to investigate
h.HandleMessage(connInfo, message); h.HandleMessage(session, message);
}); });
} }
} }

View File

@ -1,29 +1,39 @@
using System.Collections.Immutable;
using System.Collections.Generic; using System.Collections.Generic;
using Zirconium.Core.Models; using Zirconium.Core.Models;
using Zirconium.Core.Plugins.Interfaces;
namespace Zirconium.Core namespace Zirconium.Core
{ {
public class SessionManager public class SessionManager: IExposedSessionManager
{ {
private IDictionary<string, ConnectionInfo> _sessions; private IDictionary<string, Session> _sessions;
public SessionManager() public SessionManager()
{ {
_sessions = new Dictionary<string, ConnectionInfo>(); _sessions = new Dictionary<string, Session>();
} }
public void AddSession(string connID, ConnectionInfo connInfo) { public void AddSession(string connID, Session session) {
_sessions[connID] = connInfo; _sessions[connID] = session;
} }
// Get connection info about specified connection ID // Get session using specified ID
// <exception cref="KeyNotFoundException">Throws this exception when connection is not found</exception> // <exception cref="KeyNotFoundException">Throws this exception when connection is not found</exception>
public ConnectionInfo GetConnectionInfo(string connID) { public Session GetSession(string sessionID) {
return _sessions[connID]; return _sessions[sessionID];
} }
public void DeleteSession(string connID) { public void DeleteSession(string connID) {
_sessions.Remove(connID); _sessions.Remove(connID);
} }
public IImmutableDictionary<string, Session> GetSessions() {
return _sessions.ToImmutableDictionary();
}
public void CloseSession(string connID) {
_sessions[connID].ConnectionHandler.CloseConnection();
}
} }
} }

View File

@ -34,14 +34,14 @@ namespace HelloWorldPlugin
public string GetHandlingMessageType() => "test"; public string GetHandlingMessageType() => "test";
public void HandleMessage(ConnectionInfo connInfo, BaseMessage message) public void HandleMessage(Session session, BaseMessage message)
{ {
BaseMessage msg = new BaseMessage(message, true); BaseMessage msg = new BaseMessage(message, true);
msg.Payload["testProp"] = "hello world"; msg.Payload["testProp"] = "hello world";
msg.Ok = true; msg.Ok = true;
msg.From = hostModuleAPI.GetServerID(); msg.From = hostModuleAPI.GetServerID();
string strMsg = JsonConvert.SerializeObject(msg); string strMsg = JsonConvert.SerializeObject(msg);
connInfo.ConnectionHandler.SendMessage(strMsg); session.ConnectionHandler.SendMessage(strMsg);
} }
public bool IsAuthorizationRequired() => false; public bool IsAuthorizationRequired() => false;