Netty學(xué)習(xí)教程之Netty與Marshalling結(jié)合發(fā)送對(duì)象
前言
之前的一篇文章是Netty簡(jiǎn)單的學(xué)習(xí),我們可以傳遞一個(gè)字符串,那么如果我們想要在Netty中傳遞一個(gè)對(duì)象該怎么辦呢 ?
那么這個(gè)時(shí)候我們可以結(jié)合Marshalling來傳遞。
方法如下:
首先需要導(dǎo)入兩個(gè)Marshalling的依賴包
jboss-marshalling-1.3.0.CR9.jar jboss-marshalling-serial-1.3.0.CR9.jar
注意:我開始學(xué)習(xí)的時(shí)候只導(dǎo)入了第一個(gè)jar包,沒有導(dǎo)入第二個(gè),結(jié)果是不報(bào)錯(cuò),但是客戶端和服務(wù)端之間傳遞不了消息。所以兩個(gè)包一定要都導(dǎo)入才行。
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.第一個(gè)線程組是用于接收Client端連接的
EventLoopGroup bossGroup = new NioEventLoopGroup();
//2.第二個(gè)線程組是用于實(shí)際的業(yè)務(wù)處理的
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup);//綁定兩個(gè)線程池
b.channel(NioServerSocketChannel.class);//指定NIO的模式,如果是客戶端就是NioSocketChannel
b.option(ChannelOption.SO_BACKLOG, 1024);//TCP的緩沖區(qū)設(shè)置
b.option(ChannelOption.SO_SNDBUF, 32*1024);//設(shè)置發(fā)送緩沖的大小
b.option(ChannelOption.SO_RCVBUF, 32*1024);//設(shè)置接收緩沖區(qū)大小
b.option(ChannelOption.SO_KEEPALIVE, true);//保持連續(xù)
b.childHandler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel ch) throws Exception {
//設(shè)置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();//等待關(guān)閉(程序阻塞在這里等待客戶端請(qǐng)求)
bossGroup.shutdownGracefully();//關(guān)閉線程
workerGroup.shutdownGracefully();//關(guān)閉線程
}
}
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);
}
}
由于我們已經(jīng)在Server端和Client端定義了傳遞的類型又Marshalling工廠處理,所以此時(shí)我們接收的時(shí)候直接轉(zhuǎn)成發(fā)送的對(duì)象類型就行了。
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(用一句話描述這個(gè)變量表示什么)
*
* @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(用一句話描述這個(gè)變量表示什么)
* @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這兩個(gè)類,我們?cè)僬鎸?shí)環(huán)境開發(fā)的時(shí)候服務(wù)器和客戶端往往是兩個(gè)web應(yīng)用程序,在這里我們要注意服務(wù)端和客戶端之間的兩個(gè)類類名和包名在兩端要完全相同。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Java的Struts2框架配合Ext JS處理JSON數(shù)據(jù)的使用示例
這篇文章主要介紹了Java的Struts2框架配合Ext JS處理JSON數(shù)據(jù)的使用示例,包括將Ext JS中的JSON數(shù)據(jù)解析為列表的方法,需要的朋友可以參考下2016-03-03
詳解SpringBoot Controller接收參數(shù)的幾種常用方式
這篇文章主要介紹了詳解SpringBoot Controller接收參數(shù)的幾種常用方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
Spring生命周期回調(diào)與容器擴(kuò)展詳解
這篇文章主要介紹了Spring生命周期回調(diào)與容器擴(kuò)展詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-12-12
java下載指定文件并返回給前端返回流文件的實(shí)現(xiàn)步驟
在Java中我們可以根據(jù)文件地址返回一個(gè)文件流,以便對(duì)文件進(jìn)行讀取、寫入等操作,下面這篇文章主要給大家介紹了關(guān)于java下載指定文件并返回給前端返回流文件的實(shí)現(xiàn)步驟,需要的朋友可以參考下2024-03-03
Netty中ChannelPoolHandler調(diào)用處理程序詳解
這篇文章主要介紹了Netty中ChannelPoolHandler調(diào)用處理程序詳解,Netty 是基于 Java NIO 的異步事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用框架,使用 Netty 可以快速開發(fā)網(wǎng)絡(luò)應(yīng)用,Netty 提供了高層次的抽象來簡(jiǎn)化 TCP 和 UDP 服務(wù)器的編程,但是你仍然可以使用底層的 API,需要的朋友可以參考下2023-11-11
使用IDEA搭建SSM框架的詳細(xì)教程(spring + springMVC +MyBatis)
這篇文章主要介紹了使用IDEA搭建SSM框架的詳細(xì)教程 spring + springMVC +MyBatis,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05
Spring Cloud Hystrix 服務(wù)容錯(cuò)保護(hù)的原理實(shí)現(xiàn)
這篇文章主要介紹了Spring Cloud Hystrix 服務(wù)容錯(cuò)保護(hù)的原理實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-05-05

