JT808
JT808 copied to clipboard
JT808Serializer 序列化时 报 System.ArgumentOutOfRangeException 错误
trafficstars
当下发 JT808_0x8606 设置路线命令时候,下发拐点过多会导致 ArrayPool 数组长度不够,需要手动传入minBufferSize参数。现在我是预估100个顶点为4096,1000个为40960,以此类推,然后进行分包。请问是否有更优雅的实现方式?谢谢
public void Test1()
{
var body = new JT808_0x8606()
{
RouteId = 111,
RouteProperty = 0b00101000
};
var points = new List<JT808InflectionPointProperty>();
for (int i = 1000; i > 0; i--) //1000个拐点
{
points.Add(new JT808InflectionPointProperty()
{
InflectionPointId = 1,
SectionId = 1,
InflectionPointLat = 33000000,
InflectionPointLng = 33000000,
SectionWidth = 20,
SectionProperty = (byte) (0b00000010),
SectionHighestSpeed = 40,
SectionOverspeedDuration = 5,
});
}
body.InflectionPointItems = points;
body.InflectionPointCount = (ushort) points.Count;
try
{
var a = JT808Serializer.Serialize(body, JT808Version.JTT2013, 40960); //默认为4096
Console.WriteLine(a);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
对,我是先将消息体成一个大包,然后在进行分包;
/// <summary>
/// 设置路线
/// </summary>
/// <param name="terminalPhoneNo">终端手机号</param>
/// <param name="lineData">线路数据</param>
/// <param name="waitForResponse"></param>
/// <returns></returns>
public async Task<CmdResult> SetLine(string terminalPhoneNo, SetLineData lineData,
bool waitForResponse = true)
{
if (!IsVehicleOline(terminalPhoneNo, out var session))
{
return new CmdResult()
{
Success = false,
Message = "当前车辆不在线"
};
}
var body = new JT808_0x8606()
{
RouteId = lineData.RouteId,
RouteProperty = 0b00101000
};
if (cmdStatus.TryGetValue($"{terminalPhoneNo}_{body.MsgId:X}", out var time))
{
if ((DateTime.Now - time).TotalSeconds < 30)
{
return new CmdResult()
{
Success = false,
Message = terminalPhoneNo + " 等待设备回复中"
};
}
}
var points = new List<JT808InflectionPointProperty>();
foreach (var lineDataPoint in lineData.Points)
{
points.Add(new JT808InflectionPointProperty()
{
InflectionPointId = lineDataPoint.PointId,
SectionId = lineDataPoint.PointId,
InflectionPointLat = lineDataPoint.Lat,
InflectionPointLng = lineDataPoint.Lng,
SectionWidth = lineDataPoint.Width,
SectionProperty = (byte) (lineDataPoint.IsSpeedLimit ? 0b00000010 : 0),
SectionHighestSpeed = lineDataPoint.MaxSpeed,
SectionOverspeedDuration = 5,
});
}
body.InflectionPointItems = points;
body.InflectionPointCount = (ushort) points.Count;
_logger.LogInformation("下发线路 顶点数 " + points.Count);
var splitPackages = GetSplitPackageBytes(body);
var msgNum = GetMsgNum();
for (var i = 0; i < splitPackages.Length; i++)
{
var package = new JT808Package
{
Header = new JT808Header
{
MsgId = 0x8606,
TerminalPhoneNo = terminalPhoneNo,
ManualMsgNum = msgNum,
MessageBodyProperty = new JT808HeaderMessageBodyProperty()
{
IsPackage = true,
},
PackgeCount = (ushort) splitPackages.Length,
PackageIndex = (ushort)(i + 1)
},
SubDataBodies = splitPackages[i].Data
};
var bytes = JT808Serializer.Serialize(package);
session.SendAsync(bytes);
_logger.LogInformation("序号:" + package.Header.ManualMsgNum);
}
if (!waitForResponse)
{
return new CmdResult()
{
Success = false,
Message = "命令下发成功"
};
}
var result = await WaitForResponse(terminalPhoneNo, body, msgNum);
return result;
}
/// <summary>
/// 获取分包数据
/// </summary>
/// <param name="bodies"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public JT808SplitPackageProperty[] GetSplitPackageBytes<T>(T bodies) where T: JT808Bodies
{
return Jt808Config.SplitPackageStrategy.Processor(JT808Serializer.Serialize(bodies, JT808Version.JTT2013, 40960)).ToArray();
}
能实现就好,还要啥优雅,这边可以用sizeof(JT808InflectionPointProperty)*count+4这样是不是就可以动态设置buffer的大小。
写的挺好的,不用改啥了呀。666