| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 | 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.PushState;using InternalServer = WebSocketSharp.Server.WebSocketServer;using Logger = InABox.Core.Logger;namespace InABox.Server.WebSocket{    public delegate void PollEvent(Session session);    public class PushState    {        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 PushHandler : WebSocketBehavior    {        public PushState State { get; set; }        public PushHandler()        {        }                public PushHandler(PushState state)        {            State = 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 = State.SessionMap.FirstOrDefault(x => x.Value.ID == ID).Key;            State.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);            State.SessionMap[initial.SessionID] = newSession;            State.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 PushState PushState = new();        public event PollEvent? Poll;        public int Port => Server.Port;        public WebSocketServer(int port)        {            Server = new InternalServer(IPAddress.Any, port);            Server.AddWebSocketService<PushHandler>("/push", (push) =>            {                push.State = PushState;            });            PushState.OnPoll += PushState_Poll;        }        private void PushState_Poll(Session session)        {            Poll?.Invoke(session);        }        public PushHandler NewPush()        {            return new PushHandler(PushState);        }        public IEnumerable<Guid> GetSessions(Platform platform)        {            return PushState.SessionMap.Where(x => x.Value.Platform == platform).Select(x => x.Key);        }        public void Push(Guid sessionID, SocketMessage message)        {            if(PushState.SessionMap.TryGetValue(sessionID, out var session))            {                using(var stream = new MemoryStream())                {                    message.Write(stream);                    Server.WebSocketServices["/push"].Sessions.SendToAsync(stream, (int)stream.Length, session.ID, (succ) => { });                }            }        }        private void PushMessage(SocketMessage message)        {            Server.WebSocketServices["/push"].Sessions.Broadcast(message.WriteToBytes());        }        private void PushMessage(SocketMessage message, string session)        {            Server.WebSocketServices["/push"].Sessions.SendTo(message.WriteToBytes(), session);        }        public void Push(Type TPush, object push)        {            PushMessage(InABox.WebSocket.Shared.PushMessage.Push(TPush, push));        }        public void Push<TPush>(TPush push)            where TPush : BaseObject        {            PushMessage(InABox.WebSocket.Shared.PushMessage.Push(push));        }        public void Push(Guid sessionID, Type TPush, object push)        {            if(PushState.SessionMap.TryGetValue(sessionID, out var session))            {                PushMessage(InABox.WebSocket.Shared.PushMessage.Push(TPush, push), session.ID);            }        }        public void Push<TPush>(Guid sessionID, TPush push)            where TPush : BaseObject        {            if(PushState.SessionMap.TryGetValue(sessionID, out var session))            {                PushMessage(InABox.WebSocket.Shared.PushMessage.Push(push), session.ID);            }        }        public void Start()        {            Server.Start();        }        public void Stop()        {            Server.Stop();        }    }}
 |