Java Netty遊戲架構-JSTS內嵌
阿新 • • 發佈:2018-12-15
基於上篇介紹的命令通訊思路,我在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
喜歡的朋友請給贊,並繼續支援一下。