前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >t-io文档_如何区别服务端与客户端

t-io文档_如何区别服务端与客户端

作者头像
全栈程序员站长
发布2022-11-11 15:08:57
5710
发布2022-11-11 15:08:57
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君

代码语言:javascript
复制
<dependency>
            <groupId>org.t-io</groupId>
            <artifactId>tio-core</artifactId>
            <version>3.7.4.v20210808-RELEASE</version>
        </dependency>

总共五个类。数据模型Packet、客户端处理器、客户端监听器、服务端处理器、服务端监听器。

  • 数据模型
代码语言:javascript
复制
package com.example.mindsa.client;


import lombok.Getter;
import lombok.Setter;
import org.tio.core.intf.Packet;
@Setter
@Getter
public class MindPackage extends Packet {
    private static final long serialVersionUID = -172060606924066412L;
    public static final int HEADER_LENGTH = 4;//消息头的长度
    public static final String CHARSET = "utf-8";
    private byte[] body;
}

客户端处理器

代码语言:javascript
复制
package com.example.mindsa.client;
import org.tio.client.intf.ClientAioHandler;
import org.tio.core.ChannelContext;
import org.tio.core.TioConfig;
import org.tio.core.exception.TioDecodeException;
import org.tio.core.intf.Packet;
import java.nio.ByteBuffer;
public class ClientAioHandlerImpl implements ClientAioHandler {
/**
* 创建心跳包
*
* @param channelContext
* @return
* @author tanyaowu
*/
@Override
public Packet heartbeatPacket(ChannelContext channelContext) {
return new MindPackage();
}
/**
* 根据ByteBuffer解码成业务需要的Packet对象.
* 如果收到的数据不全,导致解码失败,请返回null,在下次消息来时框架层会自动续上前面的收到的数据
*
* @param buffer         参与本次希望解码的ByteBuffer
* @param limit          ByteBuffer的limit
* @param position       ByteBuffer的position,不一定是0哦
* @param readableLength ByteBuffer参与本次解码的有效数据(= limit - position)
* @param channelContext
* @return
* @throws TioDecodeException
*/
@Override
public Packet decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext) throws TioDecodeException {
//至少要有表示数据大小的四个字节。否则会因为无法知道数据大小而无法解包。
if (readableLength < MindPackage.HEADER_LENGTH) {
return null;
}
//获取存放在头部的四个字节,即数据字节的长度。这里要与服务器的编码约定一致:即头部4byte存放数据长度。
int bodyLength = buffer.getInt();
if (bodyLength < 0) {
throw new TioDecodeException("头部4byte标识的数据长度是0");
}
//数据长度+头部4byte的长度大于可取得的数据长度,说明是半包,无法解析成完整的Packet。
if (bodyLength + MindPackage.HEADER_LENGTH > readableLength) {
return null;
} else {
MindPackage mindPackage = new MindPackage();
byte[] bytes = new byte[bodyLength];
//getInt已经把头部的四个字节读取掉了,position在4的位置,把剩下的数据装入容器
buffer.get(bytes);
mindPackage.setBody(bytes);
return mindPackage;
}
}
/**
* 编码
*
* @param packet
* @param tioConfig
* @param channelContext
* @return
* @author: tanyaowu
*/
@Override
public ByteBuffer encode(Packet packet, TioConfig tioConfig, ChannelContext channelContext) {
MindPackage mindPackage = (MindPackage) packet;
byte[] body = mindPackage.getBody();
int bodyLength = 0;
if (body != null) {
bodyLength = body.length;
}
//初始化ByteBuffer,长度为数据长度+标识数据长度的头部4byte字节。
ByteBuffer byteBuffer = ByteBuffer.allocate(bodyLength + MindPackage.HEADER_LENGTH);
byteBuffer.order(tioConfig.getByteOrder());
//获取存放在头部的四个字节,即数据字节的长度。这里要与服务器的解码约定一致:即头部4byte存放数据长度。
byteBuffer.putInt(bodyLength);
if (body != null) {
//存放数据
byteBuffer.put(body);
}
return byteBuffer;
}
/**
* 处理消息包
*
* @param packet
* @param channelContext
* @throws Exception
* @author: tanyaowu
*/
@Override
public void handler(Packet packet, ChannelContext channelContext) throws Exception {
//处理解码后的消息
MindPackage mindPackage = (MindPackage) packet;
//将byte数据转utf8字符串输出。
System.out.println(new String(mindPackage.getBody(), MindPackage.CHARSET));
}
}

客户端监听器

代码语言:javascript
复制
package com.example.mindsa.client;
import org.tio.client.intf.ClientAioListener;
import org.tio.core.ChannelContext;
import org.tio.core.intf.Packet;
public class ClientAioListenerImpl implements ClientAioListener {
@Override
public void onAfterConnected(ChannelContext channelContext, boolean b, boolean b1) throws Exception {
}
@Override
public void onAfterDecoded(ChannelContext channelContext, Packet packet, int i) throws Exception {
}
@Override
public void onAfterReceivedBytes(ChannelContext channelContext, int i) throws Exception {
}
@Override
public void onAfterSent(ChannelContext channelContext, Packet packet, boolean b) throws Exception {
}
@Override
public void onAfterHandled(ChannelContext channelContext, Packet packet, long l) throws Exception {
}
@Override
public void onBeforeClose(ChannelContext channelContext, Throwable throwable, String s, boolean b) throws Exception {
}
}

服务端处理器

代码语言:javascript
复制
package com.example.mindsa.server;
import org.tio.core.ChannelContext;
import org.tio.core.TioConfig;
import org.tio.core.intf.Packet;
import org.tio.server.intf.ServerAioHandler;
import java.nio.ByteBuffer;
public class ServerAioHandlerImpl implements ServerAioHandler {
/**
* 根据ByteBuffer解码成业务需要的Packet对象.
* 如果收到的数据不全,导致解码失败,请返回null,在下次消息来时框架层会自动续上前面的收到的数据
*
* @param buffer         参与本次希望解码的ByteBuffer
* @param limit          ByteBuffer的limit
* @param position       ByteBuffer的position,不一定是0哦
* @param readableLength ByteBuffer参与本次解码的有效数据(= limit - position)
* @param channelContext
* @return
*/
@Override
public Packet decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext){
return null;
}
/**
* 编码
*
* @param packet
* @param tioConfig
* @param channelContext
* @return
* @author: tanyaowu
*/
@Override
public ByteBuffer encode(Packet packet, TioConfig tioConfig, ChannelContext channelContext) {
return null;
}
/**
* 处理消息包
*
* @param packet
* @param channelContext
* @throws Exception
* @author: tanyaowu
*/
@Override
public void handler(Packet packet, ChannelContext channelContext) throws Exception {
}
}

服务端监听器

代码语言:javascript
复制
package com.example.mindsa.server;
import org.tio.core.ChannelContext;
import org.tio.core.intf.Packet;
import org.tio.server.intf.ServerAioListener;
public class ServerAioListenerImpl implements ServerAioListener {
@Override
public boolean onHeartbeatTimeout(ChannelContext channelContext, Long aLong, int i) {
return false;
}
@Override
public void onAfterConnected(ChannelContext channelContext, boolean b, boolean b1) throws Exception {
}
@Override
public void onAfterDecoded(ChannelContext channelContext, Packet packet, int i) throws Exception {
}
@Override
public void onAfterReceivedBytes(ChannelContext channelContext, int i) throws Exception {
}
@Override
public void onAfterSent(ChannelContext channelContext, Packet packet, boolean b) throws Exception {
}
@Override
public void onAfterHandled(ChannelContext channelContext, Packet packet, long l) throws Exception {
}
@Override
public void onBeforeClose(ChannelContext channelContext, Throwable throwable, String s, boolean b) throws Exception {
}
}

启动客户端:

代码语言:javascript
复制
package com.example.mindsa.client;
import org.tio.client.ClientChannelContext;
import org.tio.client.ClientTioConfig;
import org.tio.client.ReconnConf;
import org.tio.client.TioClient;
import org.tio.core.Node;
import org.tio.core.Tio;
public class ClientStarter {
public static void main(String[] args) throws Exception {
ClientTioConfig clientTioConfig = new ClientTioConfig(new ClientAioHandlerImpl(), new ClientAioListenerImpl(), new ReconnConf());
TioClient tioClient = new TioClient(clientTioConfig);
ClientChannelContext connect = tioClient.connect(new Node("127.0.0.1", 8080));
Tio.send(connect, new MindPackage());
}
}

启动服务端

代码语言:javascript
复制
package com.example.mindsa.server;
import org.tio.server.ServerTioConfig;
import org.tio.server.TioServer;
import java.io.IOException;
public class ServerStarter {
public static void main(String[] args) throws IOException {
ServerTioConfig serverTioConfig = new ServerTioConfig(new ServerAioHandlerImpl(), new ServerAioListenerImpl());
TioServer tioServer = new TioServer(serverTioConfig);
tioServer.start(null, 8080);
}
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/186620.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月2日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档