基于上篇介绍的命令通讯思路,我在JSTS里编写了命令处理的相关组件。主要包含以下几个部分:
1. Socket/WebSocket组件
2. Message消息中间件
3. 通讯事件处理组件
下面我将通过介绍jsts中的测试代码,来讲相关思路和用法。
应用的程序入口类:JstsApplication
public static void main( String[] args ) {
SpringApplication.run(JstsApplication.class, args);
CommonContextHolder.getBean( IServerService.class ).onload();
}
作为服务器使用时,我们需要先实现IServerService中的相关方法,jsts中提供了AbsServerService的抽象类,主要包含onload、unload、reload这3个方法。可以理解为加载、卸载、重载的函数入口。
在AbsServerSerivce中的主要代码:
if(CommonConfig.getBoolean( Netty_Socket_Enable, true ) ){
CommonContextHolder.getBean( ISupportSocket.class ).onload();
log.debug( "--服务器支持[Socket]已加载." );
}
if(CommonConfig.getBoolean( Netty_WebSocket_Enable, true ) ) {
CommonContextHolder.getBean(ISupportWebSocket.class).onload();
log.debug("--服务器支持[WebSocket]已加载.");
}
if(CommonConfig.getBoolean( Netty_Connector_Enable, true ) ) {
CommonContextHolder.getBean(IConnectorService.class).onload();
log.debug("--服务器支持[连接器]已加载.");
}
在《Netty实战手册》中,我介绍了jsts将Netty的服务器通讯结构封装为了以下几个部分:
/**
* 客户端事件处理器
* @return
*/
@Bean
public ISupportHandler<ChannelHandlerContext, Object > supportHandler(){
return new AbsHandlerService<ChannelHandlerContext, Object>() {
@SuppressWarnings( "unchecked" )
@Override
/** 收到客户端消息 **/
public void receive(ChannelHandlerContext _ctx, Object _obj) {
CommonContextHolder.getBean( IRequestHandler.class ).request( _ctx, _obj );
}
@Override
/** 客户端连接 **/
public void enter(ChannelHandlerContext _ctx) {}
@Override
/** 客户端断开 **/
public void leave(ChannelHandlerContext _ctx) {}
@Override
/** 客户端中断 **/
public void standby(ChannelHandlerContext _ctx) {}
@Override
/** 客户端恢复连接 **/
public void recovery(ChannelHandlerContext _ctx) {}
@Override
/** 客户端连接异常 **/
public void error(ChannelHandlerContext _ctx, Throwable _thr) {}
};
}
在收到消息时,会通过IRequestHandler进行转发,通过消息中间件找到对应的命令,并执行,这个过程通过反射完成。可以参考上篇或者jsts源码。
命令事件处理类:JstsModel
@MessageLabel( "测试命令" )
public static final int CMD_TEST = 100;
@Autowired
ISupportHandler handler;
@SuppressWarnings( "unchecked" )
@MessageRequest( CMD_TEST )
public void request0( ChannelHandlerContext _ctx, Message _msg ){
System.out.println( "--request0" );
handler.send( _ctx, _msg );
}
@MessageResponse( CMD_TEST )
public void response0( ChannelHandlerContext _ctx, Message _msg ){
System.out.println( "--response0" );
}
服务器间的通讯或者客户端和服务器的通讯,实现方式和上述基本一致,实现类和接口不同而已。
另外Message类,通过定义消息的结构体,由protostuff来完成消息内容的相关转换。详细内容见MessageDecoder类。(注:这里其实想把MessageDecoder分为decode和encode 这2个部分的,后续版本可能会调整)
对于需要数据处理的同学,则通过导入jdbs部分,在JstsModel类中加入2个部分即可实现:
@Autowired
AbsDao dao; //建议继承BaseDao使用,而不是直接继承AbsDao
@Transactional
@MessageResponse( CMD_TEST )
public void request0( ChannelHandlerContext _ctx, Message _msg ){}
完整的代码实例,请前往以下地址:
https://github.com/aiyoyoyo/jeesupport
喜欢的朋友请给赞,并继续支持一下。