demo效果
初步准备
想要实现聊天就需要用到WebSocket,他是专门用于http进行实时聊天的的协议。因为主要核心在后端开发,所以我去白嫖了个超级简单的界面(就是不会!)
我编写demo时系统环境为Win-11,Java-8
环境依赖
只需要一个netty即可实现需要的功能
<!--netty-->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.86.Final</version>
</dependency>
其余依赖
如果你是一点不会可能会有几个函数会出现问题,那我也贴出来
<!--日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.20</version>
</dependency>
前端代码
就是一个简单的发送消息然后显示返回消息的界面,然后通过websocket来发送和接收,没有其他任何元素。
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<head>
<title>实时聊天</title>
</head>
<body>
<div id="chat">
<div id="messages"></div>
<input type="text" id="messageInput" placeholder="输入消息...">
<button onclick="sendMessage()">发送</button>
</div>
<script>
let ws;
function connect() {
//你的websocket
ws = new WebSocket('ws://localhost:32001/daimouren');
ws.onmessage = function(event) {
let message = event.data;
document.getElementById('messages').innerHTML += '<div>' + message + '</div>';
};
ws.onerror = function(event) {
console.error("WebSocket error observed:", event);
};
}
function sendMessage() {
let message = document.getElementById('messageInput').value;
ws.send(message);
document.getElementById('messageInput').value = '';
}
window.onload = connect;
</script>
</body>
</html>
后端代码
后端代码也是非常简单,Netty已经对websocket实现进行了封装。此处就是简单的一个实现对应的功能的demo。核心的逻辑就是这些,之后改协议,绑定数据库等操作我就懒得写了。主要就是demo
package com.daimouren.netty.communicate;
import ch.qos.logback.core.util.TimeUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.HttpUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
/**
* HTTP页面实时交流功能(服务端)
* @author daimouren
* @since 2023/11/29
*/
@Slf4j
public class CommunicateServerDemo {
private static final List<Channel> CONNECT_LIST = new ArrayList<>();
public static void main(String[] args) {
ServerBootstrap server = new ServerBootstrap();
NioEventLoopGroup group = new NioEventLoopGroup();
NioEventLoopGroup event = new NioEventLoopGroup();
server.group(group,event); //监听事件处理
server.channel(NioServerSocketChannel.class);
server.childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch) {
//打印的日志
ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
//http协议处理器
ch.pipeline().addLast(new HttpServerCodec());
//半包黏包处理器,这个处理器专门用于http非常适合。请求为最大请求长度
ch.pipeline().addLast(new HttpObjectAggregator(65536));
//websocket的处理器。参数为请求路径
ch.pipeline().addLast(new WebSocketServerProtocolHandler("/daimouren"));
//websocket核心逻辑处理器
ch.pipeline().addLast(new SimpleChannelInboundHandler<TextWebSocketFrame>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
//接收消息
String text = msg.text();
//创建发送消息体
TextWebSocketFrame backText = new TextWebSocketFrame((text));
//发送消息给除了自己的所有人
CONNECT_LIST.forEach(channel -> {
if (channel != ctx.channel()){
//发送消息
channel.writeAndFlush(backText);
}
});
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
//将连接添加到数组
CONNECT_LIST.add(ctx.channel());
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
//将连接提出数组
CONNECT_LIST.remove(ctx.channel());
}
});
}
});
try {
# 端口绑定
Channel channel = server.bind(32001).sync().channel();
channel.closeFuture().sync();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
group.shutdownGracefully();
event.shutdownGracefully();
}
}
}
标签:netty,ch,Java,Netty,demo,io,new,import,channel
From: https://www.cnblogs.com/daimourentop/p/17865097.html