大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE稳定放心使用
<dependency>
<groupId>org.t-io</groupId>
<artifactId>tio-core</artifactId>
<version>3.7.4.v20210808-RELEASE</version>
</dependency>
总共五个类。数据模型Packet、客户端处理器、客户端监听器、服务端处理器、服务端监听器。
- 数据模型
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;
}
- 客户端处理器
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)); } }
- 客户端监听器
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 { } }
- 服务端处理器
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 { } }
- 服务端监听器
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 { } }
启动客户端:
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()); } }
启动服务端
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); } }
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/186620.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...