文章目录
- 1.依赖
- 2.配置文件
- 3.项目结构
- 4.启动类
- 5.netty启动类
- 6.netty配置类
1.依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| 1<?xml version="1.0" encoding="UTF-8"?>
2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5
6 <groupId>com.cxl</groupId>
7 <artifactId>cxl-longdada-netty</artifactId>
8 <version>0.0.1-SNAPSHOT</version>
9 <name>cxl-longdada-netty</name>
10 <description>Demo project for Spring Boot</description>
11
12 <parent>
13 <groupId>org.springframework.boot</groupId>
14 <artifactId>spring-boot-starter-parent</artifactId>
15 <version>2.0.3.RELEASE</version>
16 <relativePath /> <!-- lookup parent from repository -->
17 </parent>
18
19 <properties>
20 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
21 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
22 <java.version>1.8</java.version>
23 </properties>
24
25 <dependencies>
26 <dependency>
27 <groupId>org.springframework.boot</groupId>
28 <artifactId>spring-boot-starter</artifactId>
29 </dependency>
30
31 <dependency>
32 <groupId>org.springframework.boot</groupId>
33 <artifactId>spring-boot-starter-web</artifactId>
34 </dependency>
35
36 <dependency>
37 <groupId>org.springframework.boot</groupId>
38 <artifactId>spring-boot-configuration-processor</artifactId>
39 <optional>true</optional>
40 </dependency>
41
42 <dependency>
43 <groupId>io.netty</groupId>
44 <artifactId>netty-all</artifactId>
45 <version>4.1.25.Final</version>
46 </dependency>
47
48 <!-- apache 工具类 -->
49 <dependency>
50 <groupId>commons-codec</groupId>
51 <artifactId>commons-codec</artifactId>
52 <version>1.11</version>
53 </dependency>
54 <dependency>
55 <groupId>org.apache.commons</groupId>
56 <artifactId>commons-lang3</artifactId>
57 <version>3.4</version>
58 </dependency>
59 <dependency>
60 <groupId>org.apache.commons</groupId>
61 <artifactId>commons-io</artifactId>
62 <version>1.3.2</version>
63 </dependency>
64
65 <dependency>
66 <groupId>mysql</groupId>
67 <artifactId>mysql-connector-java</artifactId>
68 <version>5.1.41</version>
69 </dependency>
70
71 <!-- mybatis -->
72 <dependency>
73 <groupId>org.mybatis.spring.boot</groupId>
74 <artifactId>mybatis-spring-boot-starter</artifactId>
75 <version>1.3.1</version>
76 </dependency>
77 <!--mapper -->
78 <dependency>
79 <groupId>tk.mybatis</groupId>
80 <artifactId>mapper-spring-boot-starter</artifactId>
81 <version>1.2.4</version>
82 </dependency>
83 <!--pagehelper -->
84 <dependency>
85 <groupId>com.github.pagehelper</groupId>
86 <artifactId>pagehelper-spring-boot-starter</artifactId>
87 <version>1.2.3</version>
88 </dependency>
89
90 <!-- 高性能分布式文件服务器 -->
91 <dependency>
92 <groupId>com.github.tobato</groupId>
93 <artifactId>fastdfs-client</artifactId>
94 <version>1.26.2</version>
95 </dependency>
96
97 <dependency>
98 <groupId>org.springframework</groupId>
99 <artifactId>spring-test</artifactId>
100 </dependency>
101
102 <!-- 二维码 -->
103 <dependency>
104 <groupId>com.google.zxing</groupId>
105 <artifactId>javase</artifactId>
106 <version>3.3.3</version>
107 </dependency>
108
109 </dependencies>
110
111 <build>
112 <plugins>
113 <plugin>
114 <groupId>org.springframework.boot</groupId>
115 <artifactId>spring-boot-maven-plugin</artifactId>
116 </plugin>
117 </plugins>
118 </build>
119
120</project>
121
122
123 |
2.配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| 1#fdfs.soTimeout=1501
2#fdfs.connectTimeout=601
3#fdfs.thumbImage.width=80
4#fdfs.thumbImage.height=80
5#fdfs.trackerList[0]=192.168.1.70:22122
6
7
8
9
10spring.datasource.driver-class-name=com.mysql.jdbc.Driver
11spring.datasource.url=jdbc:mysql://localhost:3306/longdada?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
12spring.datasource.username=root
13spring.datasource.password=root
14spring.datasource.type=com.zaxxer.hikari.HikariDataSource
15spring.datasource.hikari.connection-timeout=30000
16spring.datasource.hikari.minimum-idle=5
17spring.datasource.hikari.maximum-pool-size=15
18spring.datasource.hikari.auto-commit=true
19spring.datasource.hikari.idle-timeout=600000
20spring.datasource.hikari.pool-name=DatebookHikariCP
21spring.datasource.hikari.max-lifetime=28740000
22spring.datasource.hikari.connection-test-query=SELECT 1
23
24
25mybatis.type-aliases-package=com.cxl.pojo
26mybatis.mapper-locations=classpath:mapper/*.xml
27mapper.mappers=com.cxl.utils.MyMapper
28mapper.not-empty=false
29mapper.identity=MYSQL
30pagehelper.helperDialect=mysql
31pagehelper.supportMethodsArguments=true
32pagehelper.params=count=countSql
33
34server.port=8080
35
36
37server.tomcat.uri-encoding=UTF-8
38
39 |
3.项目结构
4.启动类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 1package com.cxl;
2
3import org.springframework.boot.SpringApplication;
4import org.springframework.boot.autoconfigure.SpringBootApplication;
5import org.springframework.context.annotation.ComponentScan;
6
7import tk.mybatis.spring.annotation.MapperScan;
8
9@SpringBootApplication
10@ComponentScan(basePackages= {"com.cxl"})
11@MapperScan(basePackages= {"com.cxl.mapper"})
12public class CxlLongdadaNettyApplication {
13
14 public static void main(String[] args) {
15 SpringApplication.run(CxlLongdadaNettyApplication.class, args);
16 }
17
18}
19
20
21
22 |
5.netty启动类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| 1package com.cxl;
2
3import org.springframework.context.ApplicationListener;
4import org.springframework.context.event.ContextRefreshedEvent;
5import org.springframework.stereotype.Component;
6
7import com.cxl.netty.WSServer;
8
9@Component
10public class NettyBooter implements ApplicationListener<ContextRefreshedEvent>{
11
12 @Override
13 public void onApplicationEvent(ContextRefreshedEvent event) {
14 if(event.getApplicationContext().getParent() == null) {
15 try {
16 WSServer.getInstance().start();
17 } catch (Exception e) {
18 e.printStackTrace();
19 }
20 }
21 }
22
23}
24
25
26 |
6.netty配置类
WSServer.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| 1package com.cxl.netty;
2
3import org.springframework.stereotype.Component;
4
5import io.netty.bootstrap.ServerBootstrap;
6import io.netty.channel.ChannelFuture;
7import io.netty.channel.EventLoopGroup;
8import io.netty.channel.nio.NioEventLoopGroup;
9import io.netty.channel.socket.nio.NioServerSocketChannel;
10
11@Component
12public class WSServer {
13
14 //单例
15 private static class SingletionWSServer{
16 static final WSServer INSTANCE = new WSServer();
17 }
18
19 public static WSServer getInstance() {
20 return SingletionWSServer.INSTANCE;
21 }
22
23 private EventLoopGroup mainGroup;
24 private EventLoopGroup subGroup;
25 private ServerBootstrap serverBootstrap;
26 private ChannelFuture channelFuture;
27
28 public WSServer() {
29 mainGroup = new NioEventLoopGroup();
30 subGroup = new NioEventLoopGroup();
31 serverBootstrap = new ServerBootstrap();
32 serverBootstrap.group(mainGroup,subGroup)
33 .channel(NioServerSocketChannel.class)
34 .childHandler(new WSServerInitialzer());
35 }
36
37 //开启服务器
38 public void start() {
39 this.channelFuture = serverBootstrap.bind(8077);
40 System.err.println("netty websocket server run successfully!!!");
41 }
42
43
44}
45
46
47 |
ChatHandler.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| 1package com.cxl.netty;
2
3import java.time.LocalDateTime;
4
5import io.netty.channel.Channel;
6import io.netty.channel.ChannelHandlerContext;
7import io.netty.channel.SimpleChannelInboundHandler;
8import io.netty.channel.group.ChannelGroup;
9import io.netty.channel.group.DefaultChannelGroup;
10import io.netty.channel.local.LocalChannel;
11import io.netty.handler.codec.http.HttpObject;
12import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
13import io.netty.util.concurrent.GlobalEventExecutor;
14
15/**
16 * 处理消息的handler
17 * @author mingliang
18 *TextWebSocketFrame websocket专门处理文本的对象 ,frame是载体
19 */
20public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame>{
21
22 //管理所有客户端的channel
23 private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
24
25
26 @Override
27 protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
28 String content = msg.text(); // 获取客户端传过来的消息内容
29 System.out.println("msg : "+content);
30
31 for (Channel channel : clients) {
32 channel.writeAndFlush(
33 new TextWebSocketFrame
34 ("[服务器在:]"+LocalDateTime.now()+
35 ",接收到消息为:"+content));
36 }
37
38 //以下写法和for循环一致
39// clients.writeAndFlush(new TextWebSocketFrame
40// ("[服务器在:]"+LocalDateTime.now()+
41// ",接收到消息为:"+content));
42 }
43
44 //用户进入
45 @Override
46 public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
47 clients.add(ctx.channel());
48 System.out.println("添加cid" + ctx.channel().id());clients.add(ctx.channel());
49 }
50
51 //用户离开
52 @Override
53 public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
54 clients.remove(ctx.channel());
55 System.out.println("移除cid" + ctx.channel().id());
56 System.out.println("移除长id" + ctx.channel().id().asLongText());
57 System.out.println("移除短id" + ctx.channel().id().asShortText());
58 }
59
60
61
62}
63
64
65 |
WSServerInitialzer.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| 1package com.cxl.netty;
2
3import io.netty.channel.ChannelInitializer;
4import io.netty.channel.ChannelPipeline;
5import io.netty.channel.socket.SocketChannel;
6import io.netty.handler.codec.http.HttpObjectAggregator;
7import io.netty.handler.codec.http.HttpServerCodec;
8import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
9import io.netty.handler.stream.ChunkedWriteHandler;
10
11public class WSServerInitialzer extends ChannelInitializer<SocketChannel>{
12
13 @Override
14 protected void initChannel(SocketChannel channel) throws Exception {
15 ChannelPipeline pipeline = channel.pipeline();
16
17 //编解码器
18 pipeline.addLast(new HttpServerCodec());
19 //对大数据流处理
20 pipeline.addLast(new ChunkedWriteHandler());
21 // 对httpmessage进行聚合,聚合成fullhttprequest或fullhttpresponse
22 // 几乎在netty中的编程都会使用到此hanler
23 pipeline.addLast(new HttpObjectAggregator(1024*64));
24
25 //===================以上是用于支持http协议===================
26
27 //websocket服务器处理的协议,用于指定给客户端连接访问的路由
28 pipeline.addLast(
29 new WebSocketServerProtocolHandler("/ws"));
30
31 //自定义拦截器
32 pipeline.addLast(new ChatHandler());
33
34
35
36
37
38
39 }
40
41}
42
43
44 |