/// <summary>
        /// Uses websockets with service provider
        /// </summary>
        public static IHorseServer UseWebSockets(this IHorseServer server, IServiceProvider provider)
        {
            ModelWsConnectionHandler bus = (ModelWsConnectionHandler)provider.GetService(typeof(IWebSocketServerBus));

            bus.ServiceProvider = provider;
            return(server);
        }
예제 #2
0
        /// <summary>
        /// Uses HMQ Protocol and accepts TCP connections.
        /// </summary>
        public static IHorseServer UseHmq(this IHorseServer server, IProtocolConnectionHandler <HorseServerSocket, HorseMessage> handler)
        {
            HorseMqProtocol protocol = new HorseMqProtocol(server, handler);

            server.UseProtocol(protocol);
            return(server);
        }
예제 #3
0
 /// <summary>
 /// Creates new server-side websocket client
 /// </summary>
 public WsServerSocket(IHorseServer server, IConnectionInfo info)
     : base(info)
 {
     Client = info.Client;
     Server = server;
     Info   = info;
 }
예제 #4
0
        /// <summary>
        /// Called when a new message received from the client
        /// </summary>
        public Task Received(IHorseServer server, IConnectionInfo info, HorseServerSocket client, HorseMessage message)
        {
            MqClient mc = (MqClient)client;

            //if client sends anonymous messages and server needs message id, generate new
            if (string.IsNullOrEmpty(message.MessageId))
            {
                //anonymous messages can't be responsed, do not wait response
                if (message.WaitResponse)
                {
                    message.WaitResponse = false;
                }

                //if server want to use message id anyway, generate new.
                if (_server.Options.UseMessageId)
                {
                    message.SetMessageId(_server.MessageIdGenerator.Create());
                }
            }

            //if message does not have a source information, source will be set to sender's unique id
            if (string.IsNullOrEmpty(message.Source))
            {
                message.SetSource(mc.UniqueId);
            }

            //if client sending messages like someone another, kick him
            else if (message.Source != mc.UniqueId)
            {
                client.Disconnect();
                return(Task.CompletedTask);
            }

            return(RouteToHandler(mc, message, false));
        }
 /// <summary>
 /// Triggered when handshake is completed and the connection is ready to communicate
 /// </summary>
 public async Task Ready(IHorseServer server, WsServerSocket client)
 {
     if (_readyHandler != null)
     {
         await _readyHandler(client);
     }
 }
예제 #6
0
        public async Task <WsServerSocket> Connected(IHorseServer server, IConnectionInfo connection, ConnectionData data)
        {
            WsServerSocket socket = new WsServerSocket(server, connection);

            Interlocked.Increment(ref _online);
            return(await Task.FromResult(socket));
        }
예제 #7
0
        /// <summary>
        /// Uses HMQ Protocol and accepts TCP connections.
        /// </summary>
        public static IHorseServer UseHmq(this IHorseServer server, HorseMessageHandler action)
        {
            HorseMethodHandler handler  = new HorseMethodHandler(action);
            HorseMqProtocol    protocol = new HorseMqProtocol(server, handler);

            server.UseProtocol(protocol);
            return(server);
        }
예제 #8
0
        /// <summary>
        /// Uses HTTP Protocol and accepts HTTP connections with Horse MVC Architecture
        /// </summary>
        public static IHorseServer UseMvc(this IHorseServer server, HorseMvc mvc, HttpOptions options)
        {
            MvcConnectionHandler handler  = new MvcConnectionHandler(mvc, mvc.AppBuilder);
            HorseHttpProtocol    protocol = new HorseHttpProtocol(server, handler, options);

            server.UseProtocol(protocol);
            return(server);
        }
예제 #9
0
 /// <summary>
 /// Uses WebSocket Protocol and accepts HTTP connections which comes with "Upgrade: websocket" header data
 /// </summary>
 public static IHorseServer UseWebSockets(this IHorseServer server,
                                          WebSocketReadyHandler readyAction,
                                          WebSocketMessageRecievedHandler messageAction)
 {
     return(UseWebSockets(server,
                          new MethodWebSocketConnectionHandler(null, readyAction, messageAction),
                          HttpOptions.CreateDefault()));
 }
예제 #10
0
        /// <summary>
        ///
        /// </summary>
        public Task Disconnected(IHorseServer server, HorseServerSocket client)
        {
            MqClient node = (MqClient)client;

            _server.Clients.Remove(node);

            return(Task.CompletedTask);
        }
예제 #11
0
        /// <summary>
        /// Uses HTTP Protocol and accepts HTTP connections
        /// </summary>
        public static IHorseServer UseHttp(this IHorseServer server, HttpRequestHandler action, string optionsFilename)
        {
            HttpMethodHandler handler  = new HttpMethodHandler(action);
            HorseHttpProtocol protocol = new HorseHttpProtocol(server, handler, HttpOptions.Load(optionsFilename));

            server.UseProtocol(protocol);
            return(server);
        }
예제 #12
0
        /// <summary>
        /// Uses HTTP Protocol and accepts HTTP connections
        /// </summary>
        public static IHorseServer UseHttp(this IHorseServer server, HttpRequestHandler action, HttpOptions options)
        {
            HttpMethodHandler handler  = new HttpMethodHandler(action);
            HorseHttpProtocol protocol = new HorseHttpProtocol(server, handler, options);

            server.UseProtocol(protocol);
            return(server);
        }
예제 #13
0
        /// <summary>
        /// Creates new Horse HTTP protocol handler
        /// </summary>
        public HorseHttpProtocol(IHorseServer server, IProtocolConnectionHandler <SocketBase, HttpMessage> handler, HttpOptions options)
        {
            Options  = options;
            _server  = server;
            _handler = handler;

            PredefinedHeaders.SERVER_TIME_CRLF = Encoding.UTF8.GetBytes("Date: " + DateTime.UtcNow.ToString("R") + "\r\n");
            _timeTimer = new Timer(s => PredefinedHeaders.SERVER_TIME_CRLF = Encoding.UTF8.GetBytes("Date: " + DateTime.UtcNow.ToString("R") + "\r\n"), "", 1000, 1000);
        }
예제 #14
0
 /// <summary>
 /// Creates new HMQ Server-side socket client
 /// </summary>
 public HorseServerSocket(IHorseServer server, IConnectionInfo info, IUniqueIdGenerator generator, bool useUniqueMessageId = true)
     : base(info)
 {
     Client             = info.Client;
     Server             = server;
     Info               = info;
     _uniqueIdGenerator = generator;
     UseUniqueMessageId = useUniqueMessageId;
 }
예제 #15
0
        /// <summary>
        /// Called when connected client is connected in HMQ protocol
        /// </summary>
        public async Task Disconnected(IHorseServer server, HorseServerSocket client)
        {
            MqClient mqClient = (MqClient)client;
            await _server.RemoveClient(mqClient);

            foreach (IClientHandler handler in _server.ClientHandlers)
            {
                await handler.Disconnected(_server, mqClient);
            }
        }
        /// <summary>
        /// Triggered when a websocket client is connected.
        /// </summary>
        public async Task <WsServerSocket> Connected(IHorseServer server, IConnectionInfo connection, ConnectionData data)
        {
            WsServerSocket socket = new WsServerSocket(server, connection);

            if (_connectedHandler != null)
            {
                await _connectedHandler(socket, data);
            }

            return(socket);
        }
        /// <summary>
        /// Triggered when a non-websocket request available.
        /// </summary>
        private async Task RequestAsync(IHorseServer server, HttpRequest request, HttpResponse response)
        {
            IServiceScope scope = Mvc.ServiceProvider.CreateScope();

            try
            {
                if (App.Descriptors.Count > 0)
                {
                    MiddlewareRunner runner = new MiddlewareRunner(scope);
                    await runner.RunSequence(App, request, response);

                    if (runner.LastResult != null)
                    {
                        WriteResponse(response, runner.LastResult);
                        return;
                    }
                }

                await RequestMvc(server, request, response, scope);
            }
            catch (Exception ex)
            {
                if (Mvc.IsDevelopment)
                {
                    IErrorHandler handler = new DevelopmentErrorHandler();
                    IActionResult result  = await handler.Error(request, ex);

                    WriteResponse(request.Response, result);
                }
                else if (Mvc.ErrorHandler != null)
                {
                    IActionResult result = await Mvc.ErrorHandler.Error(request, ex);

                    WriteResponse(request.Response, result);
                }
                else
                {
                    WriteResponse(request.Response, StatusCodeResult.InternalServerError());
                }

                if (request.Response.StreamSuppressed && request.Response.ResponseStream != null)
                {
                    GC.ReRegisterForFinalize(request.Response.ResponseStream);
                }
            }
            finally
            {
                scope.Dispose();
            }
        }
예제 #18
0
        /// <summary>
        ///
        /// </summary>
        public Task Received(IHorseServer server, IConnectionInfo info, HorseServerSocket client, HorseMessage message)
        {
            MqClient mc = (MqClient)client;

            if (message.Type == MessageType.Server)
            {
                if (message.ContentType == KnownContentTypes.DecisionOverNode)
                {
                    DecisionOverNode(message);
                    return(Task.CompletedTask);
                }
            }

            return(_connectionHandler.RouteToHandler(mc, message, true));
        }
예제 #19
0
        /// <summary>
        ///
        /// </summary>
        public async Task <HorseServerSocket> Connected(IHorseServer server, IConnectionInfo connection, ConnectionData data)
        {
            string clientId;
            bool   found = data.Properties.TryGetValue(HorseHeaders.CLIENT_ID, out clientId);

            if (!found || string.IsNullOrEmpty(clientId))
            {
                clientId = _server.Server.ClientIdGenerator.Create();
            }

            //if another client with same unique id is online, do not accept new client
            MqClient foundClient = _server.Clients.Find(x => x.UniqueId == clientId);

            if (foundClient != null)
            {
                await connection.Socket.SendAsync(HmqWriter.Create(MessageBuilder.Busy()));

                return(null);
            }

            //creates new node client object
            MqClient client = new MqClient(_server.Server, connection);

            client.Data     = data;
            client.UniqueId = clientId.Trim();
            client.Token    = data.Properties.GetStringValue(HorseHeaders.CLIENT_TOKEN);
            client.Name     = data.Properties.GetStringValue(HorseHeaders.CLIENT_NAME);
            client.Type     = data.Properties.GetStringValue(HorseHeaders.CLIENT_TYPE);

            if (_server.Authenticator != null)
            {
                bool accepted = await _server.Authenticator.Authenticate(_server, client);

                if (!accepted)
                {
                    return(null);
                }
            }

            client.RemoteHost = client.Info.Client.Client.RemoteEndPoint.ToString()?.Split(':')[0];
            _server.Clients.Add(client);

            await client.SendAsync(MessageBuilder.Accepted(client.UniqueId));

            return(client);
        }
예제 #20
0
        /// <summary>
        /// Uses WebSocket Protocol and accepts HTTP connections which comes with "Upgrade: websocket" header data
        /// </summary>
        public static IHorseServer UseWebSockets(this IHorseServer server,
                                                 IProtocolConnectionHandler <WsServerSocket, WebSocketMessage> handler,
                                                 HttpOptions options)
        {
            //we need http protocol is added
            IHorseProtocol http = server.FindProtocol("http");

            if (http == null)
            {
                HorseHttpProtocol httpProtocol = new HorseHttpProtocol(server, new WebSocketHttpHandler(), options);
                server.UseProtocol(httpProtocol);
            }

            HorseWebSocketProtocol protocol = new HorseWebSocketProtocol(server, handler);

            server.UseProtocol(protocol);
            return(server);
        }
        /// <summary>
        /// Uses websocket protocol
        /// </summary>
        public static IHorseServer AddWebSockets(this IHorseServer server, HttpOptions options, Action <WebSocketServerBuilder> cfg)
        {
            //we need http protocol is added
            IHorseProtocol http = server.FindProtocol("http");

            if (http == null)
            {
                HorseHttpProtocol httpProtocol = new HorseHttpProtocol(server, new WebSocketHttpHandler(), options);
                server.UseProtocol(httpProtocol);
            }

            WebSocketServerBuilder builder = new WebSocketServerBuilder();

            cfg(builder);
            ModelWsConnectionHandler handler = builder.Build();

            HorseWebSocketProtocol protocol = new HorseWebSocketProtocol(server, handler);

            server.UseProtocol(protocol);
            return(server);
        }
예제 #22
0
 public async Task Disconnected(IHorseServer server, WsServerSocket client)
 {
     Interlocked.Decrement(ref _online);
     await Task.CompletedTask;
 }
예제 #23
0
 public async Task Received(IHorseServer server, IConnectionInfo info, WsServerSocket client, WebSocketMessage message)
 {
     Console.WriteLine(message);
     await Task.CompletedTask;
 }
예제 #24
0
 public async Task Ready(IHorseServer server, WsServerSocket client)
 {
     await Task.CompletedTask;
 }
예제 #25
0
 /// <summary>
 /// Creates new HMQ Server-side socket client
 /// </summary>
 public HorseServerSocket(IHorseServer server, IConnectionInfo info)
     : this(server, info, new DefaultUniqueIdGenerator())
 {
 }
예제 #26
0
 /// <summary>
 /// Creates new HMQ Protocol handler
 /// </summary>
 public HorseMqProtocol(IHorseServer server, IProtocolConnectionHandler <HorseServerSocket, HorseMessage> handler)
 {
     _server  = server;
     _handler = handler;
 }
예제 #27
0
 /// <summary>
 /// Triggered when a HMQ client is connected.
 /// </summary>
 public async Task Disconnected(IHorseServer server, HorseServerSocket client)
 {
     await Task.CompletedTask;
 }
예제 #28
0
 /// <summary>
 /// Triggered when a HMQ message received from client
 /// </summary>
 public async Task Received(IHorseServer server, IConnectionInfo info, HorseServerSocket client, HorseMessage message)
 {
     await _action(client, message);
 }
예제 #29
0
 /// <summary>
 /// Triggered when a HMQ client is connected.
 /// </summary>
 public async Task <HorseServerSocket> Connected(IHorseServer server, IConnectionInfo connection, ConnectionData data)
 {
     return(await Task.FromResult(new HorseServerSocket(server, connection, _uniqueIdGenerator)));
 }
예제 #30
0
 /// <summary>
 /// Triggered when a client sends a message to the server
 /// </summary>
 public async Task Received(IHorseServer server, IConnectionInfo info, SocketBase client, HttpMessage message)
 {
     message.Response.StatusCode = HttpStatusCode.NotFound;
     await Task.CompletedTask;
 }