Netty简介
Netty是基于Java NIO client-server的网络应用框架,使用Netty可以快速开发网络应用,例如服务器和客户端协议。Netty提供了一种新的方式来开发网络应用程序,这种新的方式使它很容易使用和具有很强的扩展性。Netty的内部实现是很复杂的,但是Netty提供了简单易用的API从网络处理代码中解耦业务逻辑。Netty是完全基于NIO实现的,所以整个Netty都是异步的。
项目源码:百度网盘 请输入提取码 提取码: 4e7u
1.服务端
步骤一:pom文件引入
步骤二:NettyConfig
package com.example.nettybackstage.config;import io.netty.channel.Channel;import io.netty.channel.group.ChannelGroup;import io.netty.channel.group.DefaultChannelGroup;import io.netty.util.concurrent.GlobalEventExecutor;import java.util.concurrent.ConcurrentHashMap;public class NettyConfig { private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); private static ConcurrentHashMap
步骤三:NettyServer
package com.example.nettybackstage.config;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioServerSocketChannel;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.codec.serialization.ObjectEncoder;import io.netty.handler.stream.ChunkedWriteHandler;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;import javax.annotation.PreDestroy;import java.net.InetSocketAddress;@Componentpublic class NettyServer{ private static final Logger log = LoggerFactory.getLogger(NettyServer.class); @Value("${webSocket.protocol}") private String webSocketProtocol; @Value("${webSocket.netty.port}") private int port; @Value("${webSocket.netty.path}") private String webSocketPath; @Autowired private WebSocketHandler webSocketHandler; private EventLoopGroup bossGroup; private EventLoopGroup workGroup; private void start() throws InterruptedException { //数据量上来时设置线程池 bossGroup = new NioEventLoopGroup(); workGroup = new NioEventLoopGroup(); ServerBootstrap bootstrap = new ServerBootstrap(); // bossGroup辅助客户端的tcp连接请求, workGroup负责与客户端之前的读写操作 bootstrap.group(bossGroup,workGroup); // 设置NIO类型的channel bootstrap.channel(NioServerSocketChannel.class); // 设置监听端口 bootstrap.localAddress(new InetSocketAddress(port)); // 连接到达时会创建一个通道 bootstrap.childHandler(new ChannelInitializer
步骤四:WebSocketHandler
package com.example.nettybackstage.config;import cn.hutool.json.JSONObject;import cn.hutool.json.JSONUtil;import io.netty.channel.ChannelHandler;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.codec.http.websocketx.TextWebSocketframe;import io.netty.util.AttributeKey;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import org.springframework.util.ObjectUtils;import java.util.HashMap;import java.util.Map;@Component@ChannelHandler.Sharablepublic class WebSocketHandler extends SimpleChannelInboundHandler
步骤五:MessageDto
package com.example.nettybackstage.dto;import java.io.Serializable;import java.util.Map;public class MessageDto implements Serializable { public MessageDto(){} public MessageDto(String nettyId,String type,String status,String msg,Map
步骤六:PushService
package com.example.nettybackstage.service;import com.example.nettybackstage.dto.MessageDto;public interface PushService { public void sendMsgToOne(String type, MessageDto msg); public void sendMsgToAll(MessageDto msg);}
步骤七:PushServiceImpl
package com.example.nettybackstage.serviceimpl;import com.alibaba.fastjson.JSONObject;import com.example.nettybackstage.config.NettyConfig;import com.example.nettybackstage.config.WebSocketHandler;import com.example.nettybackstage.dto.MessageDto;import com.example.nettybackstage.service.PushService;import io.netty.channel.Channel;import io.netty.handler.codec.http.websocketx.TextWebSocketframe;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Service;import java.util.concurrent.ConcurrentHashMap;@Servicepublic class PushServiceImpl implements PushService { private static final Logger log = LoggerFactory.getLogger(PushServiceImpl.class); @Override public void sendMsgToOne(String type, MessageDto msg){ ConcurrentHashMap
步骤八:PushController
package com.example.nettybackstage.web;import com.example.nettybackstage.dto.MessageDto;import com.example.nettybackstage.serviceimpl.PushServiceImpl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;import java.util.Map;import java.util.UUID;@RestController@RequestMapping("/push")public class PushController { @Autowired private PushServiceImpl pushService; @PostMapping("/sendMsgToAll") public void sendMsgToAll(@RequestParam("msg") String msg){ MessageDto messageDto = new MessageDto(); String uuid = String.valueOf(UUID.randomUUID()).replace("-",""); messageDto.setNettyId(uuid); messageDto.setMsg(msg); messageDto.setStatus("0000"); messageDto.setType("netty_msg"); messageDto.setTypeId(""); messageDto.setDate("2021-12-05 21:19:10"); Map
步骤十:application.properties
server.port=8081#netty配置#连接端口webSocket.netty.port=58080#协定名称(可定义)webSocket.protocol=webSocket#路径webSocket.netty.path=/${webSocket.protocol}
2.页面客户端
步骤一
3.客户端
步骤一:pom
步骤二:WebSocketListener
package com.example.nettyclient.listener;import com.alibaba.fastjson.JSONObject;import lombok.extern.slf4j.Slf4j;import org.java_websocket.client.WebSocketClient;import org.java_websocket.drafts.Draft_6455;import org.java_websocket.handshake.ServerHandshake;import org.springframework.context.annotation.Bean;import org.springframework.stereotype.Component;import org.springframework.util.ObjectUtils;import java.net.URI;import java.util.HashMap;import java.util.Map;@Slf4j@Componentpublic class WebSocketListener { @Bean public WebSocketClient webSocketClient() { try { WebSocketClient webSocketClient = new WebSocketClient(new URI("ws://127.0.0.1:58080/webSocket"),new Draft_6455()) { @Override public void onOpen(ServerHandshake handshakedata) { log.info("[websocket] 连接成功"); Map
4.服务端和页面客户端互发消息
启动服务端和页面客户端,启动后访问页面:http://127.0.0.1:8082/index.html,如下:
用postman发送一条消息
页面成功接收到服务端即时发送的消息,同时页面也向服务端回发一条消息
5.服务端和客户端互相发送消息
启动服务
用postman调用服务端接口发送一条消息
成功接收到服务端消息