From c2f7c5dfde52bd64c75db0d5f7136761130c66eb Mon Sep 17 00:00:00 2001
From: SmallChi <564952747@qq.com>
Date: Thu, 22 Nov 2018 19:48:30 +0800
Subject: [PATCH] =?UTF-8?q?1.=E4=BA=86=E8=A7=A3=E5=9F=BA=E4=BA=8Edotnetty?=
=?UTF-8?q?=E7=9A=84http=E6=9C=8D=E5=8A=A1=202.=E5=8E=BB=E6=8E=89=E4=BC=9A?=
=?UTF-8?q?=E8=AF=9D=E6=9C=8D=E5=8A=A1job=E4=BB=BB=E5=8A=A1=203.=E5=A2=9E?=
=?UTF-8?q?=E5=8A=A0webapi=E6=9C=8D=E5=8A=A1=EF=BC=88=E5=BE=85=E6=B5=8B?=
=?UTF-8?q?=E8=AF=95=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Dtos/JT808UnificationSendRequestDto.cs | 15 ++
.../Handlers/JT808ConnectionHandler.cs | 5 +-
.../Handlers/JT808WebAPIServerHandler.cs | 88 ++-----
.../Interfaces/IJT808SessionService.cs | 2 +-
.../IJT808UnificationSendService.cs | 2 +-
src/JT808.DotNetty/JT808DotnettyExtensions.cs | 3 +-
src/JT808.DotNetty/JT808SessionManager.cs | 26 +--
src/JT808.DotNetty/JT808WebAPIServerHost.cs | 10 +-
src/JT808.DotNetty/JT808WebAPIService.cs | 214 ++++++++++++++++++
.../Metadata/JT808HttpRequest.cs | 22 ++
.../Metadata/JT808HttpResponse.cs | 22 ++
11 files changed, 312 insertions(+), 97 deletions(-)
create mode 100644 src/JT808.DotNetty/Dtos/JT808UnificationSendRequestDto.cs
create mode 100644 src/JT808.DotNetty/JT808WebAPIService.cs
create mode 100644 src/JT808.DotNetty/Metadata/JT808HttpRequest.cs
create mode 100644 src/JT808.DotNetty/Metadata/JT808HttpResponse.cs
diff --git a/src/JT808.DotNetty/Dtos/JT808UnificationSendRequestDto.cs b/src/JT808.DotNetty/Dtos/JT808UnificationSendRequestDto.cs
new file mode 100644
index 0000000..5b565f1
--- /dev/null
+++ b/src/JT808.DotNetty/Dtos/JT808UnificationSendRequestDto.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.DotNetty.Dtos
+{
+ ///
+ /// 统一下发请求参数
+ ///
+ public class JT808UnificationSendRequestDto
+ {
+ public string TerminalPhoneNo { get; set; }
+ public byte[] Data { get; set; }
+ }
+}
diff --git a/src/JT808.DotNetty/Handlers/JT808ConnectionHandler.cs b/src/JT808.DotNetty/Handlers/JT808ConnectionHandler.cs
index c14d70c..8646687 100644
--- a/src/JT808.DotNetty/Handlers/JT808ConnectionHandler.cs
+++ b/src/JT808.DotNetty/Handlers/JT808ConnectionHandler.cs
@@ -64,10 +64,7 @@ namespace JT808.DotNetty.Handlers
return base.CloseAsync(context);
}
- public override void ChannelReadComplete(IChannelHandlerContext context)
- {
- context.Flush();
- }
+ public override void ChannelReadComplete(IChannelHandlerContext context)=> context.Flush();
///
/// 超时策略
diff --git a/src/JT808.DotNetty/Handlers/JT808WebAPIServerHandler.cs b/src/JT808.DotNetty/Handlers/JT808WebAPIServerHandler.cs
index f30e557..31a0365 100644
--- a/src/JT808.DotNetty/Handlers/JT808WebAPIServerHandler.cs
+++ b/src/JT808.DotNetty/Handlers/JT808WebAPIServerHandler.cs
@@ -1,97 +1,58 @@
using DotNetty.Buffers;
using DotNetty.Codecs.Http;
-using DotNetty.Common;
using DotNetty.Common.Utilities;
using DotNetty.Transport.Channels;
-using JT808.DotNetty.Dtos;
-using JT808.DotNetty.Interfaces;
+using JT808.DotNetty.Metadata;
using Microsoft.Extensions.Logging;
-using Newtonsoft.Json;
using System;
-using System.Collections.Generic;
using System.Text;
namespace JT808.DotNetty.Handlers
{
///
/// jt808 webapi服务
- /// 请求量不大,只支持JSON格式
+ /// 请求量不大,只支持JSON格式并且只支持post发数据
/// ref: dotnetty HttpServer
///
- internal class JT808WebAPIServerHandler : ChannelHandlerAdapter
+ internal class JT808WebAPIServerHandler : SimpleChannelInboundHandler
{
- private static readonly ThreadLocalCache Cache = new ThreadLocalCache();
-
- sealed class ThreadLocalCache : FastThreadLocal
- {
- protected override AsciiString GetInitialValue()
- {
- DateTime dateTime = DateTime.UtcNow;
- return AsciiString.Cached($"{dateTime.DayOfWeek}, {dateTime:dd MMM yyyy HH:mm:ss z}");
- }
- }
-
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;
-
- volatile ICharSequence date = Cache.Value;
-
+ private readonly JT808WebAPIService jT808WebAPIService;
private readonly ILogger logger;
- private readonly IJT808SessionService jT808SessionService;
-
- private readonly IJT808UnificationSendService jT808UnificationSendService;
-
public JT808WebAPIServerHandler(
- IJT808SessionService jT808SessionService,
- IJT808UnificationSendService jT808UnificationSendService,
+ JT808WebAPIService jT808WebAPIService,
ILoggerFactory loggerFactory)
{
- this.jT808SessionService = jT808SessionService;
- this.jT808UnificationSendService = jT808UnificationSendService;
+ this.jT808WebAPIService = jT808WebAPIService;
logger = loggerFactory.CreateLogger();
}
- public override void ChannelRead(IChannelHandlerContext ctx, object message)
+ protected override void ChannelRead0(IChannelHandlerContext ctx, IFullHttpRequest msg)
{
- if (message is IHttpRequest request)
+ if (logger.IsEnabled(LogLevel.Debug))
+ {
+ logger.LogDebug($"Uri:{msg.Uri}");
+ logger.LogDebug($"Content:{msg.Content.ToString(Encoding.UTF8)}");
+ }
+ JT808HttpResponse jT808HttpResponse = null;
+ if (jT808WebAPIService.HandlerDict.TryGetValue(msg.Uri,out var funcHandler))
{
- try
- {
- Process(ctx, request);
- }
- finally
- {
- ReferenceCountUtil.Release(message);
- }
+ jT808HttpResponse = funcHandler( new JT808HttpRequest() { Json = msg.Content.ToString(Encoding.UTF8)});
}
else
{
- ctx.FireChannelRead(message);
+ jT808HttpResponse = jT808WebAPIService.NotFoundHttpResponse();
}
- }
-
- private void Process(IChannelHandlerContext ctx, IHttpRequest request)
- {
- string uri = request.Uri;
- //switch (uri)
- //{
- // //case "/json":
- // // byte[] json = Encoding.UTF8.GetBytes(NewMessage().ToJsonFormat());
- // // this.WriteResponse(ctx, Unpooled.WrappedBuffer(json), TypeJson, JsonClheaderValue);
- // // break;
- // default:
- // var response = new DefaultFullHttpResponse(HttpVersion.Http11, HttpResponseStatus.NotFound, Unpooled.Empty, false);
- // ctx.WriteAndFlushAsync(response);
- // ctx.CloseAsync();
- // break;
- //}
- byte[] json = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new JT808DefaultResultDto()));
- this.WriteResponse(ctx, Unpooled.WrappedBuffer(json), TypeJson, json.Length);
+ if (jT808HttpResponse != null)
+ {
+ WriteResponse(ctx, Unpooled.WrappedBuffer(jT808HttpResponse.Data), TypeJson, jT808HttpResponse.Data.Length);
+ }
}
private void WriteResponse(IChannelHandlerContext ctx, IByteBuffer buf, ICharSequence contentType, int contentLength)
@@ -101,16 +62,17 @@ namespace JT808.DotNetty.Handlers
HttpHeaders headers = response.Headers;
headers.Set(ContentTypeEntity, contentType);
headers.Set(ServerEntity, ServerName);
- headers.Set(DateEntity, this.date);
+ 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.WriteAsync(response);
+ ctx.WriteAndFlushAsync(response);
+ ctx.CloseAsync();
}
public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
{
- string channelId = context.Channel.Id.AsShortText();
- logger.LogError(exception, $"{channelId} {exception.Message}");
+ WriteResponse(context, Unpooled.WrappedBuffer(jT808WebAPIService.ErrorHttpResponse(exception).Data), TypeJson, jT808WebAPIService.ErrorHttpResponse(exception).Data.Length);
+ logger.LogError(exception, exception.Message);
context.CloseAsync();
}
diff --git a/src/JT808.DotNetty/Interfaces/IJT808SessionService.cs b/src/JT808.DotNetty/Interfaces/IJT808SessionService.cs
index 7eddb27..4b7dcfa 100644
--- a/src/JT808.DotNetty/Interfaces/IJT808SessionService.cs
+++ b/src/JT808.DotNetty/Interfaces/IJT808SessionService.cs
@@ -8,7 +8,7 @@ namespace JT808.DotNetty.Interfaces
///
/// JT808会话服务
///
- public interface IJT808SessionService
+ internal interface IJT808SessionService
{
///
/// 获取真实连接数
diff --git a/src/JT808.DotNetty/Interfaces/IJT808UnificationSendService.cs b/src/JT808.DotNetty/Interfaces/IJT808UnificationSendService.cs
index 2477e7b..b7434c3 100644
--- a/src/JT808.DotNetty/Interfaces/IJT808UnificationSendService.cs
+++ b/src/JT808.DotNetty/Interfaces/IJT808UnificationSendService.cs
@@ -8,7 +8,7 @@ namespace JT808.DotNetty.Interfaces
///
/// JT808统一下发命令
///
- public interface IJT808UnificationSendService
+ internal interface IJT808UnificationSendService
{
JT808ResultDto Send(string terminalPhoneNo, byte[] data);
}
diff --git a/src/JT808.DotNetty/JT808DotnettyExtensions.cs b/src/JT808.DotNetty/JT808DotnettyExtensions.cs
index 4951a61..b151ec8 100644
--- a/src/JT808.DotNetty/JT808DotnettyExtensions.cs
+++ b/src/JT808.DotNetty/JT808DotnettyExtensions.cs
@@ -24,9 +24,10 @@ namespace JT808.DotNetty
services.TryAddScoped();
services.TryAddScoped();
services.TryAddScoped();
- services.TryAddScoped();
services.TryAddSingleton();
services.TryAddSingleton();
+ services.TryAddScoped();
+ services.TryAddScoped();
services.AddHostedService();
services.AddHostedService();
});
diff --git a/src/JT808.DotNetty/JT808SessionManager.cs b/src/JT808.DotNetty/JT808SessionManager.cs
index a8d3c37..178971e 100644
--- a/src/JT808.DotNetty/JT808SessionManager.cs
+++ b/src/JT808.DotNetty/JT808SessionManager.cs
@@ -13,31 +13,18 @@ using JT808.DotNetty.Metadata;
namespace JT808.DotNetty
{
- public class JT808SessionManager: IDisposable
+ public class JT808SessionManager
{
private readonly ILogger logger;
+
private readonly JT808Configuration configuration;
- private readonly CancellationTokenSource cancellationTokenSource;
+
public JT808SessionManager(
IOptions jT808ConfigurationAccessor,
ILoggerFactory loggerFactory)
{
logger = loggerFactory.CreateLogger();
configuration = jT808ConfigurationAccessor.Value;
- cancellationTokenSource = new CancellationTokenSource();
- Task.Run(() =>
- {
- while (!cancellationTokenSource.IsCancellationRequested)
- {
- logger.LogInformation($"Online Count>>>{RealSessionCount}");
- if (RealSessionCount > 0)
- {
- logger.LogInformation($"SessionIds>>>{string.Join(",", SessionIdDict.Select(s => s.Key))}");
- logger.LogInformation($"TerminalPhoneNos>>>{string.Join(",", TerminalPhoneNo_SessionId_Dict.Select(s => $"{s.Key}-{s.Value}"))}");
- }
- Thread.Sleep(configuration.SessionReportTime);
- }
- }, cancellationTokenSource.Token);
}
///
@@ -212,12 +199,7 @@ namespace JT808.DotNetty
{
return SessionIdDict.Join(TerminalPhoneNo_SessionId_Dict, m => m.Key, s => s.Value, (m, s) => m.Value).ToList();
}
-
- public void Dispose()
- {
- cancellationTokenSource.Cancel();
- cancellationTokenSource.Dispose();
- }
+
}
}
diff --git a/src/JT808.DotNetty/JT808WebAPIServerHost.cs b/src/JT808.DotNetty/JT808WebAPIServerHost.cs
index 6e0c39c..7aea178 100644
--- a/src/JT808.DotNetty/JT808WebAPIServerHost.cs
+++ b/src/JT808.DotNetty/JT808WebAPIServerHost.cs
@@ -9,10 +9,8 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
-using System.Collections.Generic;
using System.Net;
using System.Runtime.InteropServices;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -61,9 +59,11 @@ namespace JT808.DotNetty
IChannelPipeline pipeline = channel.Pipeline;
using (var scope = serviceProvider.CreateScope())
{
- pipeline.AddLast("encoder", new HttpResponseEncoder());
- pipeline.AddLast("decoder", new HttpRequestDecoder(4096, 8192, 8192, false));
- pipeline.AddLast("jt808webapihandler", scope.ServiceProvider.GetRequiredService());
+ pipeline.AddLast("http_encoder", new HttpResponseEncoder());
+ pipeline.AddLast("http_decoder", new HttpRequestDecoder(4096, 8192, 8192, false));
+ //将多个消息转换为单一的request或者response对象 =>IFullHttpRequest
+ pipeline.AddLast("http_aggregator", new HttpObjectAggregator(65536));
+ pipeline.AddLast("http_jt808webapihandler", scope.ServiceProvider.GetRequiredService());
}
}));
logger.LogInformation($"WebAPI Server start at {IPAddress.Any}:{configuration.WebAPIPort}.");
diff --git a/src/JT808.DotNetty/JT808WebAPIService.cs b/src/JT808.DotNetty/JT808WebAPIService.cs
new file mode 100644
index 0000000..bf75288
--- /dev/null
+++ b/src/JT808.DotNetty/JT808WebAPIService.cs
@@ -0,0 +1,214 @@
+using JT808.DotNetty.Dtos;
+using JT808.DotNetty.Interfaces;
+using JT808.DotNetty.Metadata;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.DotNetty
+{
+ internal class JT808WebAPIService
+ {
+ public Dictionary> HandlerDict { get; protected set; }
+
+ private const string RouteTablePrefix = "/jt808api";
+
+ private const string sessionRoutePrefix = "Session";
+
+ private readonly IJT808SessionService jT808SessionService;
+
+ private readonly IJT808UnificationSendService jT808UnificationSendService;
+
+ ///
+ /// 初始化消息处理业务
+ ///
+ protected JT808WebAPIService(
+ IJT808SessionService jT808SessionService,
+ IJT808UnificationSendService jT808UnificationSendService)
+ {
+ this.jT808SessionService = jT808SessionService;
+ this.jT808UnificationSendService = jT808UnificationSendService;
+ HandlerDict = new Dictionary>
+ {
+ {$"{RouteTablePrefix}/UnificationSend", UnificationSend},
+ {$"{RouteTablePrefix}/{sessionRoutePrefix}/GetRealLinkCount", GetRealLinkCount},
+ {$"{RouteTablePrefix}/{sessionRoutePrefix}/GetRelevanceLinkCount", GetRelevanceLinkCount},
+ {$"{RouteTablePrefix}/{sessionRoutePrefix}/GetRealAll", GetRealAll},
+ {$"{RouteTablePrefix}/{sessionRoutePrefix}/GetRelevanceAll", GetRelevanceAll},
+ {$"{RouteTablePrefix}/{sessionRoutePrefix}/RemoveByChannelId", RemoveByChannelId},
+ {$"{RouteTablePrefix}/{sessionRoutePrefix}/RemoveByTerminalPhoneNo", RemoveByTerminalPhoneNo},
+ {$"{RouteTablePrefix}/{sessionRoutePrefix}/GetByChannelId", GetByChannelId},
+ {$"{RouteTablePrefix}/{sessionRoutePrefix}/GetByTerminalPhoneNo", GetByTerminalPhoneNo},
+ };
+ }
+
+ ///
+ /// 统一下发信息
+ ///
+ ///
+ ///
+ public JT808HttpResponse UnificationSend(JT808HttpRequest request)
+ {
+ if (string.IsNullOrEmpty(request.Json))
+ {
+ return EmptyHttpResponse();
+ }
+ JT808UnificationSendRequestDto jT808UnificationSendRequestDto = JsonConvert.DeserializeObject(request.Json);
+ var result = jT808UnificationSendService.Send(jT808UnificationSendRequestDto.TerminalPhoneNo, jT808UnificationSendRequestDto.Data);
+ return CreateJT808HttpResponse(result);
+ }
+
+ ///
+ /// 会话服务-获取真实连接数
+ ///
+ ///
+ ///
+ public JT808HttpResponse GetRealLinkCount(JT808HttpRequest request)
+ {
+ var result = jT808SessionService.GetRealAll();
+ return CreateJT808HttpResponse(result);
+ }
+
+ ///
+ /// 会话服务-获取设备相关连的连接数
+ ///
+ ///
+ ///
+ public JT808HttpResponse GetRelevanceLinkCount(JT808HttpRequest request)
+ {
+ var result = jT808SessionService.GetRelevanceLinkCount();
+ return CreateJT808HttpResponse(result);
+ }
+
+ ///
+ /// 会话服务-获取实际会话集合
+ ///
+ ///
+ ///
+ public JT808HttpResponse GetRealAll(JT808HttpRequest request)
+ {
+ var result = jT808SessionService.GetRealAll();
+ return CreateJT808HttpResponse(result);
+ }
+
+ ///
+ /// 会话服务-获取设备相关连会话集合
+ ///
+ ///
+ ///
+ public JT808HttpResponse GetRelevanceAll(JT808HttpRequest request)
+ {
+ var result = jT808SessionService.GetRelevanceAll();
+ return CreateJT808HttpResponse(result);
+ }
+
+ ///
+ /// 会话服务-通过通道Id移除对应会话
+ ///
+ ///
+ ///
+ public JT808HttpResponse RemoveByChannelId(JT808HttpRequest request)
+ {
+ if (string.IsNullOrEmpty(request.Json))
+ {
+ return EmptyHttpResponse();
+ }
+ var result = jT808SessionService.RemoveByChannelId(request.Json);
+ return CreateJT808HttpResponse(result);
+ }
+
+ ///
+ /// 会话服务-通过设备终端号移除对应会话
+ ///
+ ///
+ ///
+ public JT808HttpResponse RemoveByTerminalPhoneNo(JT808HttpRequest request)
+ {
+ if (string.IsNullOrEmpty(request.Json))
+ {
+ return EmptyHttpResponse();
+ }
+ var result = jT808SessionService.RemoveByTerminalPhoneNo(request.Json);
+ return CreateJT808HttpResponse(result);
+ }
+
+ ///
+ /// 会话服务-通过通道Id获取会话信息
+ ///
+ ///
+ ///
+ public JT808HttpResponse GetByChannelId(JT808HttpRequest request)
+ {
+ if (string.IsNullOrEmpty(request.Json))
+ {
+ return EmptyHttpResponse();
+ }
+ var result = jT808SessionService.GetByChannelId(request.Json);
+ return CreateJT808HttpResponse(result);
+ }
+
+ ///
+ /// 会话服务-通过设备终端号获取会话信息
+ ///
+ ///
+ ///
+ public JT808HttpResponse GetByTerminalPhoneNo(JT808HttpRequest request)
+ {
+ if (string.IsNullOrEmpty(request.Json))
+ {
+ return EmptyHttpResponse();
+ }
+ var result = jT808SessionService.GetByTerminalPhoneNo(request.Json);
+ return CreateJT808HttpResponse(result);
+ }
+
+ private JT808HttpResponse CreateJT808HttpResponse(dynamic dynamicObject)
+ {
+ byte[] data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(dynamicObject));
+ return new JT808HttpResponse()
+ {
+ Data = data
+ };
+ }
+
+ public JT808HttpResponse DefaultHttpResponse()
+ {
+ byte[] json = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new JT808DefaultResultDto()));
+ return new JT808HttpResponse(json);
+ }
+
+ public JT808HttpResponse EmptyHttpResponse()
+ {
+ byte[] json = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new JT808ResultDto()
+ {
+ Code=201,
+ Message="内容为空",
+ Data="Content Empty"
+ }));
+ return new JT808HttpResponse(json);
+ }
+
+ public JT808HttpResponse NotFoundHttpResponse()
+ {
+ byte[] json = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new JT808ResultDto()
+ {
+ Code=404,
+ Message="没有该服务",
+ Data= "没有该服务"
+ }));
+ return new JT808HttpResponse(json);
+ }
+
+ public JT808HttpResponse ErrorHttpResponse(Exception ex)
+ {
+ byte[] json = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new JT808ResultDto()
+ {
+ Code = 500,
+ Message = JsonConvert.SerializeObject(ex),
+ Data= ex.Message
+ }));
+ return new JT808HttpResponse(json);
+ }
+ }
+}
diff --git a/src/JT808.DotNetty/Metadata/JT808HttpRequest.cs b/src/JT808.DotNetty/Metadata/JT808HttpRequest.cs
new file mode 100644
index 0000000..6a16264
--- /dev/null
+++ b/src/JT808.DotNetty/Metadata/JT808HttpRequest.cs
@@ -0,0 +1,22 @@
+using JT808.Protocol;
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace JT808.DotNetty.Metadata
+{
+ public class JT808HttpRequest
+ {
+ public string Json { get; set; }
+
+ public JT808HttpRequest()
+ {
+
+ }
+
+ public JT808HttpRequest(string json)
+ {
+ Json = json;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/JT808.DotNetty/Metadata/JT808HttpResponse.cs b/src/JT808.DotNetty/Metadata/JT808HttpResponse.cs
new file mode 100644
index 0000000..4ab0b95
--- /dev/null
+++ b/src/JT808.DotNetty/Metadata/JT808HttpResponse.cs
@@ -0,0 +1,22 @@
+using JT808.Protocol;
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace JT808.DotNetty.Metadata
+{
+ public class JT808HttpResponse
+ {
+ public byte[] Data { get; set; }
+
+ public JT808HttpResponse()
+ {
+
+ }
+
+ public JT808HttpResponse(byte[] data)
+ {
+ this.Data = data;
+ }
+ }
+}
\ No newline at end of file