JT808 icon indicating copy to clipboard operation
JT808 copied to clipboard

JT808Serializer 序列化时 报 System.ArgumentOutOfRangeException 错误

Open 850759383 opened this issue 1 year ago • 3 comments
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;
        }
    }

850759383 avatar Jul 04 '24 04:07 850759383

对,我是先将消息体成一个大包,然后在进行分包;

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

850759383 avatar Jul 04 '24 04:07 850759383

能实现就好,还要啥优雅,这边可以用sizeof(JT808InflectionPointProperty)*count+4这样是不是就可以动态设置buffer的大小。

SmallChi avatar Jul 04 '24 04:07 SmallChi

写的挺好的,不用改啥了呀。666

SmallChi avatar Jul 04 '24 04:07 SmallChi