zoukankan      html  css  js  c++  java
  • 道路运输车辆卫星定位系统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小时后的结果:

             

             测试终端情况:

             

  • 相关阅读:
    搜索回车跳转页面
    登录验证码
    【排序算法】排序算法之插入排序
    PAT 乙级 1044 火星数字 (20 分)
    PAT 甲级 1035 Password (20 分)
    PAT 甲级 1041 Be Unique (20 分)
    PAT 甲级 1054 The Dominant Color (20 分)
    PAT 甲级 1027 Colors in Mars (20 分)
    PAT 甲级 1083 List Grades (25 分)
    PAT 甲级 1005 Spell It Right (20 分)
  • 原文地址:https://www.cnblogs.com/smark/p/6898101.html
Copyright © 2011-2022 走看看