文档章节

花十分钟时间给JFinal写了个tio插件

小徐同学
 小徐同学
发布于 2017/03/21 21:20
字数 1255
阅读 9.8K
收藏 250

本人 JFinal 脑残粉,最近公司几个项目都需要跟硬件交互,这就得用到长连接,之前一直没接触过该领域,本来还想花时间研究下netty,讲真挺难啃的,找资料的时候翻到 t-io,略微了解发现似乎学习成本极低,没想到作者本人也极其nice,解答我这个门外小伙子好多个问题,顺利用上此框架,刚好解了我的燃眉之急。

什么是 t-io? t-io是基于java aio实现的即时通讯框架,源于作者另一个久经考验的talent-nio框架,但在易用性、性能及代码可读性方面又远远超越了talent-nio。

顺便放上传送门:https://my.oschina.net/talenttan/blog/863545

最新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());
    	}

    启动结果如下:

  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); 发送消息给该客户端。

    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,客户端就能收到信息。

  • 2018-11-06 最新截图

    

  • 总结:这是我第一次写博文,有什么写得不好的请多笑纳,也是希望能帮到有同样需求的人。附上代码:https://gitee.com/xiaoxustudent/jfinal-tio

© 著作权归作者所有

小徐同学
粉丝 45
博文 11
码字总数 5432
作品 0
广州
程序员
私信 提问
加载中

评论(35)

真的好想抱抱你
真的好想抱抱你
http://git.oschina.net/ybyxzxhw/JFinalMavenDemo 这个url访问不了啊 是你没开权限吗?大佬看下demo呗
真的好想抱抱你
真的好想抱抱你
大兄弟你把demo删除啦?我还想参考下啊
小徐同学
小徐同学 博主

引用来自“talent-tan”的评论

tag要换成t-io了😄
嗯嗯,改改
talent-tan
talent-tan
tag要换成t-io了😄
小徐同学
小徐同学 博主

引用来自“村长9828”的评论

我想问下博主,你的项目里,是发送端需要长连接(发送密集型)?还是接收端需要长连接(类似监听模式)?还是两方都需要?谢谢
长连接必然是双方的。
村长9828
村长9828
我想问下博主,你的项目里,是发送端需要长连接(发送密集型)?还是接收端需要长连接(类似监听模式)?还是两方都需要?谢谢
乌龟壳
乌龟壳

引用来自“一路找北”的评论

这是个不错的jfinal样例,不过话说跟jfinal其实没什么关系。
无论是文章中的alent-aio,还是netty,自己启个端口提供服务就可以了,没必要和jfinal绑定到一起。
bobop
bobop
好东西,先收藏了
极客小子
项目找创业合伙人,有市场的项目,要求会安卓和java,有兴趣可以来了解了解q983270700
小徐同学/jfinal-tio

jfinal-tio 项目介绍 jfinal整合tio 软件架构 JFinal3.5 Tio3.2.1.v20181024-RELEASE 安装教程 git clone https://gitee.com/xiaoxustudent/jfinal-tio 使用说明 右键运行MainConifg 发送消息......

小徐同学
2019/01/25
0
0
t-io 2.0.0 发布 —— 法网天眼第一版

简单回顾并留念一下t-io 1.x版本 2017年4月1号,t-io正式上传至码云,最初让大家记住的可能是那个每秒可收发500万条聊天消息的性能数据吧,测试代码仍然完整地保留在1.6.9的分支版,欢迎随时...

talent-tan
2017/08/24
8.5K
60
t-io 2.4.0 发布, 不仅仅是百万级 TCP 长连接框架

修改点: 1、AioHandler.decode(ByteBuffer buffer, ChannelContext channelContext)方法签名改成AioHandler.decode(ByteBuffer buffer, int limit, int position, int readableLength, Cha......

talent-tan
2018/05/07
3.7K
21
中国开源界还有希望吗?

@wingerliwe 你的言行让 Jfinal J2Cache beetl tio 等国内优秀开源项目都不属于 Apache 的【民间??山寨??】包括 mybatis 本身也脱离 Apache 情何以堪??我们只是踏踏实实的为开源界添砖...

青苗
2018/11/17
3.7K
17
HowToDoIt 开源框架爱好者组织发布第一份项目总结

HowToDoIt 是一群开源框架爱好者一起成立的一个组织, 组织成员有 JFinal, Nutz, t-io, Spring, PlayFramework 等多个开源框架的作者或资深用户, 目的就一些常见应用场景为不同的开源框架提供...

罗格林
2018/07/29
3.3K
37

没有更多内容

加载失败,请刷新页面

加载更多

dubbo架构图

节点角色说明 节点 角色说明 Provider 暴露服务的服务提供方 Consumer 调用远程服务的服务消费方 Registry 服务注册与发现的注册中心 Monitor 统计服务的调用次数和调用时间的监控中心 Cont...

王成龙_开源中国
39分钟前
38
0
在PreferenceActivity中使用什么代替“ addPreferencesFromResource”?

我刚刚注意到一个事实,即方法addPreferencesFromResource(int preferencesResId)在Android的文档中( Reference Entry ) 已被标记为已弃用 。 不幸的是,该方法的说明中没有提供替代方法。...

javail
48分钟前
65
0
给初学者的技巧,只有3条,不看后悔

在这篇文章中,我想向编程新手和初级开发人员分享我的三个技巧。虽然开发可能真的很难……但是有了这些技巧,将会助你更快成功! 一、不要害怕失败 我认为最重要的是:不要害怕失败。如果你害...

武培轩
58分钟前
51
0
全面封杀?超过13个月的HTTPS证书将被Safari拒绝!

上周(当地时间2月19日),在斯洛伐克举行的CA/浏览器(CA / Browser)论坛会议上,苹果公司宣布:为了提高网络安全性,从2020年9月1日开始,任何有效期超过 398 天的新网站证书将不会受到S...

亚洲诚信
今天
60
0
node 文件操作工具库 fs-extra

github https://github.com/jprichardson/node-fs-extra promise封装版, 比之前的回调函数更加顺手 const fs = require('fs-extra')// Async with promises:fs.copy('/tmp/myfile', '/......

阿豪boy
今天
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部