Java作为一种跨平台的开发语言,被广泛地应用,对比C++来讲,不需要关心对象的释放,缓冲区的管理,使编程的细节处理上要简单了很多,但是在高负载、多线程、多任务的协作处理时,对象的频繁new,线程的频繁创建、销毁,仍有可能导致程序的异常崩溃;每一次网络开发的调试都是一个几乎要崩溃的过程,各种细节的处理会导致开发过程缓慢、周期变长,本文通过对NIO和线程池的调度封装,使服务端的高并发、网络信息传送简化成了命令的传送,让开发的整个过程规范化,使程序员在相应开发时只需注意业务的处理,将所有的网络端、多线程设定和管理简化成了配置文件。
下面我先给出一段使用封装后的库进行网络开发的实例。
//这个参数类是创建服务所需要的一些配置参数,这些参数可以通过命令行或配件文件进行传递
//这里我们只看一下它的结构,而不用关心具体的内容
public class SceneParameter
{
public int m_iReconnectCount = Integer.MAX_VALUE;
public long m_lReconnectIntervalMSEL = 5 * 1000;
/**
* CipherKeyService监听地址
*/
public InetSocketAddress m_remoteAddressCipherKeyService = null;
/**
* CompensationService监听地址
*/
public InetSocketAddress m_remoteAddressCompensationService = null;
/**
* MulticastSourceService监听地址
*/
public InetSocketAddress m_remoteAddressMulticastSourceService = null;
/**
* PublicNetworkService监听地址
*/
public InetSocketAddress m_remoteAddressPublicNetworkService = null;
/**
* CompensationService远程连接地址的long型表示
* 高32位保存了端口号,
* 低32位保存了IP地址;
*/
public long m_lCompensationServiceAddress = 0;
public MySceneLog m_mySenceLog;
}
我们为每一个服务端所需要的配置创建一个参数类,参数类中的内容可以是由命令行或者配置文件来赋值,这个参数类做为创建服务时传递的参数。
public class AssignSceneAddressService
{
/**
* 版本号
*/
private static String s_strVersion = "V1.0.3.2020.02.23.20.11";
static class AppParameter
{
public String m_strConfigFile = "AssignSceneAddressService.config";
}
public static void main(String[] args)
{
try
{
//Tcp监听服务,用于终端与CompensationServer的连接
//CompensationServer主动与组播服务器建立连接
SceneParameter sp = new SceneParameter();
TcpServerParameter tsp = new TcpServerParameter(null, null);
tsp.m_nioTcpParameter = new NioTcpParameter();
//应该将服务端的配置变成配置文件
AppParameter ap = new AppParameter();
AssignSceneAddressServiceConfig asasc = AssignSceneAddressService.parseCmdLine( ap, args, "=");
sp.setCompensationServiceRemoteAddress( asasc.m_remoteCompensationServiceConfig.getInetSocketAddress() );
sp.m_remoteAddressCipherKeyService = asasc.m_remoteCipherKeyServiceConfig.getInetSocketAddress();
sp.m_remoteAddressMulticastSourceService = asasc.m_remoteMulticastSourceServiceConfig.getInetSocketAddress();
sp.m_remoteAddressPublicNetworkService = asasc.m_publicNetworkServiceConfig.getInetSocketAddress();
sp.m_iReconnectCount = asasc.m_nioTcpConnectorParmeterConfig.m_iReconnectCount;
sp.m_lReconnectIntervalMSEL = asasc.m_nioTcpConnectorParmeterConfig.m_lReconnectIntervalMSEL;
tsp.m_strBindAddress = asasc.m_remoteAssignSceneAddressServiceConfig.m_strBindAddress;
tsp.m_iListenPort = asasc.m_remoteAssignSceneAddressServiceConfig.m_iPort;
tsp.m_iMaxSelectorCount = asasc.m_iMaxSelectorCount;
asasc.m_nioTcpParameterConfig.copyTo( tsp.m_nioTcpParameter );
//这里可以根据参数,决定选用哪一种Log
sp.m_mySenceLog = new MySceneLog();
LogLevel.setLogOutLevel( asasc.m_logOutConfig.m_lLogOutLevel );
//LogLevel.getLogFile().setJsonLogFileConfig( asasc.m_logFileConfig );
//LogLevel.getLogFile().startThread();
LogLevel.getLogFileEx().setJsonLogFileConfig( asasc.m_logFileConfig );
LogLevel.getLogFileEx().startThread();
LogLevel.outputToLogFile( Convenient.s_dfFullDateTime.format(new Date(System.currentTimeMillis()))
+ " SMKE - AssignSceneAddressService is running! " + AssignSceneAddressService.s_strVersion
+ "; \r\n\tListen address is " + tsp.getAddress()
+ "; \r\n\tPublic network service address is " + sp.getPublicNetworkServiceRemoteAddress()
+ "; \r\n\tMulticast source service address is " + sp.getMulticastSourceServiceRemoteAddress()
+ "; \r\n\tCompensation service address is " + sp.getCompensationServiceRemoteAddress()
+ "; \r\n\tCipherKey service address is " + sp.getCipherKeyServiceRemoteAddress() );
//创建服务的处理线程
ne