diff --git a/JdkLearn/pom.xml b/JdkLearn/pom.xml
index 4a18492..9fb74db 100644
--- a/JdkLearn/pom.xml
+++ b/JdkLearn/pom.xml
@@ -30,7 +30,6 @@
io.netty
netty-all
- 4.1.6.Final
diff --git a/JdkLearn/src/main/java/com/learnjava/collection/LRUCache.java b/JdkLearn/src/main/java/com/learnjava/collection/LRUCache.java
new file mode 100644
index 0000000..aca54da
--- /dev/null
+++ b/JdkLearn/src/main/java/com/learnjava/collection/LRUCache.java
@@ -0,0 +1,71 @@
+package com.learnjava.collection;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+
+/**
+ * @Description
+ * @Author luohaiyang
+ * @Date 2022/4/6
+ */
+public class LRUCache implements Iterable {
+
+ private int MAX = 3;
+ private LinkedHashMap cache = new LinkedHashMap<>();
+
+ public void cache(K key, V value) {
+ if (cache.containsKey(key)) {
+ cache.remove(key);
+ } else if (cache.size() >= MAX) {
+ Iterator iterator = cache.keySet().iterator();
+ K first = iterator.next();
+ cache.remove(first);
+ }
+ cache.put(key, value);
+ }
+
+ public V getValue(K k) {
+ return cache.get(k);
+ }
+
+ @Override
+ public void forEach(Consumer super K> action) {
+ Iterable.super.forEach(action);
+ }
+
+ @Override
+ public Spliterator spliterator() {
+ return Iterable.super.spliterator();
+ }
+
+ @Override
+ public Iterator iterator() {
+ Iterator iterator = cache.keySet().iterator();
+ return new Iterator() {
+
+ @Override
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override
+ public K next() {
+ return iterator.next();
+ }
+ };
+ }
+
+ public static void main(String[] args) {
+ LRUCache cache = new LRUCache<>();
+ cache.cache("1", "1A");
+ cache.cache("2", "2A");
+ cache.cache("3", "3A");
+ cache.cache("1", "1A");
+
+ for (String next : cache) {
+ System.out.println(cache.getValue(next));
+ }
+ }
+}
diff --git a/JdkLearn/src/main/java/com/learnjava/concurent/ReentrantLockDemo.java b/JdkLearn/src/main/java/com/learnjava/concurent/ReentrantLockDemo.java
new file mode 100644
index 0000000..0d04fb8
--- /dev/null
+++ b/JdkLearn/src/main/java/com/learnjava/concurent/ReentrantLockDemo.java
@@ -0,0 +1,9 @@
+package com.learnjava.concurent;
+
+/**
+ * @Description
+ * @Author luohaiyang
+ * @Date 2022/4/7
+ */
+public class ReentrantLockDemo {
+}
diff --git a/JdkLearn/src/main/java/com/learnjava/concurent/SnowIdUtils.java b/JdkLearn/src/main/java/com/learnjava/concurent/SnowIdUtils.java
index b07604d..384d980 100644
--- a/JdkLearn/src/main/java/com/learnjava/concurent/SnowIdUtils.java
+++ b/JdkLearn/src/main/java/com/learnjava/concurent/SnowIdUtils.java
@@ -58,7 +58,7 @@ private SnowFlake() {
// String ip = instance.getDockerIp().replace(".", "");
// 模拟获取机器节点ip
String ip = "127.0.0.1";
- long localIp = Long.valueOf(ip.replace(".", ""));
+ long localIp = Long.parseLong(ip.replace(".", ""));
machineIdPart = (localIp & MAX_MACHINE_ID) << SEQUENCE_BIT;
}
/**
diff --git a/JdkLearn/src/main/java/com/learnjava/concurent/SynchronizeDemo.java b/JdkLearn/src/main/java/com/learnjava/concurent/SynchronizeDemo.java
new file mode 100644
index 0000000..4a89467
--- /dev/null
+++ b/JdkLearn/src/main/java/com/learnjava/concurent/SynchronizeDemo.java
@@ -0,0 +1,9 @@
+package com.learnjava.concurent;
+
+/**
+ * @Description
+ * @Author luohaiyang
+ * @Date 2022/4/7
+ */
+public class SynchronizeDemo {
+}
diff --git a/JdkLearn/src/main/java/com/learnjava/concurent/ThreadPoolExecutorDemo.java b/JdkLearn/src/main/java/com/learnjava/concurent/ThreadPoolExecutorDemo.java
new file mode 100644
index 0000000..5d5b5fc
--- /dev/null
+++ b/JdkLearn/src/main/java/com/learnjava/concurent/ThreadPoolExecutorDemo.java
@@ -0,0 +1,48 @@
+package com.learnjava.concurent;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @Description
+ * @Author luohaiyang
+ * @Date 2022/4/24
+ */
+public class ThreadPoolExecutorDemo {
+
+ public static void main(String[] args) {
+ testThreadPoolExecutorBinaryCalc();
+ }
+
+
+ /**
+ * 验证ThreadPoolExecutor中的二进制位运算操作
+ */
+ private static void testThreadPoolExecutorBinaryCalc() {
+// System.out.println(ctl.get());
+// System.out.println(Integer.toBinaryString(ctlOf(RUNNING, 0)));
+// System.out.println(Integer.toBinaryString(RUNNING));
+ // 修改线程状态-STOP
+ System.out.println(Integer.toBinaryString(~runStateOf(ctlOf(STOP, 10))));
+ // 修改线程状态-TERMINATED
+// System.out.println(runStateOf(3));
+// System.out.println(Integer.toBinaryString(~CAPACITY));
+ }
+
+ private static final int COUNT_BITS = Integer.SIZE - 3;
+
+ private static final int CAPACITY = (1 << COUNT_BITS) - 1;
+
+ private static final int RUNNING = -1 << COUNT_BITS;
+ private static final int SHUTDOWN = 0 << COUNT_BITS;
+ private static final int STOP = 1 << COUNT_BITS;
+ private static final int TIDYING = 2 << COUNT_BITS;
+ private static final int TERMINATED = 3 << COUNT_BITS;
+
+ private static AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
+
+ private static int runStateOf(int c) { return c & ~CAPACITY; }
+
+ private static int workerCountOf(int c) { return c & CAPACITY; }
+
+ private static int ctlOf(int rs, int wc) { return rs | wc; }
+}
diff --git a/JdkLearn/src/main/java/com/learnjava/reference/WeakReferenceTest.java b/JdkLearn/src/main/java/com/learnjava/reference/WeakReferenceTest.java
index bbbb766..2e2ec2d 100644
--- a/JdkLearn/src/main/java/com/learnjava/reference/WeakReferenceTest.java
+++ b/JdkLearn/src/main/java/com/learnjava/reference/WeakReferenceTest.java
@@ -1,7 +1,5 @@
package com.learnjava.reference;
-import com.sun.webkit.graphics.Ref;
-
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
diff --git a/README.md b/README.md
index 6882d72..fae4153 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@
-
+
@@ -74,6 +74,8 @@ SpringCloud源码
- [一篇文章快速深入学习ThreadLocal](https://github.com/coderbruis/JavaSourceLearning/blob/master/note/JDK/%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0%E5%BF%AB%E9%80%9F%E6%B7%B1%E5%85%A5%E5%AD%A6%E4%B9%A0ThreadLocal.md)
- [深入学习Java volatile关键字](https://github.com/coderbruis/JavaSourceLearning/blob/master/note/JDK/%E6%B7%B1%E5%85%A5%E5%AD%A6%E4%B9%A0Java%20volatile%E5%85%B3%E9%94%AE%E5%AD%97.md)
- [深入学习Thread底层原理](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/JDK/%E6%B7%B1%E5%85%A5%E5%AD%A6%E4%B9%A0Thread%E5%BA%95%E5%B1%82%E6%BA%90%E7%A0%81.md)
+ - [深入学习JDK1.7、8 HashMap扩容原理]()
+ - [开源项目里那些看不懂的位运算分析](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/JDK/%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE%E9%87%8C%E9%82%A3%E4%BA%9B%E7%9C%8B%E4%B8%8D%E6%87%82%E7%9A%84%E4%BD%8D%E8%BF%90%E7%AE%97%E5%88%86%E6%9E%90.md)
- Spring源码学习
- Spring版本:5.2.1.RELEASE
@@ -96,7 +98,7 @@ SpringCloud源码
- [深入浅出SpringBoot源码——SpringFactoriesLoader](https://github.com/coderbruis/JavaSourceLearning/blob/master/note/SpringBoot/%E6%B7%B1%E5%85%A5SpringBoot%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E4%B9%8B%E2%80%94%E2%80%94SpringFactoriesLoader.md)
- [深入浅出SpringBoot源码——监听器与事件机制](https://github.com/coderbruis/JavaSourceLearning/blob/master/note/SpringBoot/%E6%B7%B1%E5%85%A5SpringBoot%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E4%B9%8B%E2%80%94%E2%80%94%E7%9B%91%E5%90%AC%E5%99%A8%E4%B8%8E%E4%BA%8B%E4%BB%B6%E6%9C%BA%E5%88%B6.md)
- - [深入浅出SpringBoot源码——系统初始化器](https://github.com/coderbruis/JavaSourceLearning/blob/master/note/SpringBoot/%E6%B7%B1%E5%85%A5SpringBoot%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E4%B9%8B%E2%80%94%E2%80%94%E7%B3%BB%E7%BB%9F.md)
+ - [深入浅出SpringBoot源码——系统初始化器](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/SpringBoot/%E6%B7%B1%E5%85%A5SpringBoot%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E4%B9%8B%E2%80%94%E2%80%94%E7%B3%BB%E7%BB%9F%E5%88%9D%E5%A7%8B%E5%8C%96%E5%99%A8.md)
- [深入浅出SpringBoot源码——启动加载器](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/SpringBoot/%E6%B7%B1%E5%85%A5SpringBoot%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E4%B9%8B%E2%80%94%E2%80%94%E5%90%AF%E5%8A%A8%E5%8A%A0%E8%BD%BD%E5%99%A8.md)
- SpringSecurity&OAuth2源码学习
@@ -121,19 +123,25 @@ SpringCloud源码
- Dubbo底层源码学习(七)—— Dubbo的服务消费
- Netty底层源码解析
- - Netty版本:4.1.60.Final
+ - Netty版本:4.1.43.Final
- [二进制运算以及源码、反码以及补码学习](https://github.com/coderbruis/JavaSourceLearning/blob/master/note/Netty/%E4%BA%8C%E8%BF%9B%E5%88%B6.md)
- [Netty源码包结构](https://github.com/coderbruis/JavaSourceLearning/blob/master/note/Netty/Netty%E6%BA%90%E7%A0%81%E5%8C%85%E7%BB%93%E6%9E%84.md)
- - [Netty中的EventLoopGroup](https://github.com/coderbruis/JavaSourceLearning/blob/master/note/Netty/Netty%E4%B8%AD%E7%9A%84EventLoopGroup%E6%98%AF%E4%BB%80%E4%B9%88.md)
+ - [Netty底层源码解析-EventLoopGroup](https://github.com/coderbruis/JavaSourceLearning/blob/master/note/Netty/Netty%E4%B8%AD%E7%9A%84EventLoopGroup%E6%98%AF%E4%BB%80%E4%B9%88.md)
- [Netty底层源码解析-初始Netty及其架构](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/Netty/Netty%E5%BA%95%E5%B1%82%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90-%E5%88%9D%E5%A7%8BNetty%E5%8F%8A%E5%85%B6%E6%9E%B6%E6%9E%84.md)
- [Netty底层源码解析-Netty服务端启动分析](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/Netty/Netty%E5%BA%95%E5%B1%82%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90-Netty%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%90%AF%E5%8A%A8%E5%88%86%E6%9E%90.md)
- [Netty底层源码解析-NioEventLoop原理分析](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/Netty/Netty%E5%BA%95%E5%B1%82%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90-NioEventLoop%E5%8E%9F%E7%90%86%E5%88%86%E6%9E%90.md)
- - Netty底层源码解析-Channel分析
- [Netty底层源码解析-ChannelPipeline分析(上)](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/Netty/Netty%E5%BA%95%E5%B1%82%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90-ChannelPipeline%E5%88%86%E6%9E%90%EF%BC%88%E4%B8%8A%EF%BC%89.md)
- [Netty底层源码解析-ChannelPipeline分析(下)](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/Netty/Netty%E5%BA%95%E5%B1%82%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90-ChannelPipeline%E5%88%86%E6%9E%90%EF%BC%88%E4%B8%8B%EF%BC%89.md)
+ - [Netty底层源码解析-NioServerSocketChannel接受数据原理分析](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/Netty/Netty%E5%BA%95%E5%B1%82%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90-NioServerSocketChannel%E6%8E%A5%E5%8F%97%E6%95%B0%E6%8D%AE%E5%8E%9F%E7%90%86%E5%88%86%E6%9E%90.md)
+ - Netty底层源码解析-NioSocketChannel接受、发送数据原理分析
- Netty底层源码解析-FastThreadLocal原理分析
- Netty底层源码解析-内存分配原理分析
- Netty底层源码解析-RocketMQ底层使用到的Netty
+ - [Netty底层的优化总结]()
+ - [实战+原理效果更佳!强烈推荐闪电侠大佬实战课:《Netty 入门与实战:仿写微信 IM 即时通讯系统》](https://juejin.cn/book/6844733738119593991)
+
+Netty实战课相关点位于:Spring-Netty,com/bruis/learnnetty/im包下,有需要的读者可前往查看。
+
- RocketMQ底层源码解析
- RocketMQ版本:4.9.0
@@ -145,6 +153,12 @@ SpringCloud源码
todo
+2021年年底完成了人生的两件大事,所以一直没时间持续输出源码分析,2022年开始需要继续努力,继续完成这个源码分析项目!
+
+- 完成Netty剩余源码分析文章
+- 完成RocketMQ剩余源码分析文章
+- 完成Dubbo剩余源码分析文章
+- C语言基础学习(为Redis底层源码学习做准备)
- Redis底层源码分析
- JUC底层源码分析
diff --git a/Spring-Netty/learnnetty.iml b/Spring-Netty/learnnetty.iml
deleted file mode 100644
index 8cc03a7..0000000
--- a/Spring-Netty/learnnetty.iml
+++ /dev/null
@@ -1,98 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Spring-Netty/pom.xml b/Spring-Netty/pom.xml
index d640f68..82d7684 100644
--- a/Spring-Netty/pom.xml
+++ b/Spring-Netty/pom.xml
@@ -16,7 +16,6 @@
1.8
- 4.1.6.Final
@@ -35,7 +34,6 @@
io.netty
netty-all
- ${netty-all.version}
diff --git a/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/NettyClient.java b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/NettyClient.java
new file mode 100644
index 0000000..4a701b4
--- /dev/null
+++ b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/NettyClient.java
@@ -0,0 +1,106 @@
+package com.bruis.learnnetty.im.client;
+
+import com.bruis.learnnetty.im.client.handler.*;
+import com.bruis.learnnetty.im.codec.PacketDecoder;
+import com.bruis.learnnetty.im.codec.PacketEncoder;
+import com.bruis.learnnetty.im.codec.Spliter;
+import com.bruis.learnnetty.im.console.ConsoleCommandManager;
+import com.bruis.learnnetty.im.console.LoginConsoleCommand;
+import com.bruis.learnnetty.im.model.LoginRequestPacket;
+import com.bruis.learnnetty.im.model.MessageRequestPacket;
+import com.bruis.learnnetty.im.util.SessionUtil;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+
+import java.util.Date;
+import java.util.Scanner;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @Description 客户端
+ * @Author luohaiyang
+ * @Date 2022/3/22
+ */
+public class NettyClient {
+ private static final int MAX_RETRY = 5;
+ private static final String HOST = "127.0.0.1";
+ private static final int PORT = 8000;
+
+
+ public static void main(String[] args) {
+ NioEventLoopGroup workerGroup = new NioEventLoopGroup();
+
+ Bootstrap bootstrap = new Bootstrap();
+ bootstrap
+ .group(workerGroup)
+ .channel(NioSocketChannel.class)
+ .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
+ .option(ChannelOption.SO_KEEPALIVE, true)
+ .option(ChannelOption.TCP_NODELAY, true)
+ .handler(new ChannelInitializer() {
+ @Override
+ public void initChannel(SocketChannel ch) {
+ // 拆包粘包处理
+ ch.pipeline().addLast(new Spliter());
+ // 编码
+ ch.pipeline().addLast(new PacketDecoder());
+ // 登录响应
+ ch.pipeline().addLast(new LoginResponseHandler());
+ // 消息返回
+ ch.pipeline().addLast(new MessageResponseHandler());
+ ch.pipeline().addLast(new CreateGroupResponseHandler());
+ ch.pipeline().addLast(new JoinGroupResponseHandler());
+ ch.pipeline().addLast(new QuitGroupResponseHandler());
+ ch.pipeline().addLast(new ListGroupMembersResponseHandler());
+ ch.pipeline().addLast(new GroupMessageResponseHandler());
+ ch.pipeline().addLast(new LogoutResponseHandler());
+ // 解码
+ ch.pipeline().addLast(new PacketEncoder());
+ }
+ });
+
+ connect(bootstrap, HOST, PORT, MAX_RETRY);
+ }
+
+ private static void connect(Bootstrap bootstrap, String host, int port, int retry) {
+ bootstrap.connect(host, port).addListener(future -> {
+ if (future.isSuccess()) {
+ System.out.println(new Date() + ": 连接成功,启动控制台线程……");
+ Channel channel = ((ChannelFuture) future).channel();
+ startConsoleThread(channel);
+ } else if (retry == 0) {
+ System.err.println("重试次数已用完,放弃连接!");
+ } else {
+ // 第几次重连
+ int order = (MAX_RETRY - retry) + 1;
+ // 本次重连的间隔
+ int delay = 1 << order;
+ System.err.println(new Date() + ": 连接失败,第" + order + "次重连……");
+ bootstrap.config().group().schedule(() -> connect(bootstrap, host, port, retry - 1), delay, TimeUnit
+ .SECONDS);
+ }
+ });
+ }
+
+ private static void startConsoleThread(Channel channel) {
+ ConsoleCommandManager consoleCommandManager = new ConsoleCommandManager();
+ LoginConsoleCommand loginConsoleCommand = new LoginConsoleCommand();
+ Scanner scanner = new Scanner(System.in);
+
+ new Thread(() -> {
+ while (!Thread.interrupted()) {
+ if (!SessionUtil.hasLogin(channel)) {
+ loginConsoleCommand.exec(scanner, channel);
+ } else {
+ consoleCommandManager.exec(scanner, channel);
+ }
+ }
+ }).start();
+ }
+}
diff --git a/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/CreateGroupResponseHandler.java b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/CreateGroupResponseHandler.java
new file mode 100644
index 0000000..04125de
--- /dev/null
+++ b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/CreateGroupResponseHandler.java
@@ -0,0 +1,19 @@
+package com.bruis.learnnetty.im.client.handler;
+
+import com.bruis.learnnetty.im.model.CreateGroupResponsePacket;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+
+/**
+ * @Description
+ * @Author luohaiyang
+ * @Date 2022/3/23
+ */
+public class CreateGroupResponseHandler extends SimpleChannelInboundHandler {
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, CreateGroupResponsePacket msg) throws Exception {
+ System.out.print("群创建成功,id 为[" + msg.getGroupId() + "], ");
+ System.out.println("群里面有:" + msg.getUserNameList());
+ }
+}
diff --git a/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/GroupMessageResponseHandler.java b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/GroupMessageResponseHandler.java
new file mode 100644
index 0000000..3dc9921
--- /dev/null
+++ b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/GroupMessageResponseHandler.java
@@ -0,0 +1,20 @@
+package com.bruis.learnnetty.im.client.handler;
+
+import com.bruis.learnnetty.im.model.GroupMessageResponsePacket;
+import com.bruis.learnnetty.im.session.Session;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+
+/**
+ * @Description
+ * @Author luohaiyang
+ * @Date 2022/3/24
+ */
+public class GroupMessageResponseHandler extends SimpleChannelInboundHandler {
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, GroupMessageResponsePacket responsePacket) {
+ String fromGroupId = responsePacket.getFromGroupId();
+ Session fromUser = responsePacket.getFromUser();
+ System.out.println("收到群[" + fromGroupId + "]中[" + fromUser + "]发来的消息:" + responsePacket.getMessage());
+ }
+}
\ No newline at end of file
diff --git a/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/JoinGroupResponseHandler.java b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/JoinGroupResponseHandler.java
new file mode 100644
index 0000000..cc7efea
--- /dev/null
+++ b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/JoinGroupResponseHandler.java
@@ -0,0 +1,21 @@
+package com.bruis.learnnetty.im.client.handler;
+
+import com.bruis.learnnetty.im.model.JoinGroupResponsePacket;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+
+/**
+ * @Description
+ * @Author luohaiyang
+ * @Date 2022/3/24
+ */
+public class JoinGroupResponseHandler extends SimpleChannelInboundHandler {
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, JoinGroupResponsePacket responsePacket) throws Exception {
+ if (responsePacket.isSuccess()) {
+ System.out.println("加入群[" + responsePacket.getGroupId() + "]成功!");
+ } else {
+ System.err.println("加入群[" + responsePacket.getGroupId() + "]失败,原因为:" + responsePacket.getReason());
+ }
+ }
+}
diff --git a/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/ListGroupMembersResponseHandler.java b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/ListGroupMembersResponseHandler.java
new file mode 100644
index 0000000..0117eac
--- /dev/null
+++ b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/ListGroupMembersResponseHandler.java
@@ -0,0 +1,18 @@
+package com.bruis.learnnetty.im.client.handler;
+
+import com.bruis.learnnetty.im.model.ListGroupMembersResponsePacket;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+
+/**
+ * @Description
+ * @Author luohaiyang
+ * @Date 2022/3/24
+ */
+public class ListGroupMembersResponseHandler extends SimpleChannelInboundHandler {
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, ListGroupMembersResponsePacket responsePacket) {
+ System.out.println("群[" + responsePacket.getGroupId() + "]中的人包括:" + responsePacket.getSessionList());
+ }
+}
\ No newline at end of file
diff --git a/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/LoginResponseHandler.java b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/LoginResponseHandler.java
new file mode 100644
index 0000000..282afcc
--- /dev/null
+++ b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/LoginResponseHandler.java
@@ -0,0 +1,33 @@
+package com.bruis.learnnetty.im.client.handler;
+
+import com.bruis.learnnetty.im.model.LoginResponsePacket;
+import com.bruis.learnnetty.im.session.Session;
+import com.bruis.learnnetty.im.util.SessionUtil;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+
+/**
+ * @Description 登录响应的reponse
+ * @Author luohaiyang
+ * @Date 2022/3/23
+ */
+public class LoginResponseHandler extends SimpleChannelInboundHandler {
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, LoginResponsePacket loginResponsePacket) throws Exception {
+ String userId = loginResponsePacket.getUserId();
+ String userName = loginResponsePacket.getUserName();
+
+ if (loginResponsePacket.isSuccess()) {
+ System.out.println("[" + userName + "]登录成功,userId 为: " + loginResponsePacket.getUserId());
+ SessionUtil.bindSession(new Session(userId, userName), ctx.channel());
+ } else {
+ System.out.println("[" + userName + "]登录失败,原因:" + loginResponsePacket.getReason());
+ }
+ }
+
+ @Override
+ public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+ System.out.println("客户端连接被关闭");
+ }
+}
diff --git a/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/LogoutResponseHandler.java b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/LogoutResponseHandler.java
new file mode 100644
index 0000000..78fd173
--- /dev/null
+++ b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/LogoutResponseHandler.java
@@ -0,0 +1,19 @@
+package com.bruis.learnnetty.im.client.handler;
+
+import com.bruis.learnnetty.im.model.LogoutResponsePacket;
+import com.bruis.learnnetty.im.util.SessionUtil;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+
+/**
+ * @Description
+ * @Author luohaiyang
+ * @Date 2022/3/23
+ */
+public class LogoutResponseHandler extends SimpleChannelInboundHandler {
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, LogoutResponsePacket logoutResponsePacket) {
+ SessionUtil.unBindSession(ctx.channel());
+ }
+}
\ No newline at end of file
diff --git a/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/MessageResponseHandler.java b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/MessageResponseHandler.java
new file mode 100644
index 0000000..ea6fac1
--- /dev/null
+++ b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/MessageResponseHandler.java
@@ -0,0 +1,19 @@
+package com.bruis.learnnetty.im.client.handler;
+
+import com.bruis.learnnetty.im.model.MessageResponsePacket;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+
+/**
+ * @Description
+ * @Author luohaiyang
+ * @Date 2022/3/23
+ */
+public class MessageResponseHandler extends SimpleChannelInboundHandler {
+ @Override
+ protected void channelRead0(ChannelHandlerContext channelHandlerContext, MessageResponsePacket messageResponsePacket) throws Exception {
+ String fromUserId = messageResponsePacket.getFromUserId();
+ String fromUserName = messageResponsePacket.getFromUserName();
+ System.out.println(fromUserId + ":" + fromUserName + " -> " + messageResponsePacket.getMessage());
+ }
+}
diff --git a/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/QuitGroupResponseHandler.java b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/QuitGroupResponseHandler.java
new file mode 100644
index 0000000..be82bd5
--- /dev/null
+++ b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/client/handler/QuitGroupResponseHandler.java
@@ -0,0 +1,22 @@
+package com.bruis.learnnetty.im.client.handler;
+
+import com.bruis.learnnetty.im.model.QuitGroupResponsePacket;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+
+/**
+ * @Description
+ * @Author luohaiyang
+ * @Date 2022/3/24
+ */
+public class QuitGroupResponseHandler extends SimpleChannelInboundHandler {
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, QuitGroupResponsePacket responsePacket) throws Exception {
+ if (responsePacket.isSuccess()) {
+ System.out.println("退出群聊[" + responsePacket.getGroupId() + "]成功!");
+ } else {
+ System.out.println("退出群聊[" + responsePacket.getGroupId() + "]失败!");
+ }
+ }
+}
diff --git a/Spring-Netty/src/main/java/com/bruis/learnnetty/im/codec/PacketCodecHandler.java b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/codec/PacketCodecHandler.java
new file mode 100644
index 0000000..35aa573
--- /dev/null
+++ b/Spring-Netty/src/main/java/com/bruis/learnnetty/im/codec/PacketCodecHandler.java
@@ -0,0 +1,35 @@
+package com.bruis.learnnetty.im.codec;
+
+import com.bruis.learnnetty.im.model.Packet;
+import com.bruis.learnnetty.im.model.PacketCodeC;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToMessageCodec;
+
+import java.util.List;
+
+/**
+ * @Description
+ * @Author luohaiyang
+ * @Date 2022/3/25
+ */
+@ChannelHandler.Sharable
+public class PacketCodecHandler extends MessageToMessageCodec {
+
+ public static final PacketCodecHandler INSTANCE = new PacketCodecHandler();
+
+ private PacketCodecHandler() {}
+
+ @Override
+ protected void encode(ChannelHandlerContext ctx, Packet msg, List