using DotNetty.Buffers;
using DotNetty.Codecs.Http;
using DotNetty.Common.Utilities;
using DotNetty.Transport.Channels;
using JT808.DotNetty.Core.Handlers;
using JT808.DotNetty.Core.Metadata;
using Microsoft.Extensions.Logging;
using System;
using System.Text;
namespace JT808.DotNetty.WebApi.Handlers
{
///
/// jt808 webapi服务
/// 请求量不大,只支持JSON格式并且只支持post发数据
/// ref: dotnetty HttpServer
///
internal class JT808WebAPIServerHandler : SimpleChannelInboundHandler
{
private static readonly AsciiString TypeJson = AsciiString.Cached("application/json");
private static readonly AsciiString ServerName = AsciiString.Cached("JT808WebAPINetty");
private static readonly AsciiString ContentTypeEntity = HttpHeaderNames.ContentType;
private static readonly AsciiString DateEntity = HttpHeaderNames.Date;
private static readonly AsciiString ContentLengthEntity = HttpHeaderNames.ContentLength;
private static readonly AsciiString ServerEntity = HttpHeaderNames.Server;
private readonly JT808MsgIdHttpHandlerBase jT808MsgIdHttpHandlerBase;
private readonly ILogger logger;
public JT808WebAPIServerHandler(
JT808MsgIdHttpHandlerBase jT808MsgIdHttpHandlerBase,
ILoggerFactory loggerFactory)
{
this.jT808MsgIdHttpHandlerBase = jT808MsgIdHttpHandlerBase;
logger = loggerFactory.CreateLogger();
}
protected override void ChannelRead0(IChannelHandlerContext ctx, IFullHttpRequest msg)
{
if (logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug($"Uri:{msg.Uri}");
logger.LogDebug($"Content:{msg.Content.ToString(Encoding.UTF8)}");
}
JT808HttpResponse jT808HttpResponse = null;
if (jT808MsgIdHttpHandlerBase.HandlerDict.TryGetValue(msg.Uri,out var funcHandler))
{
jT808HttpResponse = funcHandler( new JT808HttpRequest() { Json = msg.Content.ToString(Encoding.UTF8)});
}
else
{
jT808HttpResponse = jT808MsgIdHttpHandlerBase.NotFoundHttpResponse();
}
if (jT808HttpResponse != null)
{
WriteResponse(ctx, Unpooled.WrappedBuffer(jT808HttpResponse.Data), TypeJson, jT808HttpResponse.Data.Length);
}
}
private void WriteResponse(IChannelHandlerContext ctx, IByteBuffer buf, ICharSequence contentType, int contentLength)
{
// Build the response object.
var response = new DefaultFullHttpResponse(HttpVersion.Http11, HttpResponseStatus.OK, buf, false);
HttpHeaders headers = response.Headers;
headers.Set(ContentTypeEntity, contentType);
headers.Set(ServerEntity, ServerName);
headers.Set(DateEntity, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
headers.Set(ContentLengthEntity, contentLength);
// Close the non-keep-alive connection after the write operation is done.
ctx.WriteAndFlushAsync(response);
ctx.CloseAsync();
}
public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
{
WriteResponse(context, Unpooled.WrappedBuffer(jT808MsgIdHttpHandlerBase.ErrorHttpResponse(exception).Data), TypeJson, jT808MsgIdHttpHandlerBase.ErrorHttpResponse(exception).Data.Length);
logger.LogError(exception, exception.Message);
context.CloseAsync();
}
public override void ChannelReadComplete(IChannelHandlerContext context) => context.Flush();
}
}