SpringBoot整合Netty

版权声明:技术交流群:758191639 作者支付宝18696232390喜欢的可以打钱! https://blog.csdn.net/u014131617/article/details/86489827

1.依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	
	<groupId>com.cxl</groupId>
	<artifactId>cxl-longdada-netty</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>cxl-longdada-netty</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.3.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>
		
		<dependency>
			<groupId>io.netty</groupId>
			<artifactId>netty-all</artifactId>
			<version>4.1.25.Final</version>
		</dependency>
		
		<!-- apache 工具类 -->
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
			<version>1.11</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.4</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-io</artifactId>
			<version>1.3.2</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.41</version>
		</dependency>

		<!-- mybatis -->
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.1</version>
		</dependency>
		<!--mapper -->
		<dependency>
			<groupId>tk.mybatis</groupId>
			<artifactId>mapper-spring-boot-starter</artifactId>
			<version>1.2.4</version>
		</dependency>
		<!--pagehelper -->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper-spring-boot-starter</artifactId>
			<version>1.2.3</version>
		</dependency>

		<!-- 高性能分布式文件服务器 -->
		<dependency>
		    <groupId>com.github.tobato</groupId>
		    <artifactId>fastdfs-client</artifactId>
		    <version>1.26.2</version>
		</dependency>
		
		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-test</artifactId>
		</dependency>
		
		<!-- 二维码 -->
		<dependency>
		    <groupId>com.google.zxing</groupId>
		    <artifactId>javase</artifactId>
		    <version>3.3.3</version>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

2.配置文件

#fdfs.soTimeout=1501
#fdfs.connectTimeout=601
#fdfs.thumbImage.width=80
#fdfs.thumbImage.height=80
#fdfs.trackerList[0]=192.168.1.70:22122




spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/longdada?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.pool-name=DatebookHikariCP
spring.datasource.hikari.max-lifetime=28740000
spring.datasource.hikari.connection-test-query=SELECT 1


mybatis.type-aliases-package=com.cxl.pojo
mybatis.mapper-locations=classpath:mapper/*.xml
mapper.mappers=com.cxl.utils.MyMapper
mapper.not-empty=false
mapper.identity=MYSQL
pagehelper.helperDialect=mysql
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql

server.port=8080


server.tomcat.uri-encoding=UTF-8

3.项目结构

在这里插入图片描述

4.启动类

package com.cxl;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

import tk.mybatis.spring.annotation.MapperScan;

@SpringBootApplication
@ComponentScan(basePackages= {"com.cxl"})
@MapperScan(basePackages= {"com.cxl.mapper"})
public class CxlLongdadaNettyApplication {

	public static void main(String[] args) {
		SpringApplication.run(CxlLongdadaNettyApplication.class, args);
	}

}


5.netty启动类

package com.cxl;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import com.cxl.netty.WSServer;

@Component
public class NettyBooter implements ApplicationListener<ContextRefreshedEvent>{

	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		if(event.getApplicationContext().getParent() == null) {
			try {
				WSServer.getInstance().start();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
}

6.netty配置类

WSServer.java

package com.cxl.netty;

import org.springframework.stereotype.Component;

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;

@Component
public class WSServer {
	
	//单例
	private static class SingletionWSServer{
		static final WSServer INSTANCE = new WSServer();
	}
	
	public static WSServer getInstance() {
		return SingletionWSServer.INSTANCE;
	}
	
	private EventLoopGroup mainGroup;
	private EventLoopGroup subGroup; 
	private ServerBootstrap serverBootstrap; 
	private ChannelFuture channelFuture; 
	
	public WSServer() {
		 mainGroup = new NioEventLoopGroup();
		 subGroup = new NioEventLoopGroup();
		 serverBootstrap = new ServerBootstrap();
		 serverBootstrap.group(mainGroup,subGroup)
			.channel(NioServerSocketChannel.class)
			.childHandler(new WSServerInitialzer());
	}
	
	//开启服务器
	public void start() {
		this.channelFuture = serverBootstrap.bind(8077);
		System.err.println("netty websocket server run successfully!!!");
	}
	
	
}

ChatHandler.java

package com.cxl.netty;

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.channel.local.LocalChannel;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 *  处理消息的handler
 * @author mingliang
 *TextWebSocketFrame websocket专门处理文本的对象 ,frame是载体
 */
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame>{

	//管理所有客户端的channel
	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("msg : "+content);
		
		for (Channel channel : clients) {
			channel.writeAndFlush(
					new TextWebSocketFrame
					("[服务器在:]"+LocalDateTime.now()+
							",接收到消息为:"+content));
		}
		
		//以下写法和for循环一致
//		clients.writeAndFlush(new TextWebSocketFrame
//					("[服务器在:]"+LocalDateTime.now()+
//							",接收到消息为:"+content));
	}
	
	//用户进入
	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
		clients.add(ctx.channel());
		System.out.println("添加cid" + ctx.channel().id());clients.add(ctx.channel());
	}

	//用户离开
	@Override
	public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
		clients.remove(ctx.channel());
		System.out.println("移除cid" + ctx.channel().id());
		System.out.println("移除长id" + ctx.channel().id().asLongText());
		System.out.println("移除短id" + ctx.channel().id().asShortText());
	}
	
	

}

WSServerInitialzer.java

package com.cxl.netty;

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 channel) throws Exception {
		ChannelPipeline pipeline = channel.pipeline();
		
		//编解码器
		pipeline.addLast(new HttpServerCodec());
		//对大数据流处理
		pipeline.addLast(new ChunkedWriteHandler());
		// 对httpmessage进行聚合,聚合成fullhttprequest或fullhttpresponse
		// 几乎在netty中的编程都会使用到此hanler
		pipeline.addLast(new HttpObjectAggregator(1024*64));
		
		//===================以上是用于支持http协议===================
		
		//websocket服务器处理的协议,用于指定给客户端连接访问的路由
		pipeline.addLast(
				new WebSocketServerProtocolHandler("/ws"));
		
		//自定义拦截器
		pipeline.addLast(new ChatHandler());
		
		
		
		
		
		
	}

}

猜你喜欢

转载自blog.csdn.net/u014131617/article/details/86489827