采集项目总结
一、项目简介
本采集系统的基本功能是通过TCP/IP协议长连接基站,将基站上传的字节流根据协议解析为相应的基站和定位卡信息,过滤后进行持久化,提供访问页面供用户查询定位信息;用户可通过采集系统须对基站、位置、卡等相关实体进行管理。
系统用户分为两类,应用系统用户和管理员。
二、项目架构图
三、Ehcache在项目中的应用
Ehcache缓存数据,在Mina handler类中收到卡定位信息后直接放到缓存中,不直接与数据库交互,与数据库的交互放在缓存监听器类中。这里有一个问题是ehcache与Spring 的整合中没有提供缓存与监听器的绑定。只能手工实现,例:
A、
<cache name="alarmrecordCache" maxElementsInMemory="200"
eternal="false"
timeToIdleSeconds="30" overflowToDisk="false"
memoryStoreEvictionPolicy="LFU">
<cacheEventListenerFactory
class="com.**.listener.CacheEventListenerFactory"
properties="bean=alarmRecordListener"/>
</cache>
B、
<bean id="alarmRecordListener"
class="com.**.listener.AlarmRecordListener" lazy-init="false">
<property name="alarminfoService" ref="alarminfoService">
</property>
</bean>
C、
public class CacheEventListenerFactory extends
net.sf.ehcache.event.CacheEventListenerFactory{
@Override
public CacheEventListener createCacheEventListene (Properties properties) {
String beanName = properties.getProperty( "bean" );
if ( beanName == null ) {
throw new IllegalArgumentException( "缓存监听器名字未定义" );
}
return (CacheEventListener)
SpringContextTool.getApplicationContext().getBean( beanName );
}
}
四、基站分2种:小区与CDMA ,小区基站有固定ip ,CDMA基站无固定ip,通过发送消息通过sim卡->移动->互联网,所以CDMA的ip地址是变动的。业务中有要求给CDMA下发指令,因为没有固定ip ,所以只能广播。这样就有一个问题,广播时会有很多“远程主机已经关闭”错误,因为该ip的连接已经没有了。
解决:将所有下发的命令先存放在一个HashMap(Integer,List),integer 为基站编号,List 中存放命令,命令可能有多条。当CDMA基站向服务器发送信息,SessionOpened 时间中增加代码:根据基站编号查询命令并下发。即:CDMA打开连接时下发命令,基本上这个时候连接还在的。
A、
public class CdmaSendCommandSupport {
/**
* 数据存放格式 integer -> 基站号 List<AbstractCommond> -> 命令LIST
*/
public static HashMap<Integer, List<AbstractCommond>> cdmaCommandMap = new HashMap<Integer, List<AbstractCommond>>();
/**
* 把命令放到 Map 中去
*/
public static void putCommandToQueue(int readerid, AbstractCommond c) {
if (readerid == 0) {
ApplicationContext appContext = SpringContextTool.getApplicationContext();
ReaderService readerService = (ReaderService) appContext.getBean("readerService");
@SuppressWarnings("rawtypes")
List idList = readerService.loadAllCdmaReaderid();
for (int i = 0; i < idList.size(); i++) {
List<AbstractCommond> cList = CdmaSendCommandSupport.cdmaCommandMap
.get((Integer) idList.get(i));
if (cList == null) {
cList = new ArrayList<AbstractCommond>();
}
cList.add(c);
CdmaSendCommandSupport.cdmaCommandMap.put((Integer) idList.get(i), cList);
}
} else {
List<AbstractCommond> cList = CdmaSendCommandSupport.cdmaCommandMap
.get(new Integer(readerid));
if (cList == null) {
cList = new ArrayList<AbstractCommond>();
}
cList.add(c);
CdmaSendCommandSupport.cdmaCommandMap.put(new Integer(readerid),cList);
}
}
}
B、
// 1、处理未发送的命令
List<AbstractCommond> cList = CdmaSendCommandSupport.cdmaCommandMap
.get(readerState.getReaderId());
if (cList != null) {
for (AbstractCommond c : cList)
session.write(c);
CdmaSendCommandSupport.cdmaCommandMap.remove(readerState
.getReaderId());
}
五、枚举的应用
业务中遇到这样的问题,卡的类型,基站的类型,报警的类型都是使用的固定值,程序中要定义常量,数据库中也存在记录。容易造成不一致,最后采用了枚举,hibernate中有一个UserType接口用用来自定义与数据库的映射,注意这样修改后,相关的前台显示与查询均要修改。
public class EnumUserType<E extends Enum<E>> implements UserType {
private static final int[] sqlTypes = {Types.INTEGER };
private Class<E> clazz = null;
protected EnumUserType(Class<E> c) {
clazz = c;
if(!clazz.isEnum()){//检查是否是枚举类
throw new IllegalArgumentException(c+"不是枚举类");
}
if(!Identifiable.class.isAssignableFrom(clazz)){//检查是否实现Identifiable接口
throw new IllegalArgumentException(c+"未实现Identifiable接口");
}
}
@Override
public int[] sqlTypes() {
return sqlTypes;
}
@Override
public Class<E> returnedClass() {
return clazz;
}
@Override
public boolean equals(Object x, Object y){
if (x == y)
return true;
if (x == null || y == null)
return false;
else
return x.equals(y);
}
@Override
public int hashCode(Object x) {
return x.hashCode();
}
/**
* 把数据库中的查询结果集转换成相应的枚举类
*/
@Override
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
int id = rs.getInt(names[0]);
Object result = null;
if (!rs.wasNull())
result = getEnumByID(id);
return result;
}
/**
* 私有方法,配合Identifiable接口通过ID返回相应的枚举值
*/
private E getEnumByID(int id) {
E[] values = clazz.getEnumConstants();
E type = null;
for(E t : values){
if(id==((Identifiable)t).getID()){
type = t;
break;
}
}
if(type==null){
throw new HibernateException("ID为"+id+"的枚举类"+clazz.getName()+"不存在");
}
return type;
}
/**
* 配合Identifiable接口将枚举值转成int类型以存入数据库
*/
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
if (null == value)
st.setNull(index, Types.INTEGER);
else
st.setInt(index, ((Identifiable) value).getID());//必须实现Identifiable接口
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
@Override
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}
@Override
public Object replace(Object original, Object targer, Object owner)
throws HibernateException {
return original;
}
六、帮助类的应用
使用帮助类能更好的减低程序的耦合, 并且这些帮助类和方法一般定义为static,能减少内存占用,但是帮助类中经常会需要用到其他类,直接声明显然不太好。Spring有获取上下文,进而获取bean的方法。正好能用。
A、/**
* 持有Spring上下文
*/
public class SpringContextTool implements ApplicationContextAware {
private static ApplicationContext context;
public void setApplicationContext(ApplicationContext acx) {
context = acx;
}
public static ApplicationContext getApplicationContext() {
return context;
}
}
B、<bean name="springContextTool" class="com.yixun.middleware.util.SpringContextTool" lazy-init="false"></bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" depends-on="springContextTool">
<property name="location">
<value>classpath:system.properties</value>
</property>
</bean>
C、public static NioSocketAcceptor getNioSocketAcceptor() {
ApplicationContext context = SpringContextTool.getApplicationContext();
return (NioSocketAcceptor) context.getBean("areaNioAcceptor");
}
七、关于Mina解析
.....
分享到:
相关推荐
### 基于Flink的风电数据实时采集项目总结 #### 一、项目背景与概述 随着可再生能源的发展,风力发电作为一种清洁且可持续的能源形式,在全球范围内得到了广泛的应用。为了更好地管理和优化风电场的运行效率,实时...
在本风电实时采集项目中,我们利用了先进的大数据处理框架Flink进行实时数据的收集、处理和分析。Flink作为一种强大的流处理和批处理引擎,因其低延迟、高吞吐量以及状态管理能力而在现代大数据解决方案中占据重要...
【基于ARMLinux 视频采集系统项目总结报告】 一、项目概述与市场需求 本项目旨在构建一个基于ARMLinux的视频采集系统,以满足现代信息技术发展的需求。随着后PC时代的到来,传统的视频采集设备(如CCD摄像头和采集...
MES智慧车间项目总结涉及的知识点主要包括MES系统的应用、智慧工厂的实现、生产管理与优化以及信息化在生产中的价值。 MES,即制造执行系统(Manufacturing Execution System),是智能制造和智慧工厂的重要组成...
装配工艺推荐项目和车间数据采集与分析项目 - 项目总结 - 对外学习版V_qyt.pptx
总结,本技术方案详尽规划了一个数据采集处理项目的实施路径,从引言到具体的技术实现,全面覆盖了项目的目标、原则、规范以及关键技术。通过实施该项目,投资商和企业可以充分利用数据资源,提升业务决策的科学性和...
### 装配工艺推荐项目和车间数据采集与分析项目 - 项目总结 #### 一、项目背景与目标 该项目旨在提升企业的装配工艺编制水平,实现工艺数据的有效管理和利用。通过对现有工艺数据进行整理和分析,建立知识数据库,...
### 装配工艺推荐项目和车间数据采集与分析项目知识点总结 #### 一、项目背景及概述 **装配工艺推荐项目**与**车间数据采集与分析项目**旨在提升制造业中的装配工艺效率,并通过数据分析来优化生产流程。项目主要...
总结,这个项目涉及到LabVIEW的声卡接口编程、语音信号处理、实时数据采集和分析等多个方面,通过使用LabVIEW 8.5,我们可以构建一个高效的语音信号处理系统,对声卡采集的语音信号进行详尽的分析。在实际操作中,...
《信息采集服务总部项目管理细则》是针对信息采集类项目的一套全面管理规范,旨在确保项目高效、有序运行。该细则涵盖了从日常管理到财务管理、文案管理、安全管理等多个方面,旨在提高工作效率,保障服务质量,同时...
总结,月入10W+的自动采集站项目涉及到的技术和环节众多,包括但不限于爬虫技术、数据处理、网站开发、SEO优化、流量获取以及合法合规运营。要实现该项目的成功,需要深入了解并掌握这些方面,同时不断学习和跟进...
在F列的第二行我们输入以采集模块 采集代码 数仓模块 分析 展示模块 web客户端 通用模块 工具和数据库之间的通用联系客户端下内容:="INSERT INTO student (id,sex,name,age,grade) VALUES ("&A2;&",'"&B2;&"','"&C2...
【EN-C200项目总结报告1】 EN-C200项目是一个专注于温湿度数据采集、处理和上传至物联网平台的单板设计方案。该板卡具备控制物联网模拟场景的能力,并提供USB接口方便与PC通信,同时预留了扩展接口,允许用户自定义...
基于Python网络爬虫的二手房数据采集及可视化分析项目源码+使用教程+爬虫+报告PPT.zip已获导师认可并高分通过的毕业设计项目,代码完整,该资源代码都是经过测试运行成功,没有任何问题功能完整的情况下才上传的,...
在论文的结尾,作者会总结研究过程中的成果和经验,讨论系统可能存在的问题和改进方向。电信采集系统的持续发展将依赖于新技术的应用,例如人工智能和机器学习在数据预测和异常检测中的应用。 通过这篇毕业论文,...
在本案例中,“163K门户采集开源”可能是一个针对163K门户站点的开源采集项目,用户可以利用这个工具进行个性化的数据抓取。 对于"163K门户采集开源",我们可以推测这是一款专门针对163K门户站点设计的网络资源采集...
总结,C#串口数据采集与实时曲线显示是结合硬件通信和图形化界面的关键技术。通过SerialPort类处理串口通信,DataReceived事件监听数据,OxyPlot库绘制曲线,以及File类进行数据存储,我们可以构建出高效、实时的...
电子银行业务分析系统项目总结是关于软件开发全生命周期的一次深度反思,涵盖了需求分析、计划、质量控制、设计、开发、测试、沟通管理和技术前景等多个关键环节。在本项目中,作者强调了风险管理和有效沟通的重要性...
该项目是关于基于STM32微控制器的双路485总线系统,用于采集按键次数。STM32是一个广泛使用的微控制器系列,以其强大的处理能力和丰富的外设接口著称。485总线是一种常见的工业通信协议,适用于远距离、多节点的通信...