Exemplo n.º 1
0
        /// <summary>
        /// It will also put user into status 'Online' (means it's available to get messages via socket) if authorized
        /// and also updated last connection activity (for destroy connections it they was not active some time)
        /// </summary>
        /// <param name="client"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        private bool CheckAuthorization(DuplexNetworkClient client, DuplexNetworkRequest request)
        {
            client.UpdateActivity();

            var errMsg = string.Empty;

            if (client.User == null) //try to authorize if not yet
            {
                client.User = EnergoServer.Current.FindUserByAuthToken(request.AuthToken, out errMsg);
            }

            return(client.User != null);
        }
Exemplo n.º 2
0
        private async Task DirectResponse <T>(DuplexNetworkClient client, T response)
        {
            var message = "";

            if (response is string)
            {
                message = response.ToString();
            }
            else
            {
                response.ToJson();
            }

            var data = message.GetByteSegment();

            if (client.Connection.State == WebSocketState.Open)
            {
                await client.SendData(data);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// It will expecting to recieve AuthToken as Json parameter from client to join it to network
        /// </summary>
        /// <param name="http"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public async Task HandleRequests(HttpContext http, Func <Task> next)
        {
            if (!http.WebSockets.IsWebSocketRequest)
            {
                await next();

                return;
            }

            var webSocket = await http.WebSockets.AcceptWebSocketAsync();

            if (webSocket != null && webSocket.State == WebSocketState.Open)
            {
                CloseUnactiveConnections();

                var client = new DuplexNetworkClient(webSocket);
                _clients.Add(client);

                //todo: move this block to the separate method
                while (webSocket.State == WebSocketState.Open)
                {
                    try
                    {
                        //todo buffer size means it will trunc or separate requests if they will exceed 4k? Need to handle this case?
                        var buffer   = new ArraySegment <byte>(new byte[4096]);
                        var received = await webSocket.ReceiveAsync(buffer, CancellationToken.None);

                        //todo: handle only text?
                        switch (received.MessageType)
                        {
                        case WebSocketMessageType.Close:
                            CloseUnactiveConnections(new[] { WebSocketState.CloseReceived });
                            break;

                        case WebSocketMessageType.Text:
                            var socketMessage = Encoding.UTF8.GetString(buffer.Array, buffer.Offset, buffer.Count).Trim('\0');
                            var request       = socketMessage.ToObject <DuplexNetworkRequest>();

                            if (CheckAuthorization(client, request))
                            {
                                OnRequestRecieved(client.User, request.Type, socketMessage);
                            }
                            else
                            {
                                var response = new { IsSuccess = false, Message = "You are not authorized" };
                                await DirectResponse(client, response);

                                ServerContext.Current.Logger.Log(LogDestination.Console, LogType.Info, "Websocket Unauthorized client trying to send something");
                            }
                            break;

                        case WebSocketMessageType.Binary:
                            //todo: not impl yet for binary - do we need this case?
                            ServerContext.Current.Logger.Log(LogDestination.Console, LogType.Info, "Websocket Binary recieved:");
                            ServerContext.Current.Logger.Log(LogDestination.Console, LogType.Info, buffer.Array);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        ServerContext.Current.Logger.LogError(LogDestination.Console, ex);
                        break;
                    }
                }
                //todo: handle closed socket - remove?
            }
            else
            {
                // Nothing to do here, pass downstream.
                await next();
            }
        }