void HandleHttpRequest(IChannelHandlerContext ctx, IFullHttpRequest req)
 {
     // Handle a bad request.
     if (!req.Result.IsSuccess)
     {
         SendHttpResponse(ctx, req, new DefaultFullHttpResponse(Http11, BadRequest));
         return;
     }
     if ("/favicon.ico".Equals(req.Uri))
     {
         var res = new DefaultFullHttpResponse(Http11, NotFound);
         SendHttpResponse(ctx, req, res);
         return;
     }
     if (iJT1078Authorization.Authorization(req, out var principal))
     {
         if (req.Uri.StartsWith(WebsocketPath))
         {
             // Handshake
             var wsFactory = new WebSocketServerHandshakerFactory(GetWebSocketLocation(req), null, true, 5 * 1024 * 1024);
             this.handshaker = wsFactory.NewHandshaker(req);
             if (this.handshaker == null)
             {
                 WebSocketServerHandshakerFactory.SendUnsupportedVersionResponse(ctx.Channel);
             }
             else
             {
                 this.handshaker.HandshakeAsync(ctx.Channel, req);
                 jT1078HttpSessionManager.TryAdd(principal.Identity.Name, ctx.Channel);
                 httpMiddleware?.Next(ctx, req, principal);
             }
         }
         else
         {
             jT1078HttpSessionManager.TryAdd(principal.Identity.Name, ctx.Channel);
             httpMiddleware?.Next(ctx, req, principal);
         }
     }
     else
     {
         SendHttpResponse(ctx, req, new DefaultFullHttpResponse(Http11, Unauthorized));
         return;
     }
 }
Esempio n. 2
0
        private async ValueTask ProcessRequestAsync(HttpListenerContext context, IPrincipal principal)
        {
            if (context.Request.RawUrl.StartsWith("/favicon.ico"))
            {
                context.Http404();
                return;
            }
            if (context.Request.RawUrl.Contains(".m3u8") || context.Request.RawUrl.Contains(".ts"))
            {
                hLSRequestManager.HandleHlsRequest(context, principal);
                return;
            }
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace($"[http RequestTraceIdentifier]:{context.Request.RequestTraceIdentifier.ToString()}-{context.Request.RemoteEndPoint.ToString()}");
            }
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace($"[http RequestTraceIdentifier]:{context.Request.RequestTraceIdentifier.ToString()}-{context.Request.RemoteEndPoint.ToString()}");
            }
            string sim     = context.Request.QueryString.Get("sim");
            string channel = context.Request.QueryString.Get("channel");

            if (string.IsNullOrEmpty(sim) || string.IsNullOrEmpty(channel))
            {
                await context.Http400();

                return;
            }
            int.TryParse(channel, out int channelNo);
            if (context.Request.IsWebSocketRequest)
            {
                HttpListenerWebSocketContext wsContext = await context.AcceptWebSocketAsync(null, keepAliveInterval : TimeSpan.FromSeconds(5));

                var jT1078HttpContext = new JT1078HttpContext(context, wsContext, principal);
                jT1078HttpContext.Sim          = sim;
                jT1078HttpContext.ChannelNo    = channelNo;
                jT1078HttpContext.RTPVideoType = RTPVideoType.Ws_Flv;
                SessionManager.TryAdd(jT1078HttpContext);
                //这个发送出去,flv.js就报错了
                //await jT1078HttpContext.WebSocketSendHelloAsync();
                await Task.Factory.StartNew(async(state) =>
                {
                    //https://www.bejson.com/httputil/websocket/
                    //ws://localhost:15555?token=22&sim=1221&channel=1
                    var websocketContext = state as JT1078HttpContext;
                    while (websocketContext.WebSocketContext.WebSocket.State == WebSocketState.Open ||
                           websocketContext.WebSocketContext.WebSocket.State == WebSocketState.Connecting)
                    {
                        var buffer = ArrayPool <byte> .Shared.Rent(256);
                        try
                        {
                            //客户端主动断开需要有个线程去接收通知,不然会客户端会卡死直到超时
                            WebSocketReceiveResult receiveResult = await websocketContext.WebSocketContext.WebSocket.ReceiveAsync(buffer, CancellationToken.None);
                            if (receiveResult.EndOfMessage)
                            {
                                if (receiveResult.Count > 0)
                                {
                                    var data = buffer.AsSpan().Slice(0, receiveResult.Count).ToArray();
                                    if (Logger.IsEnabled(LogLevel.Trace))
                                    {
                                        Logger.LogTrace($"[ws receive]:{Encoding.UTF8.GetString(data)}");
                                    }
                                    await websocketContext.WebSocketSendTextAsync(data);
                                }
                            }
                        }
                        finally
                        {
                            ArrayPool <byte> .Shared.Return(buffer);
                        }
                    }
                    if (Logger.IsEnabled(LogLevel.Information))
                    {
                        Logger.LogInformation($"[ws close]:{websocketContext.SessionId}-{websocketContext.Sim}-{websocketContext.ChannelNo}-{websocketContext.StartTime:yyyyMMddhhmmss}");
                    }
                    SessionManager.TryRemove(websocketContext.SessionId);
                }, jT1078HttpContext);
            }
            else
            {
                var jT1078HttpContext = new JT1078HttpContext(context, principal);
                jT1078HttpContext.Sim          = sim;
                jT1078HttpContext.RTPVideoType = RTPVideoType.Http_Flv;
                jT1078HttpContext.ChannelNo    = channelNo;
                SessionManager.TryAdd(jT1078HttpContext);
            }
        }
Esempio n. 3
0
        private async ValueTask ProcessRequestAsync(HttpListenerContext context, IPrincipal principal)
        {
            if (context.Request.RawUrl.StartsWith("/favicon.ico"))
            {
                context.Http404();
                return;
            }
            var    uri         = new Uri(context.Request.RawUrl);
            string url         = uri.AbsolutePath;
            var    queryParams = uri.Query.Substring(1, uri.Query.Length - 1).Split('&');

            if (queryParams.Length < 2)
            {
                context.Http404();
                return;
            }
            if (url.EndsWith(".m3u8") || url.EndsWith(".ts"))
            {
                string key = $"{queryParams[0].Split('=')[1]}_{queryParams[1].Split('=')[1]}";//默认queryParams第一个参数是终端号,第二个参数是通道号
                memoryCache.GetOrCreate(key, (cacheEntry) => {
                    cacheEntry.SetSlidingExpiration(TimeSpan.FromSeconds(20));
                    cacheEntry.RegisterPostEvictionCallback((key, value, reason, state) => {
                        //当清空httpssion时,同时清除tcpsseion
                    });
                    return(DateTime.Now);
                });
                string filename = Path.GetFileName(url);
                string filepath = Path.Combine(Configuration.HlsRootDirectory, key, filename);
                if (!File.Exists(filepath))
                {
                    context.Http404();
                    return;
                }
                try
                {
                    using (FileStream sr = new FileStream(filepath, FileMode.Open))
                    {
                        context.Response.ContentLength64 = sr.Length;
                        await sr.CopyToAsync(context.Response.OutputStream);
                    }
                    string ext = Path.GetExtension(filename);
                    if (ext == ".m3u8")
                    {
                        context.Response.ContentType = m3u8Mime;
                    }
                    else if (ext == ".ts")
                    {
                        context.Response.ContentType = tsMime;
                    }
                    context.Response.StatusCode = (int)HttpStatusCode.OK;
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, $"{context.Request.RawUrl}");
                    context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                }
                finally
                {
                    context.Response.OutputStream.Close();
                    context.Response.Close();
                }
                return;
            }
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace($"[http RequestTraceIdentifier]:{context.Request.RequestTraceIdentifier.ToString()}-{context.Request.RemoteEndPoint.ToString()}");
            }
            string sim     = context.Request.QueryString.Get("sim");
            string channel = context.Request.QueryString.Get("channel");

            if (string.IsNullOrEmpty(sim) || string.IsNullOrEmpty(channel))
            {
                await context.Http400();

                return;
            }
            int.TryParse(channel, out int channelNo);
            if (context.Request.IsWebSocketRequest)
            {
                HttpListenerWebSocketContext wsContext = await context.AcceptWebSocketAsync(null, keepAliveInterval : TimeSpan.FromSeconds(5));

                var jT1078HttpContext = new JT1078HttpContext(context, wsContext, principal);
                jT1078HttpContext.Sim       = sim;
                jT1078HttpContext.ChannelNo = channelNo;
                SessionManager.TryAdd(jT1078HttpContext);
                await jT1078HttpContext.WebSocketSendHelloAsync();

                await Task.Factory.StartNew(async(state) =>
                {
                    //https://www.bejson.com/httputil/websocket/
                    //ws://localhost:15555?token=22&sim=1221&channel=1
                    var websocketContext = state as JT1078HttpContext;
                    while (websocketContext.WebSocketContext.WebSocket.State == WebSocketState.Open ||
                           websocketContext.WebSocketContext.WebSocket.State == WebSocketState.Connecting)
                    {
                        var buffer = ArrayPool <byte> .Shared.Rent(256);
                        try
                        {
                            //客户端主动断开需要有个线程去接收通知,不然会客户端会卡死直到超时
                            WebSocketReceiveResult receiveResult = await websocketContext.WebSocketContext.WebSocket.ReceiveAsync(buffer, CancellationToken.None);
                            if (receiveResult.EndOfMessage)
                            {
                                if (receiveResult.Count > 0)
                                {
                                    var data = buffer.AsSpan().Slice(0, receiveResult.Count).ToArray();
                                    if (Logger.IsEnabled(LogLevel.Trace))
                                    {
                                        Logger.LogTrace($"[ws receive]:{Encoding.UTF8.GetString(data)}");
                                    }
                                    await websocketContext.WebSocketSendTextAsync(data);
                                }
                            }
                        }
                        finally
                        {
                            ArrayPool <byte> .Shared.Return(buffer);
                        }
                    }
                    if (Logger.IsEnabled(LogLevel.Information))
                    {
                        Logger.LogInformation($"[ws close]:{websocketContext.SessionId}-{websocketContext.Sim}-{websocketContext.ChannelNo}-{websocketContext.StartTime:yyyyMMddhhmmss}");
                    }
                    SessionManager.TryRemove(websocketContext.SessionId);
                }, jT1078HttpContext);
            }
            else
            {
                var jT1078HttpContext = new JT1078HttpContext(context, principal);
                jT1078HttpContext.Sim       = sim;
                jT1078HttpContext.ChannelNo = channelNo;
                SessionManager.TryAdd(jT1078HttpContext);
            }
        }