代码语言:javascript复制毕设需求,调研一下,新手来说任何项目都是从研究demo开始的(至少我这个菜鸡就这样,只能先研究研究再开始做自己的项目),这里提供了一个我最开始的demo,提供借鉴
<!--先来一下netty的 maven仓库配置需求-->
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.25.Final</version>
</dependency>
服务端搭建
服务器三个代码块基本是层层构建,像盖房子一样从低向上一样 部分代码是常规配置,大家注意看注释哦
1.1服务器基础配置
代码语言:javascript复制package com.zyh.future.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class WebSocketNettyServer {
public static void main(String[] args){
//创建netty的主从两个线程池
NioEventLoopGroup mainGrp = new NioEventLoopGroup();//主线程池
NioEventLoopGroup subGrp = new NioEventLoopGroup();//从线程池
try {
//创建Netty服务器启动对象
ServerBootstrap serverBootstrap = new ServerBootstrap();
//初始化服务器启动对象
serverBootstrap
//为netty服务器指定和配备主从线程池
.group(mainGrp,subGrp)
//指定netty通道类型
.channel(NioServerSocketChannel.class)
//指定通道初始化器用来加载当channel收到消息后
//如何进行业务处理
.childHandler(new WebSocketChannelInitializer());
//绑定服务器端口, 以同步的方式启动服务器
ChannelFuture channelFuture = serverBootstrap.bind(9090).sync();
//等待服务器关闭
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//使用优雅的方式关闭服务器
//主要是关闭两个线程池
mainGrp.shutdownGracefully();
subGrp.shutdownGracefully();
}
}
}
2.2服务器初始化配置
代码语言:javascript复制package com.zyh.future.server;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
/**
* 功能描述: 通道初始化器器
* 用来加载通道处理器(channelhandler)
* @Author: Zyh
* @Date: 2020/1/22 20:31
*/
public class WebSocketChannelInitializer extends ChannelInitializer<SocketChannel> {
@Override
//初始化通道
//在这个方法中加载对应的ChannelHandler
protected void initChannel(SocketChannel socketChannel) throws Exception {
/* 固定写法部分*/
//获取管道,将一个个ChannelHandler添加到管道中
ChannelPipeline channelPipeline = socketChannel.pipeline();
//可以将channelpipeline理解为拦截器
//当我们的socketChannel数据进来时候会依次调用我们的ChannelHandler
//添加一个http的编解码器
channelPipeline.addLast(new HttpServerCodec());
//添加大数据流支持
channelPipeline.addLast(new ChunkedWriteHandler());
//添加聚合器 ,可以将我们的httpmaessage聚合成Fullhttprequest/respond ---想拿到请求和响应就要添加聚合器
channelPipeline.addLast(new HttpObjectAggregator(1024*24));//指定缓存大小
/* 固定写法部分*/
//指定接收请求的路由
//指定必须使用ws为结尾的url才能访问
channelPipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
//添加自定义的handler进行业务处理
channelPipeline.addLast(new ChatHandler());
}
}
3.3 服务器业务处理
代码语言:javascript复制package com.zyh.future.server;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import java.text.SimpleDateFormat;
import java.util.Date;
//extends SimpleChannelInboundHandler<TextWebSocketFrame> 使我们接收到的消息会封装到一个TextWebSocketFrame中
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
//用来保存所有的客户端连接
private static ChannelGroup clients=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
//创建一个时间生成器
private SimpleDateFormat sdf=new SimpleDateFormat("yyyy-mm-dd hh:MM");
@Override //该方面当接收到数据时候会自动调用
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
String text=msg.text();
System.out.println("接收到的消息为: " text);
//遍历clients(所有客户端,群发)
for (Channel client:clients){
//发送消息并刷新通道
client.writeAndFlush(new TextWebSocketFrame(sdf.format(new Date()) ": " text));
}
}
@Override //当有新的客户端接入到服务器时候会自动调用该方法
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
clients.add(ctx.channel());//将新的连接加入channel中
}
}
客户端搭建
代码语言:javascript复制最简单的demo级别,主要大家可以简单清晰的看出来数据的传输和响应
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>在线聊天室</title>
</head>
<body>
<input type="text" id="message">
<input type="button" value="发送消息" onclick="sendMessage()">
</br>
接收到的消息为:
</br>
<p id="server_message" style="background-color: #aaaaaa"></p>
<script>
//判断当前浏览器是否支持websocket (H5才支持)
var websocket=null;
if (window.WebSocket){
websocket=new WebSocket("ws://127.0.0.1:9090/ws");//前面的ws是协议,后面的ws是我们指定了接收的为ws结尾的路由
websocket.onopen=function () {
console.log("建立连接");
}
websocket.onclose=function () {
console.log("断开连接");
}
websocket.onmessage=function (e) {
console.log("接收到服务器的数据为: " e.data);
var server_messsage=document.getElementById("server_message");
server_messsage.innerHTML =e.data "</br>";
}
}else {
alert("当前浏览器不支持websocket");
}
function sendMessage() {
var message=document.getElementById("message");
websocket.send(message.value);
}
</script>
</body>
</html>