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; } }
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); } }
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); } }