| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 | 
							- using System.Collections.Concurrent;
 
- using InABox.Core;
 
- namespace InABox.Rpc
 
- {
 
-     public abstract class RpcServerTransport<TConnection> : IPusher, IRpcServerTransport where TConnection : notnull
 
-     {
 
-         public abstract bool IsSecure();
 
-         
 
-         private ConcurrentDictionary<TConnection, RpcServerSession> _sessions = new ConcurrentDictionary<TConnection, RpcServerSession>();
 
-         protected RpcServerSession CreateSession(TConnection connection)
 
-         {
 
-             var result = new RpcServerSession();
 
-             _sessions[connection] = result;
 
-             return result;
 
-         }
 
-         public RpcServerSession? GetSession(TConnection? connection)
 
-         {
 
-             if (connection == null)
 
-                 return null;
 
-             _sessions.TryGetValue(connection, out RpcServerSession? result);
 
-             return result;
 
-         }
 
-         protected RpcServerSession? DeleteSession(TConnection connection)
 
-         {
 
-             _sessions.Remove(connection, out RpcServerSession? session);
 
-             return session;
 
-         }
 
-         
 
-         private Dictionary<string, IRpcCommandHandler> _handlers = new Dictionary<string, IRpcCommandHandler>();
 
-         public void AddHandler<TSender, TCommand, TProperties, TResult>(RpcCommandHandler<TSender, TCommand, TProperties, TResult> handler)
 
-             where TSender : class
 
-             where TCommand : IRpcCommand<TProperties, TResult>
 
-             where TProperties : IRpcCommandParameters, new()
 
-             where TResult : IRpcCommandResult, new()
 
-         {
 
-             _handlers[typeof(TCommand).Name] = handler;
 
-         }
 
-         
 
-         public abstract void Start();
 
-         public abstract void Stop();
 
-         
 
-         public event RpcTransportOpenEvent? OnOpen;
 
-         protected void DoOpen(TConnection connection)
 
-         {
 
-             var session = CreateSession(connection);
 
-             OnOpen?.Invoke(this, new RpcTransportOpenArgs(session) );
 
-         }
 
-         public event RpcTransportCloseEvent? OnClose;
 
-         protected void DoClose(TConnection connection, RpcTransportCloseEventType type)
 
-         {
 
-             var session = DeleteSession(connection);
 
-             OnClose?.Invoke(this, new RpcTransportCloseArgs(session, type));
 
-         }
 
-         public event RpcTransportExceptionEvent? OnException;
 
-         protected void DoException(TConnection? connection, Exception e)
 
-         {
 
-             var session = GetSession(connection);
 
-             OnException?.Invoke(this, new RpcTransportExceptionArgs(session, e));
 
-         }
 
-         public event RpcTransportMessageEvent? BeforeMessage;
 
-         protected void DoBeforeMessage(RpcServerSession? session, RpcMessage? message)
 
-         {
 
-             BeforeMessage?.Invoke(this, new RpcTransportMessageArgs(session,message));
 
-         }
 
-         public event RpcTransportMessageEvent? AfterMessage;
 
-         protected void DoAfterMessage(RpcServerSession? session, RpcMessage? message)
 
-         {
 
-             AfterMessage?.Invoke(this, new RpcTransportMessageArgs(session,message));
 
-         }
 
-         
 
-         /// <summary>
 
-         /// Handle a message from a client.
 
-         /// </summary>
 
-         /// <param name="connection">The client connection.</param>
 
-         /// <param name="message">The message to be handled.</param>
 
-         /// <returns>The response to be sent back to the client.</returns>
 
-         public RpcMessage? DoMessage(TConnection? connection, RpcMessage? message)
 
-         {
 
-             if(message is null)
 
-             {
 
-                 DoException(connection, new Exception("NULL Message Received"));
 
-                 return null;
 
-             }
 
-             var response = new RpcMessage() { Id = message.Id, Command = message.Command };
 
-             try
 
-             {
 
-                 var session = GetSession(connection);
 
-                 DoBeforeMessage(session, message);
 
-                 if (session != null)
 
-                 {
 
-                     response = new RpcMessage() { Id = message.Id, Command = message.Command };
 
-                     if (_handlers.TryGetValue(message.Command, out var command))
 
-                     {
 
-                         try
 
-                         {
 
-                             response.Payload = command.Execute(session, message.Payload);
 
-                         }
 
-                         catch (RpcException err)
 
-                         {
 
-                             response.Error = err.Error;
 
-                         }
 
-                     }
 
-                     else
 
-                     {
 
-                         DoException(connection, new Exception("Command Not Found"));
 
-                         response.Error = RpcError.COMMANDNOTFOUND;
 
-                     }
 
-                     DoAfterMessage(session, response);
 
-                 }
 
-                 else
 
-                 {
 
-                     DoException(connection, new Exception("Session not Found"));
 
-                     response.Error = RpcError.SESSIONNOTFOUND;
 
-                 }
 
-             }
 
-             catch(Exception e)
 
-             {
 
-                 DoException(connection, e);
 
-                 response.Error = RpcError.SERVERERROR;
 
-             }
 
-             return response;
 
-         }
 
-         /// <summary>
 
-         /// Send a message to a particular client connection.
 
-         /// </summary>
 
-         /// <param name="connection">The connection to send to.</param>
 
-         /// <param name="message">The message to send.</param>
 
-         public abstract void Send(TConnection connection, RpcMessage message);
 
-         #region Pusher Stuff
 
-         public void PushToAll<TPush>(TPush push) where TPush : BaseObject
 
-         {
 
-             var message = new RpcMessage(Guid.NewGuid(), "Push", RpcPush.Create(push).WriteBinary(BinarySerializationSettings.Latest));
 
-             foreach (var connection in _sessions.Keys)
 
-             {
 
-                 Send(connection, message);
 
-             }
 
-         }
 
-         public void PushToSession<TPush>(Guid session, TPush push) where TPush : BaseObject
 
-         {
 
-             var message = new RpcMessage(Guid.NewGuid(), "Push", RpcPush.Create(push).WriteBinary(BinarySerializationSettings.Latest));
 
-             var sessionConnection = _sessions.FirstOrDefault(x => x.Value.ID == session).Key;
 
-             if(sessionConnection is not null)
 
-             {
 
-                 Send(sessionConnection, message);
 
-             }
 
-         }
 
-         public void PushToSession(Guid session, Type TPush, BaseObject push)
 
-         {
 
-             var message = new RpcMessage(Guid.NewGuid(), "Push", new RpcPush
 
-             {
 
-                 Object = push,
 
-                 Type = TPush
 
-             }.WriteBinary(BinarySerializationSettings.Latest));
 
-             var sessionConnection = _sessions.FirstOrDefault(x => x.Value.ID == session).Key;
 
-             if (sessionConnection is not null)
 
-             {
 
-                 Send(sessionConnection, message);
 
-             }
 
-         }
 
-         public IEnumerable<Guid> GetUserSessions(Guid user) =>
 
-             _sessions.Values.Where(x => x.UserGuid == user).Select(x => x.ID);
 
-         public IEnumerable<Guid> GetSessions(Platform platform) =>
 
-             _sessions.Values.Where(x => x.Platform == platform).Select(x => x.ID);
 
-         #endregion
 
-     }
 
- }
 
 
  |