1. 程式人生 > >Java Netty遊戲架構-JSTS內嵌

Java Netty遊戲架構-JSTS內嵌

基於上篇介紹的命令通訊思路,我在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

喜歡的朋友請給贊,並繼續支援一下。