一、先引入依赖,客户端和服务端用的都是同一个依赖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
2.Constants
3.LoginFailMsg
4.LoginMsg
5.MsgType
6.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,用于进行接收处理客户端消息、断线重连、异常处理等操作。
2.NettyServerBootstrap引导程序,用于进行启动服务、推送消息、通道操作等操作。
3.NettyChannelMap,用于进行存放、添加、删除通道等操作。
四、客户端添加Handler和Bootstrap:
1.NettyClientHandler,用于进行接收处理服务端消息、断线重连、异常处理等操作。
2.NettyClientBootstrap引导程序,用于进行通道创建、通道关闭、通道状态检测等操作。
至于那个ServerInfoModel无视就好。。。那是我模型层中存取ip用的一个类,各位直接给host附上ip(如:192.168.1.123)即可。
端口我这里写死为9999。
五、启动服务端和客户端相关程序完成推送。
1.服务端调用引导程序中的create方法(端口不写9999的话需要把客户端端口改成一致)。
2.客户端配好正确的ip后调用引导程序中的create方法,用户名和密码按服务端Handler中isLogin方法来即可。
3.服务端调用引导程序中的pushAll方法,即可完成推送。
但如果没有现成程序直接移植进去调用的话,可以用我这个JFrame暂时测试一下:
以及它的PushServer测试类:
最后:
Demo地址:
http://download.csdn.net/detail/chaoxiyouda/9455584
(注:这个demo是旧的,勉强能用,但上面的那些代码都是最新的,所以大家要用的话可以把上面的那些代码和这个旧demo结合起来进行参考使用。本人略懒就不再整理一份啦,蛤蛤蛤。)