| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 | using InABox.Core;using InABox.WebSocket.Shared;using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.Linq;using System.Net;using System.Runtime.CompilerServices;using System.Text;using System.Threading.Tasks;using WebSocketSharp;using WebSocketSharp.Server;using static InABox.Server.WebSocket.NotifyState;using InternalServer = WebSocketSharp.Server.WebSocketServer;using Logger = InABox.Core.Logger;namespace InABox.Server.WebSocket{    public delegate void PollEvent(Session session);    public class NotifyState    {        public class Session        {            public string ID { get; set; }            public Guid SessionID { get; set; }            public Platform Platform { get; set; }            public Session(string id, Guid sessionID, Platform platform)            {                ID = id;                SessionID = sessionID;                Platform = platform;            }        }        public ConcurrentDictionary<Guid, Session> SessionMap = new();        public event PollEvent? OnPoll;        public void Poll(Session session)        {            OnPoll?.Invoke(session);        }    }    public class NotifyHandler : WebSocketBehavior    {        private NotifyState NotifyState;        public NotifyHandler(NotifyState state)        {            NotifyState = state;        }        protected override void OnOpen()        {            Logger.Send(LogType.Information, "", $"WebSocket client connected");        }        protected override void OnClose(CloseEventArgs e)        {            Logger.Send(LogType.Information, "", $"WebSocket client disconnected");            var sessionID = NotifyState.SessionMap.Where(x => x.Value.ID == ID).FirstOrDefault().Key;            NotifyState.SessionMap.TryRemove(sessionID, out var session);        }        protected override void OnError(WebSocketSharp.ErrorEventArgs e)        {            Logger.Send(LogType.Error, "", $"WebSocket Error: {e.Message}");        }        private void DoInitial(InitialMessage initial)        {            var newSession = new Session(ID, initial.SessionID, initial.Platform);            NotifyState.SessionMap[initial.SessionID] = newSession;            NotifyState.Poll(newSession);        }        protected override void OnMessage(MessageEventArgs e)        {            Logger.Send(LogType.Information, "", "Message received");            var message = SocketMessage.ReadMessage(e.RawData);            if (message is InitialMessage initial)            {                DoInitial(initial);            }        }    }    public class WebSocketServer    {        private InternalServer Server;        private NotifyState NotifyState = new();        public event PollEvent? Poll;        public int Port => Server.Port;        public WebSocketServer(int port)        {            Server = new InternalServer(IPAddress.Any, port);            Server.AddWebSocketService("/notify", NewNotify);            NotifyState.OnPoll += NotifyState_Poll;        }        private void NotifyState_Poll(Session session)        {            Poll?.Invoke(session);        }        public NotifyHandler NewNotify()        {            return new NotifyHandler(NotifyState);        }        public IEnumerable<Guid> GetSessions(Platform platform)        {            return NotifyState.SessionMap.Where(x => x.Value.Platform == platform).Select(x => x.Key);        }        public void Push(Guid sessionID, SocketMessage message)        {            if(NotifyState.SessionMap.TryGetValue(sessionID, out var session))            {                using(var stream = new MemoryStream())                {                    message.Write(stream);                    Server.WebSocketServices["/notify"].Sessions.SendToAsync(stream, (int)stream.Length, session.ID, (succ) => { });                }            }        }        private void PushMessage(SocketMessage message)        {            Server.WebSocketServices["/notify"].Sessions.Broadcast(message.WriteToBytes());        }        private void PushMessage(SocketMessage message, string session)        {            Server.WebSocketServices["/notify"].Sessions.SendTo(message.WriteToBytes(), session);        }        public void Push(Type TNotification, object notification)        {            PushMessage(NotifyMessage.Notify(TNotification, notification));        }        public void Push<TNotification>(TNotification notification)        {            PushMessage(NotifyMessage.Notify(notification));        }        public void Push(Guid sessionID, Type TNotification, object notification)        {            if(NotifyState.SessionMap.TryGetValue(sessionID, out var session))            {                PushMessage(NotifyMessage.Notify(TNotification, notification), session.ID);            }        }        public void Push<TNotification>(Guid sessionID, TNotification notification)        {            if(NotifyState.SessionMap.TryGetValue(sessionID, out var session))            {                PushMessage(NotifyMessage.Notify(notification), session.ID);            }        }        public void Start()        {            Server.Start();        }        public void Stop()        {            Server.Stop();        }    }}
 |