Netty的序列化之MessagePack

目录

引入MessagePack依赖

实体类

服务端代码

客户端代码

执行结果


引入MessagePack依赖

        <dependency><groupId>org.msgpack</groupId><artifactId>msgpack</artifactId><version>0.6.12</version></dependency>

实体类

@Message//MessagePack提供的注解,表明这是一个需要序列化的实体类
public class User {private String id;private String userName;private int age;private UserContact userContact;public User(String userName, int age, String id) {this.userName = userName;this.age = age;this.id = id;}public User() {}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getId() {return id;}public void setId(String id) {this.id = id;}public UserContact getUserContact() {return userContact;}public void setUserContact(UserContact userContact) {this.userContact = userContact;}@Overridepublic String toString() {return "User{" +"userName='" + userName + '\'' +", age=" + age +", id='" + id + '\'' +", userContact=" + userContact +'}';}
}
@Message//MessagePack提供的注解,表明这是一个需要序列化的实体类
public class UserContact {private String mail;private String phone;public UserContact() {}public UserContact(String mail, String phone) {this.mail = mail;this.phone = phone;}public String getMail() {return mail;}public void setMail(String mail) {this.mail = mail;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}@Overridepublic String toString() {return "UserContact{" +"mail='" + mail + '\'' +", phone='" + phone + '\'' +'}';}
}

服务端代码

public class ServerMsgPackEcho {public static final int PORT = 9995;public static void main(String[] args) throws InterruptedException {ServerMsgPackEcho serverMsgPackEcho = new ServerMsgPackEcho();System.out.println("服务器即将启动");serverMsgPackEcho.start();}public void start() throws InterruptedException {final MsgPackServerHandler serverHandler = new MsgPackServerHandler();EventLoopGroup group = new NioEventLoopGroup();/*线程组*/try {ServerBootstrap b = new ServerBootstrap();/*服务端启动必须*/b.group(group)/*将线程组传入*/.channel(NioServerSocketChannel.class)/*指定使用NIO进行网络传输*/.localAddress(new InetSocketAddress(PORT))/*指定服务器监听端口*//*服务端每接收到一个连接请求,就会新启一个socket通信,也就是channel,所以下面这段代码的作用就是为这个子channel增加handle*/.childHandler(new ChannelInitializerImp());ChannelFuture f = b.bind().sync();/*异步绑定到服务器,sync()会阻塞直到完成*/System.out.println("服务器启动完成,等待客户端的连接和数据.....");f.channel().closeFuture().sync();/*阻塞直到服务器的channel关闭*/} finally {group.shutdownGracefully().sync();/*优雅关闭线程组*/}}private static class ChannelInitializerImp extends ChannelInitializer<Channel> {@Overrideprotected void initChannel(Channel ch) throws Exception {ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(65535,0,2,0,2));ch.pipeline().addLast(new MsgPackDecoder());ch.pipeline().addLast(new MsgPackServerHandler());}}
}/*基于MessagePack的解码器,反序列化*/
public class MsgPackDecoder extends MessageToMessageDecoder<ByteBuf> {@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out)throws Exception {final int length = msg.readableBytes();final byte[] array = new byte[length];msg.getBytes(msg.readerIndex(),array,0,length);MessagePack messagePack = new MessagePack();out.add(messagePack.read(array,User.class));}
}@ChannelHandler.Sharable
public class MsgPackServerHandler extends ChannelInboundHandlerAdapter {private AtomicInteger counter = new AtomicInteger(0);/*** 服务端读取到网络数据后的处理*/@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {//将上一个handler生成的数据强制转型User user = (User)msg;System.out.println("Server Accept["+user+"] and the counter is:"+counter.incrementAndGet());//服务器的应答String resp = "I process user :"+user.getUserName()+ System.getProperty("line.separator");ctx.writeAndFlush(Unpooled.copiedBuffer(resp.getBytes()));ctx.fireChannelRead(user);}/*** 发生异常后的处理*/@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.close();}
}

客户端代码

public class ClientMsgPackEcho {private final String host;public ClientMsgPackEcho(String host) {this.host = host;}public void start() throws InterruptedException {EventLoopGroup group = new NioEventLoopGroup();/*线程组*/try {final Bootstrap b = new Bootstrap();;/*客户端启动必须*/b.group(group)/*将线程组传入*/.channel(NioSocketChannel.class)/*指定使用NIO进行网络传输*//*配置要连接服务器的ip地址和端口*/.remoteAddress(new InetSocketAddress(host, ServerMsgPackEcho.PORT)).handler(new ChannelInitializerImp());ChannelFuture f = b.connect().sync();System.out.println("已连接到服务器.....");f.channel().closeFuture().sync();} finally {group.shutdownGracefully().sync();}}private static class ChannelInitializerImp extends ChannelInitializer<Channel> {@Overrideprotected void initChannel(Channel ch) throws Exception {/*告诉netty,计算一下报文的长度,然后作为报文头加在前面*/ch.pipeline().addLast(new LengthFieldPrepender(2));/*对服务器的应答也要解码,解决粘包半包*/ch.pipeline().addLast(new LineBasedFrameDecoder(1024));/*对我们要发送的数据做编码-序列化*/ch.pipeline().addLast(new MsgPackEncode());ch.pipeline().addLast(new MsgPackClientHandler(5));}}public static void main(String[] args) throws InterruptedException {new ClientMsgPackEcho("127.0.0.1").start();}
}/*基于MessagePack的编码器,序列化*/
public class MsgPackEncode extends MessageToByteEncoder<User> {@Overrideprotected void encode(ChannelHandlerContext ctx, User msg, ByteBuf out)throws Exception {MessagePack messagePack = new MessagePack();byte[] raw = messagePack.write(msg);out.writeBytes(raw);}
}public class MsgPackClientHandler extends SimpleChannelInboundHandler<ByteBuf> {private final int sendNumber;public MsgPackClientHandler(int sendNumber) {this.sendNumber = sendNumber;}private AtomicInteger counter = new AtomicInteger(0);/*** 客户端读取到网络数据后的处理*/protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {System.out.println("client Accept["+msg.toString(CharsetUtil.UTF_8)+"] and the counter is:"+counter.incrementAndGet());}/*** 客户端被通知channel活跃后,做事*/@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {User[] users = makeUsers();//发送数据for(User user:users){System.out.println("Send user:"+user);ctx.write(user);}ctx.flush();}/*** 发生异常后的处理*/@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.close();}/*生成用户实体类的数组,以供发送*/private User[] makeUsers(){User[] users=new User[sendNumber];User user =null;for(int i=0;i<sendNumber;i++){user=new User();user.setAge(i);String userName = "ABC--->"+i;user.setUserName(userName);user.setId("No:"+(sendNumber-i));user.setUserContact(new UserContact(userName+"@9527.com","133333333"));users[i]=user;}return users;}
}

核心就是通过MessagePack提供的处理器来处理数据。

执行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/675574.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Stable Diffusion教程——使用TensorRT GPU加速提升Stable Diffusion出图速度

概述 Diffusion 模型在生成图像时最大的瓶颈是速度过慢的问题。为了解决这个问题&#xff0c;Stable Diffusion 采用了多种方式来加速图像生成&#xff0c;使得实时图像生成成为可能。最核心的加速是Stable Diffusion 使用了编码器将图像从原始的 3512512 大小转换为更小的 46…

Python爬虫http基本原理#2

Python爬虫逆向系列&#xff08;更新中&#xff09;&#xff1a;http://t.csdnimg.cn/5gvI3 HTTP 基本原理 在本节中&#xff0c;我们会详细了解 HTTP 的基本原理&#xff0c;了解在浏览器中敲入 URL 到获取网页内容之间发生了什么。了解了这些内容&#xff0c;有助于我们进一…

雨云2h2g香港二区云服务器测评(纯测评)

购买并且重装好系统后&#xff0c;来itdog去ping一下看看延迟怎么样。&#xff08;香港无移动屏蔽&#xff09;&#xff1a; 然后&#xff0c;我们来做一个线路路由测试&#xff08;去回程路由测试&#xff09;。&#xff08;雨云香港服务器IP不是原生IP&#xff0c;而是广播IP…

【Python】使用 requirements.txt 与 pytorch 相关配置

【Python】使用 requirements.txt 与 pytorch 相关配置 前言一、pip1、导出结果含有路径2、导出不带路径的 二、Conda1、导出requirements.txt2、导出yml 文件 三、第三方包&#xff1a;pipreqs&#xff08;推荐&#xff09;1、创建并激活conda环境2、安装requirements文件的pi…

Ubuntu22.04 gnome-builder gnome C 应用程序习练笔记(三)

八、ui窗体创建要点 .h文件定义(popwindowf.h)&#xff0c; TEST_TYPE_WINDOW宏是要创建的窗口样式。 #pragma once #include <gtk/gtk.h> G_BEGIN_DECLS #define TEST_TYPE_WINDOW (test_window_get_type()) G_DECLARE_FINAL_TYPE (TestWindow, test_window, TEST, WI…

Quorum NWR算法,鱼和熊掌也可兼得

众所周知在分布式系统中CAP&#xff0c;一致性&#xff08;Consistency&#xff09;、可用性&#xff08;Availability&#xff09;、分区容错性&#xff08;Partition Tolerance&#xff09;三个指标不可兼得&#xff0c;只能在三个指标中选择两个。假如此时已经实现了一套AP型…

C#上位机与三菱PLC的通信05--MC协议之QnA-3E报文解析

1、MC协议回顾 MC是公开协议 &#xff0c;所有报文格式都是有标准 &#xff0c;MC协议可以在串口通信&#xff0c;也可以在以太网通信 串口&#xff1a;1C、2C、3C、4C 网口&#xff1a;4E、3E、1E A-1E是三菱PLC通信协议中最早的一种&#xff0c;它是一种基于二进制通信协…

day7(2024/2/8)

mainui.h(第二个界面) #ifndef MAINUI_H #define MAINUI_H#include <QWidget>namespace Ui { class MainUi; }class MainUi : public QWidget {Q_OBJECTpublic:explicit MainUi(QWidget *parent nullptr);~MainUi();public slots:void main_ui();private:Ui::MainUi *u…

Rust 格式化输出

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、format! 宏二、fmt::Debug三、fmt::Display四、? 操作符 循环打印 前言 Rust学习系列-本文根据教程学习Rust的格式化输出&#xff0c;包括fmt::Debug&…

MATLAB环境下基于深层小波时间散射网络的ECG信号分类

2012年&#xff0c;法国工程学院院士Mallat教授深受深度学习结构框架思想的启发&#xff0c;提出了基于小波变换的小波时间散射网络&#xff0c;并以此构造了小波时间散射网络。 小波时间散射网络的结构类似于深度卷积神经网络&#xff0c;不同的是其滤波器是预先确定好的小波…

【leetcode热题100】最大矩形

给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵&#xff0c;找出只包含 1 的最大矩形&#xff0c;并返回其面积。 示例 1&#xff1a; 输入&#xff1a;matrix [["1","0","1","0","0"],["1",&quo…

C语言操作符超详细总结

文章目录 1. 操作符的分类2. 二进制和进制转换2.1 2进制转10进制2.1.1 10进制转2进制数字 2.2 2进制转8进制和16进制2.2.1 2进制转8进制2.2.2 2进制转16进制 3. 原码、反码、补码4.移位操作符4.1 左移操作符4.2 右移操作符 5. 位操作符&#xff1a;&、|、^、~6. 逗号表达式…

从github上拉取项目到pycharm中

有两种方法&#xff0c;方法一较为简单&#xff0c;方法二用到了git bash&#xff0c;推荐方法一 目录 有两种方法&#xff0c;方法一较为简单&#xff0c;方法二用到了git bash&#xff0c;推荐方法一方法一&#xff1a;方法二&#xff1a; 方法一&#xff1a; 在github上复制…

复制和粘贴文本时剥离格式的5种方法(MacWindows)

您可能每天复制和粘贴多次。虽然它是一个非常方便的功能&#xff0c;但最大的烦恼之一就是带来了特殊的格式。从网络上获取一些文本&#xff0c;您经常会发现粘贴到文档中时&#xff0c;它保持原始样式。 我们将展示如何使用一些简单的技巧在不格式化的情况下复制和粘贴。 1.…

下载已编译的 OpenCV 包在 Visual Studio 下实现快速配置

自己编译 OpenCV 挺麻烦的&#xff0c;配置需要耗费很长时间&#xff0c;编译也需要很长时间&#xff0c;而且无法保证能全部编译通过。利用 OpenCV 官网提供的已编译的 OpenCV 库可以节省很多时间。下面介绍安装配置方法。 1. OpenCV 官网 地址是&#xff1a;https://opencv…

C++初阶:容器(Containers)vector常用接口详解

介绍完了string类的相关内容后&#xff1a;C初阶&#xff1a;适合新手的手撕string类&#xff08;模拟实现string类&#xff09; 接下来进入新的篇章&#xff0c;容器vector介绍&#xff1a; 文章目录 1.vector的初步介绍2.vector的定义&#xff08;constructor&#xff09;3.v…

WebSocket+Http实现功能加成

WebSocketHttp实现功能加成 前言 首先&#xff0c;WebSocket和HTTP是两种不同的协议&#xff0c;它们在设计和用途上有一些显著的区别。以下是它们的主要特点和区别&#xff1a; HTTP (HyperText Transfer Protocol): 请求-响应模型&#xff1a; HTTP 是基于请求-响应模型的协…

阿里云幻兽帕鲁服务器有用过的吗?搭建简单啊

玩转幻兽帕鲁服务器&#xff0c;幻兽帕鲁Palworld多人游戏专用服务器一键部署教程&#xff0c;阿里云推出新手0基础一键部署幻兽帕鲁服务器教程&#xff0c;傻瓜式一键部署&#xff0c;3分钟即可成功创建一台Palworld专属服务器&#xff0c;成本仅需26元&#xff0c;阿里云百科…

了解海外云手机的多种功能

随着社会的高度发展&#xff0c;海外云手机成为商家不可或缺的工具&#xff0c;为企业出海提供了便利的解决方案。然而&#xff0c;谈及海外云手机&#xff0c;很多人仍不了解其强大功能。究竟海外云手机有哪些功能&#xff0c;可以为我们做些什么呢&#xff1f; 由于国内电商竞…

Vue2中v-for 与 v-if 的优先级

在Vue2中&#xff0c;v-for 和 v-if 是常用的指令&#xff0c;它们在前端开发中非常有用。但是&#xff0c;当我们在同一个元素上同时使用这两个指令时&#xff0c;就需要注意它们的优先级关系了。 首先&#xff0c;让我们了解一下v-for和v-if的基本用法。 v-for 是Vue的内置…