只需五步,即可基于Netty框架实现Android内网推送功能。

时间:2021-08-31 15:43:44

一、先引入依赖,客户端和服务端用的都是同一个依赖netty-all。

  Android Studio中Gradle配置:

compile 'io.netty:netty-all:5.0.0.Alpha2'

  IDEA中Maven配置:

<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>5.0.0.Alpha2</version>
</dependency>

二、创建消息模块包。

  目前demo中消息包共如下6个类:

  1.BaseMsg

只需五步,即可基于Netty框架实现Android内网推送功能。  BaseMsg

  2.Constants

只需五步,即可基于Netty框架实现Android内网推送功能。  Constants

  3.LoginFailMsg

只需五步,即可基于Netty框架实现Android内网推送功能。  LoginFailMsg

  4.LoginMsg

只需五步,即可基于Netty框架实现Android内网推送功能。  LoginMsg

  5.MsgType

只需五步,即可基于Netty框架实现Android内网推送功能。  MsgType

  6.PushMsg

只需五步,即可基于Netty框架实现Android内网推送功能。  PushMsg

  但要注意,客户端包名和服务端包名必须一致,否则会报如下错误:

八月 11, 2016 10:37:57 上午 io.netty.channel.DefaultChannelPipeline$TailContext exceptionCaught
警告: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
io.netty.handler.codec.DecoderException: java.io.InvalidClassException: failed to read class descriptor
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:347)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:230)
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:84)
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:153)
at io.netty.channel.PausableChannelEventExecutor.invokeChannelRead(PausableChannelEventExecutor.java:86)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:389)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:956)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:127)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:514)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:471)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:385)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:351)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
at io.netty.util.internal.chmv8.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1412)
at io.netty.util.internal.chmv8.ForkJoinTask.doExec(ForkJoinTask.java:280)
at io.netty.util.internal.chmv8.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:877)
at io.netty.util.internal.chmv8.ForkJoinPool.scan(ForkJoinPool.java:1706)
at io.netty.util.internal.chmv8.ForkJoinPool.runWorker(ForkJoinPool.java:1661)
at io.netty.util.internal.chmv8.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:126)
Caused by: java.io.InvalidClassException: failed to read class descriptor
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1604)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at io.netty.handler.codec.serialization.ObjectDecoder.decode(ObjectDecoder.java:75)
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:343)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:316)
... 18 more
Caused by: java.lang.ClassNotFoundException: org.netty.module.LoginMsg
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at io.netty.handler.codec.serialization.ClassLoaderClassResolver.resolve(ClassLoaderClassResolver.java:31)
at io.netty.handler.codec.serialization.CompactObjectInputStream.readClassDescriptor(CompactObjectInputStream.java:55)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1602)
... 25 more

  我这里包名统一为org.netty.module。当然我也不百分百确定是不是这个原因,所以如果有了解的望能指点一下。。多谢了!

三、服务端添加Handler,Bootstrap,ChannelMap:

  1.NettyServerHandler,用于进行接收处理客户端消息、断线重连、异常处理等操作。

只需五步,即可基于Netty框架实现Android内网推送功能。  NettyServerHandler

  2.NettyServerBootstrap引导程序,用于进行启动服务、推送消息、通道操作等操作。

只需五步,即可基于Netty框架实现Android内网推送功能。  NettyServerBootstrap

  3.NettyChannelMap,用于进行存放、添加、删除通道等操作。

只需五步,即可基于Netty框架实现Android内网推送功能。  NettyChannelMap

四、客户端添加Handler和Bootstrap:

  1.NettyClientHandler,用于进行接收处理服务端消息、断线重连、异常处理等操作。

只需五步,即可基于Netty框架实现Android内网推送功能。  NettyClientHandler

  2.NettyClientBootstrap引导程序,用于进行通道创建、通道关闭、通道状态检测等操作。

只需五步,即可基于Netty框架实现Android内网推送功能。  NettyClientBootstrap

  至于那个ServerInfoModel无视就好。。。那是我模型层中存取ip用的一个类,各位直接给host附上ip(如:192.168.1.123)即可。

  端口我这里写死为9999。

五、启动服务端和客户端相关程序完成推送。

  1.服务端调用引导程序中的create方法(端口不写9999的话需要把客户端端口改成一致)。

  2.客户端配好正确的ip后调用引导程序中的create方法,用户名和密码按服务端Handler中isLogin方法来即可。

  3.服务端调用引导程序中的pushAll方法,即可完成推送。

  但如果没有现成程序直接移植进去调用的话,可以用我这个JFrame暂时测试一下:

只需五步,即可基于Netty框架实现Android内网推送功能。  TestFrame

  以及它的PushServer测试类:

只需五步,即可基于Netty框架实现Android内网推送功能。  PushServer

 

最后:

Demo地址:

http://download.csdn.net/detail/chaoxiyouda/9455584

(注:这个demo是旧的,勉强能用,但上面的那些代码都是最新的,所以大家要用的话可以把上面的那些代码和这个旧demo结合起来进行参考使用。本人略懒就不再整理一份啦,蛤蛤蛤。)