IoTserver
源代码开源在gitee上 :IoT netty java gitee server sample
c++ libuv 的IoT tcp serverIoT c++ libuv gitee server sample
c++的代码也给了一个示例,为了方便调试使用了vs。为了调试方便,java下面有一个nodejs 的测试文件:
nodejs 客户端代码
IoTserver的使用最好就是使用固定协议,一种协议写一种接收,这里使用几种语言去接收,如java,c++,nodejs,技巧很多,尤其是使用java的时候,netty的接收协议方式非常方便,下面是主程序message中的定义:
publicclassMessage{privatefinal Charset charset= Charset.forName("utf-8");privatebyte magicType;privatelong deviceid;//设备privatebyte cmd;//命令privatebyte length;private String body;publicMessage(){}publicMessage(byte magicType,long deviceid,byte cmd,byte[] data){this.magicType= magicType;//0x69this.deviceid= deviceid;this.cmd=cmd;this.length=(byte)data.length;this.body=newString(data, charset);}publicMessage(byte magicType,long deviceid,byte cmd, String body){this.magicType= magicType;this.cmd= cmd;this.deviceid= deviceid;this.length=(byte)body.getBytes(charset).length;this.body= body;}public StringGetBody(){returnthis.body;}publicbyteGetCmd(){returnthis.cmd;}}
非常清晰地定义,协议由类型,定义,设备类型,命令字,数据内容长度,最后是内容。下面是主要代码,server启动在多个端口上。
package zhongda.iot.server;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelOption;import io.netty.channel.ChannelPipeline;import io.netty.channel.ChannelPipeline;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioServerSocketChannel;import redis.clients.jedis.*;/**
* Netty实现的tcp iotserver 程序
* @author qianbo
*/publicclassTcpServer{/*端口号*/staticfinalint PORT1=9002;staticfinalint PORT2=9003;publicstaticvoidmain(String[] args){
JedisPool jedisPool=newJedisPool(newJedisPoolConfig(),"192.168.1.222",6379);
Publisher publish=newPublisher(jedisPool);
publish.start();//publish.join();
EventLoopGroup bossGroup= null;
EventLoopGroup workerGroup= null;
ServerBootstrap b= null;
System.out.println("the server start at 9002 9003");try{//1:第一个线程组是用于接收Client连接的
bossGroup=newNioEventLoopGroup();//2:第二个线程组是用于实际的业务处理操作的
workerGroup=newNioEventLoopGroup();//3:创建一个启动NIO服务的辅助启动类ServerBootstrap 就是对我们的Server进行一系列的配置
b=newServerBootstrap();//4:绑定两个线程组
b.group(bossGroup, workerGroup)//5:需要指定使用NioServerSocketChannel这种类型的通道.channel(NioServerSocketChannel.class)//(3) 服务端 -->NioServerSocketChannel//6:一定要使用childHandler 去绑定具体的事件处理器.childHandler(newChannelInitializer<SocketChannel>()//(4) childHandler{@OverrideprotectedvoidinitChannel(SocketChannel sc)throws Exception{//7:将自定义的serverHandler加入到管道中去(多个)
ChannelPipeline p= sc.pipeline();
p.addLast(newMessageDecoder(255,6,1));//p.addLast(new MessageEncoder());
p.addLast(newServerHandler());//handler中实现真正的业务逻辑}})//8:设置TCP连接的缓冲区.option(ChannelOption.SO_BACKLOG,200)//(5)//设置发送缓冲大小 32K发送缓冲// .option(ChannelOption.SO_SNDBUF, 32*1024)//设置接收缓冲大小// .option(ChannelOption.SO_RCVBUF, 32*1024)//9:保持连接.childOption(ChannelOption.SO_KEEPALIVE,true);//(6)//10:绑定指定的端口 进行监听
ChannelFuture cf2= b.bind(PORT1).sync();// (7)
ChannelFuture cf3= b.bind(PORT2).sync();// (7) 绑定多个端口
cf2.channel().closeFuture().sync();//异步等待关闭
cf3.channel().closeFuture().sync();//异步等待关闭}catch(Exception e){
e.printStackTrace();}finally{
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();}}}