花十分鐘時間給JFinal寫了個tio插件

本人 JFinal 腦殘粉,最近公司幾個項目都須要跟硬件交互,這就得用到長鏈接,以前一直沒接觸過該領域,原本還想花時間研究下netty,講真挺難啃的,找資料的時候翻到 t-io,略微瞭解發現彷佛學習成本極低,沒想到做者本人也極其nice,解答我這個門外小夥子好多個問題,順利用上此框架,恰好解了個人燃眉之急。java

什麼是 t-io? t-io是基於java aio實現的即時通信框架,源於做者另外一個久經考驗的talent-nio框架,但在易用性、性能及代碼可讀性方面又遠遠超越了talent-nio。git

順便放上傳送門:https://my.oschina.net/talenttan/blog/863545api

最新demo代碼:https://gitee.com/xiaoxustudent/jfinal-tio服務器

廢話不說,下面正題:框架

  1. 下載talent-aio的demo,demo極其簡單,主要仍是看HelloAbsAioHandler這個類的編碼協議,剩下的就是看Aio的類了,api 貌似都在這。具體不介紹了,上面有連接,要注意的是Client端與Server端協議要一致。在這裏說下我以前踩的坑,好比talent-aio的demo代碼中的協議是有header的,Server端對客戶端沒有要求,但必須遵循交互協議,因此如果你用百度出來的socket實例連Server要注意,這裏咱們用回自己提供的Client代碼就能夠了。
  2. 導入talnet-aio依賴。
    <dependency>
    		    <groupId>com.talent-aio</groupId>
    		    <artifactId>talent-aio-server</artifactId>
    		    <version>1.6.6.v20170318-RELEASE</version>
    		</dependency>

     

  3. 怎麼整合到JFinal上去呢?咱們只要將talent-aio的server端在JFinal啓動的時候順便也啓動起來就ok了。得益JFinal 插件擴展極其方便(說的這裏很感謝波總), 過程也極其簡單,讓HelloServerStarter實現JFinal的IPlugin接口就ok 了。
    import java.io.IOException;
    import com.jfinal.plugin.IPlugin;
    import com.talent.aio.server.AioServer;
    import com.talent.aio.server.ServerGroupContext;
    import com.talent.aio.server.intf.ServerAioHandler;
    import com.talent.aio.server.intf.ServerAioListener;
    
    /**
     * 
     * @author tanyaowu
     * @建立時間 2016年11月17日 下午5:59:24
     *
     * @操做列表 編號 | 操做時間 | 操做人員 | 操做說明 (1) | 2016年11月17日 | tanyaowu | 新建類
     *
     */
    public class HelloServerStarter implements IPlugin {
    	public static ServerGroupContext<Object, HelloPacket, Object> serverGroupContext = null;
    	static AioServer<Object, HelloPacket, Object> aioServer = null; // 能夠爲空
    	static ServerAioHandler<Object, HelloPacket, Object> aioHandler = null;
    	static ServerAioListener<Object, HelloPacket, Object> aioListener = null;
    	static String serverIp = null;
    	static int serverPort = Const.PORT;
    
    	public static void main(String[] args) throws IOException {
    		aioHandler = new HelloServerAioHandler();
    		aioListener = null; // 能夠爲空
    		serverGroupContext = new ServerGroupContext<>(aioHandler, aioListener);
    		aioServer = new AioServer<>(serverGroupContext);
    		aioServer.start(serverIp, serverPort);
    	}
    
    	@Override
    	public boolean start() {
    		aioHandler = new HelloServerAioHandler();
    		aioListener = null; // 能夠爲空
    		serverGroupContext = new ServerGroupContext<>(aioHandler, aioListener);
    		aioServer = new AioServer<>(serverGroupContext);
    		try {
    			aioServer.start(serverIp, serverPort);
    		} catch (IOException e) {
    			e.printStackTrace();
    			return false;
    		}
    		return true;
    	}
    
    	@Override
    	public boolean stop() {
    		return aioServer.stop();
    	}
    }

     

  4. 這裏爲了方便我把demo的代碼copy過來了,具體環境中看我的操做,很少說。
  5. 而後咱們在MainConfig中 加入這個插件就能夠了。
  6. @Override
    	public void configPlugin(Plugins me) {
    		me.add(new HelloServerStarter());
    	}

    啓動結果以下:socket

  7. 右鍵執行HelloClientStarter,會發現服務器收到了信息,客戶端也收到了服務器返回的信息。
  • 客戶端:收到消息:收到了你的消息,你的消息是:hello world
  • 服務器:收到消息:hello world
  1. 固然業務需求確定沒簡單,這裏我弄了個簡單經常使用的功能場景。客戶端鏈接上來後,服務器保存起這個客戶,Controller收到業務請求,須要發送信息給指定客戶端。 實現方式以下:
  • 在 HelloServerAioHandler 中,客戶端連進來的時候用Aio.bindUser(channelContext, userid)這個方法把用戶存起來,這裏我寫死1234,實際應該是根據IP或者發送信息來肯定。
    /**
     * **************************************************************************
     *
     * @說明: 
     * @項目名稱: talent-aio-examples-server
     *
     * @author: tanyaowu 
     * @建立時間: 2016年11月18日 上午9:13:15
     *
     * **************************************************************************
     */
    package nio;
    
    import com.talent.aio.common.Aio;
    import com.talent.aio.common.ChannelContext;
    import com.talent.aio.server.intf.ServerAioHandler;
    
    /**
     * 
     * @author tanyaowu
     * @建立時間 2016年11月18日 上午9:13:15
     *
     * @操做列表 編號 | 操做時間 | 操做人員 | 操做說明 (1) | 2016年11月18日 | tanyaowu | 新建類
     *
     */
    public class HelloServerAioHandler extends HelloAbsAioHandler implements
    		ServerAioHandler<Object, HelloPacket, Object> {
    	/**
    	 * 處理消息
    	 */
    	@Override
    	public Object handler(HelloPacket packet,
    			ChannelContext<Object, HelloPacket, Object> channelContext)
    			throws Exception {
    		byte[] body = packet.getBody();
    		if (body != null) {
    			String str = new String(body, HelloPacket.CHARSET);
    			System.out.println("收到消息:" + str);
    			// 綁定長鏈接
    			Aio.bindUser(channelContext, "1234");
    			HelloPacket resppacket = new HelloPacket();
    			resppacket.setBody(("收到了你的消息,你的消息是:" + str)
    					.getBytes(HelloPacket.CHARSET));
    			Aio.send(channelContext, resppacket);
    
    		}
    		return null;
    	}
    }

    而後在中Controller調用Aio.sendToUser(HelloServerStarter.serverGroupContext, getPara(), hello); 發送消息給該客戶端。jsp

    package controller;
    
    import nio.HelloPacket;
    import nio.HelloServerStarter;
    
    import com.jfinal.core.Controller;
    import com.talent.aio.common.Aio;
    
    public class IndexController extends Controller{
    	public void index(){
    		render("index.jsp");
    	}
    	
    	public void aio(){
    		HelloPacket hello = new HelloPacket();
    		byte arr[] = {104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100}	;
    		hello.setBody(arr);
    		Aio.sendToUser(HelloServerStarter.serverGroupContext, getPara(), hello);
    		renderJson();
    	}
    	
    }

    啓動項目訪問http://localhost/aio/1234,客戶端就能收到信息。
    ide

  • 2018-11-06 最新截圖性能

    

  • 總結:這是我第一次寫博文,有什麼寫得很差的請多笑納,也是但願能幫到有一樣需求的人。附上代碼:https://gitee.com/xiaoxustudent/jfinal-tio學習

相關文章
相關標籤/搜索