首先需要在后台建立netty服务器启动类;
package com.cxy;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;/*** * @ClassName: WsNetty * @Description: * @Auther: cxy * @Date: 2019/2/5:14:15 * @version : V1.0 */public class WsNetty { ???public static void main(String[] args) throws InterruptedException { ???????/* 主从线程组模型 ???????*/ ???????EventLoopGroup mainGroup =new NioEventLoopGroup(); ???????EventLoopGroup subGroup=new NioEventLoopGroup(); ???????try {
//创建核心类 ???????????ServerBootstrap serverBootstrap =new ServerBootstrap(); ???????????serverBootstrap.group(mainGroup,subGroup) ???????????????????.channel(NioServerSocketChannel.class) ???????????????????.childHandler(new WSServerInitialzer());//添加助手类 ???????????ChannelFuture channelFuture= serverBootstrap.bind(8088).sync(); ???????????channelFuture.channel().closeFuture().sync(); ???????} catch (InterruptedException e) { ???????????e.printStackTrace(); ???????}finally { ???????????mainGroup.shutdownGracefully(); ???????????subGroup.shutdownGracefully();//优雅的关闭主从线程池 ???????} ???}}
第二创建初始化类;
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;public class WSServerInitialzer extends ChannelInitializer<SocketChannel> { ???@Override ???protected void initChannel(SocketChannel ch) throws Exception { ???????ChannelPipeline pipeline = ch.pipeline(); ???????????????// websocket 基于http协议,所以要有http编解码器 ???????pipeline.addLast(new HttpServerCodec()); ???????// 对写大数据流的支持 ????????pipeline.addLast(new ChunkedWriteHandler()); ???????// 对httpMessage进行聚合,聚合成FullHttpRequest或FullHttpResponse ???????// 几乎在netty中的编程,都会使用到此hanler ???????pipeline.addLast(new HttpObjectAggregator(1024*64)); ???????????????// ====================== 以上是用于支持http协议 ???====================== ???????????????// ====================== 以下是支持httpWebsocket ====================== ???????????????/** ????????* websocket 服务器处理的协议,用于指定给客户端连接访问的路由 : /ws ????????* 本handler会帮你处理一些繁重的复杂的事 ????????* 会帮你处理握手动作: handshaking(close, ping, pong) ping + pong = 心跳 ????????* 对于websocket来讲,都是以frames进行传输的,不同的数据类型对应的frames也不同 ????????*/ ???????pipeline.addLast(new WebSocketServerProtocolHandler("/ws")); ???????????????// 自定义的handler ???????pipeline.addLast(new ChatHandler()); ???}}
第三步:创建助手类
import java.time.LocalDateTime;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;/** * ?* @Description: 处理消息的handler * TextWebSocketFrame: 在netty中,是用于为websocket专门处理文本的对象,frame是消息的载体 */public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> { ???// 用于记录和管理所有客户端的channle ???private static ChannelGroup clients = ????????????new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); ???????@Override ???protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) ????????????throws Exception { ???????// 获取客户端传输过来的消息 ???????String content = msg.text(); ???????System.out.println("接受到的数据:" + content); ???????// ???????for (Channel channel: clients) {// ???????????channel.writeAndFlush(// ???????????????new TextWebSocketFrame(// ???????????????????????"[服务器在]" + LocalDateTime.now() // ???????????????????????+ "接受到消息, 消息为:" + content));// ???????} ???????// 下面这个方法,和上面的for循环,一致 ???????clients.writeAndFlush( ???????????????new TextWebSocketFrame( ???????????????????????"[服务器在]" + LocalDateTime.now() ????????????????????????+ "接受到消息, 消息为:" + content)); ???????????} ???/** ????* 当客户端连接服务端之后(打开连接) ????* 获取客户端的channle,并且放到ChannelGroup中去进行管理 ????*/ ???@Override ???public void handlerAdded(ChannelHandlerContext ctx) throws Exception { ???????clients.add(ctx.channel()); ???} ???@Override ???public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { ???????// 当触发handlerRemoved,ChannelGroup会自动移除对应客户端的channel// ???????clients.remove(ctx.channel()); ???????System.out.println("客户端断开,channle对应的长id为:" ????????????????????????????+ ctx.channel().id().asLongText()); ???????System.out.println("客户端断开,channle对应的短id为:" ????????????????????????????+ ctx.channel().id().asShortText()); ???} ???????}
前端页面:
<!DOCTYPE html><html> ???<head> ???????<meta charset="utf-8" /> ???????<title></title> ???</head> ???<body> ???????<div>发送消息</div> ???????<input type="text" id="msgContent" /> ???????<input type="button" value="点我发送" onclick="chat.chat1()" /> ???????<div>接受消息</div> ???????<div id="receiveMsg" style="background-color: gainsboro;"> </div> ???????<script type="application/javascript"> ???????????????????????window.chat={ ???????????????????????????????socket:null, ???????????????init:function(){ ???????????????????if(window.WebSocket){ ???????????????????????chat.socket =new WebSocket("ws://127.0.0.1:8088/ws"); ???????????????????????chat.socket.onopen =function(){ ???????????????????????????console.log("连接建立成功"); ???????????????????????}, ???????????????????????chat.socket.onclose =function(){ ???????????????????????????console.log("连接关闭"); ???????????????????????????????????????????????????}, ???????????????????????chat.socket.onerror =function(){ ???????????????????????????console.log("连接出错"); ???????????????????????}, ???????????????????????chat.socket.onmessage =function(e){ ???????????????????????????console.log("接受到消息"+e.data); ???????????????????????????var receiveMsg =document.getElementById("receiveMsg"); ???????????????????????????var html =receiveMsg.innerHTML; ???????????????????????????receiveMsg.innerHTML=html+"<br/>"+e.data; ???????????????????????????????????????????????????} ???????????????????????????????????????????}else{ ???????????????????????alert("浏览器不支持协议"); ???????????????????} ???????????????????????????????????}, ???????????????chat1:function(){ ???????????????????var msg =document.getElementById("msgContent"); ???????????????????chat.socket.send(msg.value); ???????????????????????????????????} ???????????????????????????}; ???????????chat.init(); ???????</script> ???</body></html>
测试结果:
netty结合websocket使用
原文地址:https://www.cnblogs.com/xiufengchen/p/10352841.html