예제 #1
0
파일: Program.cs 프로젝트: ciker/twino
        public async Task <WsServerSocket> Connected(ITwinoServer server, IConnectionInfo connection, ConnectionData data)
        {
            WsServerSocket socket = new WsServerSocket(server, connection);

            Interlocked.Increment(ref _online);
            return(await Task.FromResult(socket));
        }
예제 #2
0
        /// <summary>
        /// Called when a new message received from the client
        /// </summary>
        public async Task Received(ITwinoServer server, IConnectionInfo info, TmqServerSocket client, TmqMessage 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.ResponseRequired)
                {
                    message.ResponseRequired = 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;
            }

            await RouteToHandler(mc, message, info);
        }
 /// <summary>
 /// Triggered when handshake is completed and the connection is ready to communicate
 /// </summary>
 public async Task Ready(ITwinoServer server, WsServerSocket client)
 {
     if (_readyHandler != null)
     {
         await _readyHandler(client);
     }
 }
예제 #4
0
 /// <summary>
 /// Creates new server-side websocket client
 /// </summary>
 public WsServerSocket(ITwinoServer server, IConnectionInfo info)
     : base(info)
 {
     Client = info.Client;
     Server = server;
     Info   = info;
 }
예제 #5
0
        /// <summary>
        ///
        /// </summary>
        public async Task Disconnected(ITwinoServer server, TmqServerSocket client)
        {
            MqClient node = (MqClient)client;

            _server.Clients.Remove(node);
            await Task.CompletedTask;
        }
예제 #6
0
        /// <summary>
        /// Uses TMQ Protocol and accepts TCP connections.
        /// </summary>
        public static ITwinoServer UseTmq(this ITwinoServer server, IProtocolConnectionHandler <TmqServerSocket, TmqMessage> handler)
        {
            TwinoTmqProtocol protocol = new TwinoTmqProtocol(server, handler);

            server.UseProtocol(protocol);
            return(server);
        }
예제 #7
0
 /// <summary>
 /// Uses WebSocket Protocol and accepts HTTP connections which comes with "Upgrade: websocket" header data
 /// </summary>
 public static ITwinoServer UseWebSockets(this ITwinoServer server,
                                          WebSocketReadyHandler readyAction,
                                          WebSocketMessageRecievedHandler messageAction)
 {
     return(UseWebSockets(server,
                          new MethodWebSocketConnectionHandler(null, readyAction, messageAction),
                          HttpOptions.CreateDefault()));
 }
예제 #8
0
        /// <summary>
        /// Uses HTTP Protocol and accepts HTTP connections with Twino MVC Architecture
        /// </summary>
        public static ITwinoServer UseMvc(this ITwinoServer server, TwinoMvc mvc, HttpOptions options)
        {
            MvcConnectionHandler handler  = new MvcConnectionHandler(mvc, mvc.AppBuilder);
            TwinoHttpProtocol    protocol = new TwinoHttpProtocol(server, handler, options);

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

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

            server.UseProtocol(protocol);
            return(server);
        }
예제 #11
0
        /// <summary>
        /// Uses TMQ Protocol and accepts TCP connections.
        /// </summary>
        public static ITwinoServer UseTmq(this ITwinoServer server, TmqMessageHandler action)
        {
            TmqMethodHandler handler  = new TmqMethodHandler(action);
            TwinoTmqProtocol protocol = new TwinoTmqProtocol(server, handler);

            server.UseProtocol(protocol);
            return(server);
        }
예제 #12
0
        /// <summary>
        /// Creates new Twino HTTP protocol handler
        /// </summary>
        public TwinoHttpProtocol(ITwinoServer 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);
        }
예제 #13
0
 /// <summary>
 /// Creates new TMQ Server-side socket client
 /// </summary>
 public TmqServerSocket(ITwinoServer server, IConnectionInfo info, IUniqueIdGenerator generator, bool useUniqueMessageId = true)
     : base(info)
 {
     Client             = info.Client;
     Server             = server;
     Info               = info;
     _uniqueIdGenerator = generator;
     UseUniqueMessageId = useUniqueMessageId;
 }
예제 #14
0
        /// <summary>
        /// Called when connected client is connected in TMQ protocol
        /// </summary>
        public async Task Disconnected(ITwinoServer server, TmqServerSocket client)
        {
            MqClient mqClient = (MqClient)client;
            await _server.RemoveClient(mqClient);

            if (_server.ClientHandler != null)
            {
                await _server.ClientHandler.Disconnected(_server, mqClient);
            }
        }
        /// <summary>
        /// Triggered when a websocket client is connected.
        /// </summary>
        public async Task <WsServerSocket> Connected(ITwinoServer server, IConnectionInfo connection, ConnectionData data)
        {
            WsServerSocket socket = new WsServerSocket(server, connection);

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

            return(socket);
        }
예제 #16
0
        /// <summary>
        ///
        /// </summary>
        public async Task <TmqServerSocket> Connected(ITwinoServer server, IConnectionInfo connection, ConnectionData data)
        {
            string clientId;
            bool   found = data.Properties.TryGetValue(TmqHeaders.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(await _writer.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(TmqHeaders.CLIENT_TOKEN);
            client.Name     = data.Properties.GetStringValue(TmqHeaders.CLIENT_NAME);
            client.Type     = data.Properties.GetStringValue(TmqHeaders.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);
        }
예제 #17
0
        /// <summary>
        /// Triggered when a non-websocket request available.
        /// </summary>
        private async Task RequestAsync(ITwinoServer server, HttpRequest request, HttpResponse response)
        {
            IContainerScope scope = Mvc.Services.CreateScope();

            try
            {
                if (App.Descriptors.Count > 0)
                {
                    MiddlewareRunner runner = new MiddlewareRunner(Mvc, 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();
                    await handler.Error(request, ex);
                }
                else if (Mvc.ErrorHandler != null)
                {
                    await Mvc.ErrorHandler.Error(request, ex);
                }
                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>
        /// Called when connected client is connected in TMQ protocol
        /// </summary>
        public async Task Disconnected(ITwinoServer server, TmqServerSocket client)
        {
            MqClient mqClient = (MqClient)client;

            if (mqClient.IsInstanceServer)
            {
                _server.SlaveInstances.FindAndRemove(x => x.Client == client);
                return;
            }

            await _server.RemoveClient(mqClient);

            if (_server.ClientHandler != null)
            {
                await _server.ClientHandler.Disconnected(_server, mqClient);
            }
        }
예제 #19
0
        /// <summary>
        /// Uses WebSocket Protocol and accepts HTTP connections which comes with "Upgrade: websocket" header data
        /// </summary>
        public static ITwinoServer UseWebSockets(this ITwinoServer server,
                                                 IProtocolConnectionHandler <WsServerSocket, WebSocketMessage> handler,
                                                 HttpOptions options)
        {
            //we need http protocol is added
            ITwinoProtocol http = server.FindProtocol("http");

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

            TwinoWebSocketProtocol protocol = new TwinoWebSocketProtocol(server, handler);

            server.UseProtocol(protocol);
            return(server);
        }
예제 #20
0
 /// <summary>
 /// Creates new Websocket protocol handler
 /// </summary>
 public TwinoWebSocketProtocol(ITwinoServer server, IProtocolConnectionHandler <WsServerSocket, WebSocketMessage> handler)
 {
     _server  = server;
     _handler = handler;
 }
예제 #21
0
 /// <summary>
 /// Triggered when handshake is completed and the connection is ready to communicate
 /// </summary>
 public async Task Ready(ITwinoServer server, TmqServerSocket client)
 {
     await Task.CompletedTask;
 }
예제 #22
0
파일: Program.cs 프로젝트: ciker/twino
 public async Task Disconnected(ITwinoServer server, WsServerSocket client)
 {
     Interlocked.Decrement(ref _online);
     await Task.CompletedTask;
 }
예제 #23
0
파일: Program.cs 프로젝트: ciker/twino
 public async Task Received(ITwinoServer server, IConnectionInfo info, WsServerSocket client, WebSocketMessage message)
 {
     Console.WriteLine(message);
     await Task.CompletedTask;
 }
예제 #24
0
 /// <summary>
 /// Uses WebSocket Protocol and accepts HTTP connections which comes with "Upgrade: websocket" header data
 /// </summary>
 public static ITwinoServer UseWebSockets(this ITwinoServer server,
                                          WebSocketMessageRecievedHandler handlerAction,
                                          HttpOptions options)
 {
     return(UseWebSockets(server, new MethodWebSocketConnectionHandler(handlerAction), options));
 }
예제 #25
0
 /// <summary>
 /// Triggered when a websocket client is connected.
 /// </summary>
 public async Task <SocketBase> Connected(ITwinoServer server, IConnectionInfo connection, ConnectionData data)
 {
     return(await Task.FromResult((SocketBase)null));
 }
예제 #26
0
 /// <summary>
 /// Triggered when a client sends a message to the server
 /// </summary>
 public async Task Received(ITwinoServer server, IConnectionInfo info, SocketBase client, HttpMessage message)
 {
     message.Response.StatusCode = HttpStatusCode.NotFound;
     await Task.CompletedTask;
 }
예제 #27
0
 /// <summary>
 /// Triggered when a websocket client is disconnected.
 /// </summary>
 public async Task Disconnected(ITwinoServer server, SocketBase client)
 {
     await Task.CompletedTask;
 }
예제 #28
0
 /// <summary>
 /// Triggered when handshake is completed and the connection is ready to communicate
 /// </summary>
 public async Task Ready(ITwinoServer server, SocketBase client)
 {
     await Task.CompletedTask;
 }
예제 #29
0
        /// <summary>
        /// Called when a new client is connected via TMQ protocol
        /// </summary>
        public async Task <TmqServerSocket> Connected(ITwinoServer server, IConnectionInfo connection, ConnectionData data)
        {
            string clientId;
            bool   found = data.Properties.TryGetValue(TmqHeaders.CLIENT_ID, out clientId);

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

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

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

                return(null);
            }

            //creates new mq client object
            MqClient client = new MqClient(_server, connection, _server.MessageIdGenerator, _server.Options.UseMessageId);

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

            //connecting client is a MQ server
            string serverValue = data.Properties.GetStringValue(TmqHeaders.TWINO_MQ_SERVER);

            if (!string.IsNullOrEmpty(serverValue) && (serverValue.Equals("1") || serverValue.Equals("true", StringComparison.InvariantCultureIgnoreCase)))
            {
                if (_server.ServerAuthenticator == null)
                {
                    return(null);
                }

                bool accepted = await _server.ServerAuthenticator.Authenticate(_server, client);

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

                client.IsInstanceServer = true;
                _server.SlaveInstances.Add(new SlaveInstance
                {
                    ConnectedDate = DateTime.UtcNow,
                    Client        = client,
                    RemoteHost    = client.Info.Client.Client.RemoteEndPoint.ToString().Split(':')[0]
                });

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

            //connecting client is a producer/consumer client
            else
            {
                //authenticates client
                if (_server.Authenticator != null)
                {
                    client.IsAuthenticated = await _server.Authenticator.Authenticate(_server, client);

                    if (!client.IsAuthenticated)
                    {
                        await client.SendAsync(MessageBuilder.Unauthorized());

                        return(null);
                    }
                }

                //client authenticated, add it into the connected clients list
                _server.AddClient(client);

                //send response message to the client, client should check unique id,
                //if client's unique id isn't permitted, server will create new id for client and send it as response
                await client.SendAsync(MessageBuilder.Accepted(client.UniqueId));

                if (_server.ClientHandler != null)
                {
                    await _server.ClientHandler.Connected(_server, client);
                }
            }

            return(client);
        }
예제 #30
0
 /// <summary>
 /// Creates new TMQ Protocol handler
 /// </summary>
 public TwinoTmqProtocol(ITwinoServer server, IProtocolConnectionHandler <TmqServerSocket, TmqMessage> handler)
 {
     _server  = server;
     _handler = handler;
 }