1.登录账号
2.登陆后会显示
3.当另一个用户登录
4.两个用户相互交流不会影响其他用户
下面上代码
pom.xml 添加netty的依赖
io.netty
netty-all
5.0.0.Alpha1
@SpringBootApplication
public class App implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
//实现CommandLineRunner 重写run方法 这里放了netty的启动
@Override
public void run(String... args) throws Exception {
new NettyService();
}
}
/**
*
* @author Dream
* Netty的服务
*
*/
public class NettyService {
public NettyService() {
/*new Thread(() -> {*/
System.out.println("启动Netty!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new MyChannelInitializer());
Channel channel = serverBootstrap.bind(9099).sync().channel();
channel.closeFuture().sync();
} catch (Exception e) {
System.err.println(e);
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
/*}).start();*/
}
}
/**
*
* @author Dream
*
* 组装handler
*/
public class MyChannelInitializer extends ChannelInitializer {
@Override
protected void initChannel(Channel channel) throws Exception {
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast("http-codec", new HttpServerCodec()); // Http消息编码解码
pipeline.addLast("aggregator", new HttpObjectAggregator(65536)); // Http消息组装
pipeline.addLast("http-chunked", new ChunkedWriteHandler()); // WebSocket通信支持
pipeline.addLast("handler", new MyMatchingHandler());//每两个匹配房间
}
}
/**
*
* @author Dream
*
* 自定义的Handler
*/
public class MyMatchingHandler extends SimpleChannelInboundHandler
/**
* 存储信息
*/
public class InformationOperateMapMatching {
public static ConcurrentMap> map = new ConcurrentHashMap<>();
public static Queue queue = new ConcurrentLinkedQueue<>();
public static ConcurrentMap login = new ConcurrentHashMap<>();
private ChannelHandlerContext ctx;
private Mage mage;
private InformationOperateMapMatching(ChannelHandlerContext ctx, Mage mage) {
this.ctx = ctx;
this.mage = mage;
}
/**
* 添加到队列当中等待其他用户登录后匹配
* @param ctx
* @param mage
*/
public static void offer(ChannelHandlerContext ctx, Mage mage) {
queue.offer(new InformationOperateMapMatching(ctx, mage));
}
/**
* 添加用户信息
* @param ctx
* @param mage
*/
public static void add(ChannelHandlerContext ctx, Mage mage) {
InformationOperateMapMatching iom = new InformationOperateMapMatching(ctx, mage);
ConcurrentMap cmap = new ConcurrentHashMap<>();
if (map.containsKey(mage.getTable())) {
map.get(mage.getTable()).put(mage.getId(), iom);
} else {
cmap.put(mage.getId(), iom);
map.put(mage.getTable(), cmap);
}
login.replace(mage.getId(), mage.getTable());
}
/**
* 删除用户信息
* @param id
* @param table
*/
public static void delete(String id, String table) {
ConcurrentMap cmap = map.get(table);
if (cmap.size() <= 1) {
map.remove(table);
} else {
cmap.remove(id);
}
}
/**
* 给用户发送消息
* @param mage
* @throws Exception
*/
public void sead(Mage mage) throws Exception{
//this.ctx.channel().write(new TextWebSocketFrame(mage.toJson()));
//this.ctx.flush();
this.ctx.writeAndFlush(new TextWebSocketFrame(mage.toJson()));
}
public Mage getMage() {
return this.mage;
}
public ChannelHandlerContext getChannelHandlerContext() {
return this.ctx;
}
public InformationOperateMapMatching setTableId(String table) {
this.mage.setTableId(table);
return this;
}
}
/**
* 解析消息
* 将前台发过来的消息解析成Mage
* 后台发送消息到前台转成json字符串
*/
@Data
public class Mage {
private static ObjectMapper gson = new ObjectMapper();
/*private static Gson gson = new Gson();*/
/**
* 那个聊天室
*/
private String table;
/**
* 用户id
*/
private String id;
/**
* 用户名
*/
private String name;
/**
* 所发送的消息
*/
private String message;
/**
* 将json字符串转成Mage
* @param message
* @return
* @throws Exception
*/
public static Mage strJson2Mage(String message) throws Exception{
return Strings.isNullOrEmpty(message) ? null : gson.readValue(message, Mage.class);
}
/**
* 将Mage转成json字符串
* @return
* @throws Exception
*/
public String toJson() throws Exception{
return gson.writeValueAsString(this);
}
public Mage setTableId(String table) {
this.setTable(table);
return this;
}
}
前端页面:
netty一对一聊天室
请等待匹配
源码:https://github.com/dream-broken/springbootEasyFrame