Netty學習教程之Netty與Marshalling結合發(fā)送對象
前言
之前的一篇文章是Netty簡單的學習,我們可以傳遞一個字符串,那么如果我們想要在Netty中傳遞一個對象該怎么辦呢 ?
那么這個時候我們可以結合Marshalling來傳遞。
方法如下:
首先需要導入兩個Marshalling的依賴包
jboss-marshalling-1.3.0.CR9.jar jboss-marshalling-serial-1.3.0.CR9.jar
注意:我開始學習的時候只導入了第一個jar包,沒有導入第二個,結果是不報錯,但是客戶端和服務端之間傳遞不了消息。所以兩個包一定要都導入才行。
MarshallingCodeCFactory工具類
public class MarshallingCodeCFactory { public static MarshallingDecoder buildMarshallingDecoder() { final MarshallerFactory factory = Marshalling.getProvidedMarshallerFactory("serial"); final MarshallingConfiguration configuration = new MarshallingConfiguration(); configuration.setVersion(5); UnmarshallerProvider provider = new DefaultUnmarshallerProvider(factory, configuration); MarshallingDecoder decoder = new MarshallingDecoder(provider, 1024*1024); return decoder; } public static MarshallingEncoder buildMarshallingEncoder() { final MarshallerFactory factory = Marshalling.getProvidedMarshallerFactory("serial"); final MarshallingConfiguration configuration = new MarshallingConfiguration(); configuration.setVersion(5); MarshallerProvider provider = new DefaultMarshallerProvider(factory, configuration); MarshallingEncoder encoder = new MarshallingEncoder(provider); return encoder; } }
server端
public class Server { public static void main(String[] args) throws InterruptedException { //1.第一個線程組是用于接收Client端連接的 EventLoopGroup bossGroup = new NioEventLoopGroup(); //2.第二個線程組是用于實際的業(yè)務處理的 EventLoopGroup workerGroup = new NioEventLoopGroup(); ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup);//綁定兩個線程池 b.channel(NioServerSocketChannel.class);//指定NIO的模式,如果是客戶端就是NioSocketChannel b.option(ChannelOption.SO_BACKLOG, 1024);//TCP的緩沖區(qū)設置 b.option(ChannelOption.SO_SNDBUF, 32*1024);//設置發(fā)送緩沖的大小 b.option(ChannelOption.SO_RCVBUF, 32*1024);//設置接收緩沖區(qū)大小 b.option(ChannelOption.SO_KEEPALIVE, true);//保持連續(xù) b.childHandler(new ChannelInitializer<SocketChannel>() { protected void initChannel(SocketChannel ch) throws Exception { //設置Marshalling的編碼和解碼 ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder()); ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder()); ch.pipeline().addLast(new ServertHandler()); } }); ChannelFuture future = b.bind(8765).sync();//綁定端口 future.channel().closeFuture().sync();//等待關閉(程序阻塞在這里等待客戶端請求) bossGroup.shutdownGracefully();//關閉線程 workerGroup.shutdownGracefully();//關閉線程 } }
ServerHandler處理類
public class ServertHandler extends ChannelHandlerAdapter { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { Send send = (Send) msg; System.out.println("client發(fā)送:"+send); Receive receive = new Receive(); receive.setId(send.getId()); receive.setMessage(send.getMessage()); receive.setName(send.getName()); ctx.writeAndFlush(receive); } }
由于我們已經在Server端和Client端定義了傳遞的類型又Marshalling工廠處理,所以此時我們接收的時候直接轉成發(fā)送的對象類型就行了。
Client端
public class Client { public static void main(String[] args) throws InterruptedException { EventLoopGroup worker = new NioEventLoopGroup(); Bootstrap b = new Bootstrap(); b.group(worker) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel sc) throws Exception { //ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes()); //sc.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,buf)); //sc.pipeline().addLast(new StringDecoder()); sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder()); sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder()); sc.pipeline().addLast(new ClientHandler()); } }); ChannelFuture f=b.connect("127.0.0.1",8765).sync(); for(int i=1;i<=5;i++){ Send send = new Send(); send.setId(i); send.setMessage("message"+i); send.setName("name"+i); f.channel().writeAndFlush(send); } f.channel().closeFuture().sync(); worker.shutdownGracefully(); } }
ClientHandler端
public class ClientHandler extends ChannelHandlerAdapter{ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { Receive receive = (Receive) msg; System.out.println("server反饋:"+receive); } }
send類
public class Send implements Serializable { /** * serialVersionUID:TODO(用一句話描述這個變量表示什么) * * @since 1.0.0 */ private static final long serialVersionUID = 1L; private Integer id; private String name; private String message; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } @Override public String toString() { return "Send [id=" + id + ", name=" + name + ", message=" + message + "]"; } }
Receive類
public class Receive implements Serializable{ /** * serialVersionUID:TODO(用一句話描述這個變量表示什么) * @since 1.0.0 */ private static final long serialVersionUID = 1L; private Integer id; private String name; private String message; private byte[] sss; public byte[] getSss() { return sss; } public void setSss(byte[] sss) { this.sss = sss; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } @Override public String toString() { return "Receive [id=" + id + ", name=" + name + ", message=" + message + ", sss=" + Arrays.toString(sss) + "]"; } }
注意:send類和receive這兩個類,我們再真實環(huán)境開發(fā)的時候服務器和客戶端往往是兩個web應用程序,在這里我們要注意服務端和客戶端之間的兩個類類名和包名在兩端要完全相同。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關文章
Java的Struts2框架配合Ext JS處理JSON數據的使用示例
這篇文章主要介紹了Java的Struts2框架配合Ext JS處理JSON數據的使用示例,包括將Ext JS中的JSON數據解析為列表的方法,需要的朋友可以參考下2016-03-03詳解SpringBoot Controller接收參數的幾種常用方式
這篇文章主要介紹了詳解SpringBoot Controller接收參數的幾種常用方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-10-10Netty中ChannelPoolHandler調用處理程序詳解
這篇文章主要介紹了Netty中ChannelPoolHandler調用處理程序詳解,Netty 是基于 Java NIO 的異步事件驅動的網絡應用框架,使用 Netty 可以快速開發(fā)網絡應用,Netty 提供了高層次的抽象來簡化 TCP 和 UDP 服務器的編程,但是你仍然可以使用底層的 API,需要的朋友可以參考下2023-11-11使用IDEA搭建SSM框架的詳細教程(spring + springMVC +MyBatis)
這篇文章主要介紹了使用IDEA搭建SSM框架的詳細教程 spring + springMVC +MyBatis,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05Spring Cloud Hystrix 服務容錯保護的原理實現
這篇文章主要介紹了Spring Cloud Hystrix 服務容錯保護的原理實現,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-05-05