• 道路运输车辆卫星定位系统JT/T808服务实现和压测


            在工作上的需要接触道路运输车辆卫星定位系统相关应用,由于自己对网络服务的编写比较感兴趣,所以利用空闲时间实现了JT/T808的一些协议和相关服务(不得不说这种协议的设计在解释的确导致性能上的损耗,特别针地托管语言的C#来说就更加容易导致性能问题,不过对于现有硬件资源来说一台简配的PC支撑上几万个终端那还是没什么压力的).主要基于兴趣来写所以JT/T808只实现了几个常用的协议:0x0002,0x0200,0x0100等.

            为了更好地进行模拟测试还实现了一个简单的JT/T808模拟器方便进行一些简单的测试  

           

    消息封装

             一个好的消息封装会给消息扩展带来极大的方便和效率(不过不得不面对资源损耗的加大).Beetle.JT808采用对象结合特性的方式来描述一个JT808消息,特别对于一个多位组合的属性也通过对象化来表现,这样可以上使用者使用起来更方便和简单.

        /// <summary>
        /// 终端注册
        /// </summary>
        [MessageType(ID = 0x0100)]
        public class Register 
        {
            /// <summary>
            /// 标示终端安装车辆所在的省域,0保留,由平台取默认值。省域ID采用GB/T 2260中规定的行政区划代码六位中前两位
            /// </summary>
            [UInt16Handler]
            public ushort Province { get; set; }
            /// <summary>
            /// 标示终端安装车辆所在的市域和县域,0保留, 由平台取默认值。市县域ID采用GB/T 2260中规定的行政区划代码六位后四位
            /// </summary>
            [UInt16Handler]
            public ushort City { get; set; }
            /// <summary>
            /// 五个字节,终端制造商编码。
            /// </summary>
            [ASCIIHandler(5)]
            public string Provider { get; set; }
            /// <summary>
            /// 八个字节,此终端型号由制造商自行定义,位数不是八位的,补空格。
            /// </summary>
            [ASCIIHandler(8)]
            public string DeviceNumber { get; set; }
            /// <summary>
            /// 七个字节,由大写字母和数字组成,此终端ID由制造商自行定义
            /// </summary>
            [ASCIIHandler(7)]
            public string DeviceID { get; set; }
            /// <summary>
            /// 车牌颜色,按照JT/T 415-2006的5.4.12
            /// </summary>
            [ByteHandler]
            public byte Color { get; set; }
            /// <summary>
            /// 公安交通管理部门颁发的机动车号牌
            /// </summary>
            [GBKHandler]
            public string PlateNumber { get; set; }
        }
    }

    服务器封装

            有服务端封装上也是采购消息事件来驱动消息逻辑的处理,这样在扩展消息处理上也非常方便

            protected virtual void OnPostion(Message msg, Messages.Postion e, Beetle.Express.IChannel channel)
            {
                channel.Name = msg.SIM;
                channel["GPS_INFO"] = e;
                if (Loger.Enabled(LogType.DEBUG))
                    Loger.Process(LogType.DEBUG, "{0} postion lng:{1}/lat:{2} time:{3}", msg.SIM, e.Longitude, e.Latitude, e.Time);
                ReturnCenterResponse(msg, channel);
            }
    
            protected virtual void OnRegister(Message msg, Messages.Register e, Beetle.Express.IChannel channel)
            {
                if (Loger.Enabled(LogType.DEBUG))
                    Loger.Process(LogType.DEBUG, "{0} registed platenumber:{1}", msg.SIM, e.PlateNumber);
                Message result = MessageFactory.CreateMessage<RegisterResponse>(msg.SIM);
                RegisterResponse response = result.GetBody<RegisterResponse>();
                response.BusinessNO = msg.BussinessNO;
                response.Result = RegisterStatus.Success;
                response.Signature = Guid.NewGuid().ToString("N");
                result.Send(channel);
            }
    
            protected virtual void OnSignature(Message msg, Messages.ClientSignature e, Beetle.Express.IChannel channel)
            {
                if (Loger.Enabled(LogType.DEBUG))
                    Loger.Process(LogType.DEBUG, "{0} signature {1}", msg.SIM, e.Signature);
                ReturnCenterResponse(msg, channel);
            }
    
            protected virtual void OnNotImplement(Message msg, Messages.MessageNotImplement e, Beetle.Express.IChannel channel)
            {
                if (Loger.Enabled(LogType.DEBUG))
                    Loger.Process(LogType.DEBUG, "{0} message:{1} not implement!", msg.SIM, e.MessageID);
                ReturnCenterResponse(msg, channel);
            }

    压测结果

            虽然对服务功能进行了大量的抽象封装,在效率上会有很大的开销损耗.但在现有的硬件资源下并不会存在多大问题.以下是模拟10000个终端设备每5秒提交一条车辆行驶信息的测试情况:

            服务端是一台虚拟化的4核,16G内存的电脑.

            行车信息:

                    Messages.Postion postion = new Messages.Postion();
                    postion.Direction = (ushort)ran.Next(ushort.MinValue, ushort.MaxValue);
                    postion.Height = (ushort)ran.Next(ushort.MinValue, ushort.MaxValue);
                    postion.Latitude = (uint)ran.Next(0, 2000000);
                    postion.Longitude = (uint)ran.Next(0, 2000000);
                    postion.Speed = (ushort)ran.Next(ushort.MinValue, ushort.MaxValue);
                    postion.Time = DateTime.Now;
                    postion.FuelGauge.Value = (ushort)ran.Next(ushort.MinValue, ushort.MaxValue);
                    postion.Milometer.Value = (uint)ran.Next(0, 2000000);
                    postion.Speedometer.Value = (ushort)ran.Next(10, 200);
                    Client.Postion(postion);

            服务器压力17小时后的结果:

             

             测试终端情况:

             

  • 相关阅读:
    Servlet3.0-使用注解定义Servlet
    poj 1256 Anagram—next_permutation的神奇应用
    poj 1664 放苹果 (划分数)
    poj 1011 Sticks
    poj和hdu部分基础算法分类及难度排序
    Notepad++支持jQuery、html5、css3
    Codeforces Round #395 (Div. 2) C. Timofey and a tree
    Codeforces Round #390 (Div. 2) D. Fedor and coupons
    bazel-编译动态库
    bazel-编译多目标
  • 原文地址:https://www.cnblogs.com/smark/p/6898101.html
Copyright © 2020-2023  润新知