👍 init
This commit is contained in:
+40
@@ -0,0 +1,40 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
logs
|
||||
.idea
|
||||
@@ -0,0 +1,72 @@
|
||||
<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.zsw</groupId>
|
||||
<artifactId>netty01</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>netty01</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.63.Final</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>2.7.10</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>31.1-jre</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
<version>1.18.28</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.16</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.9.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.zsw;
|
||||
|
||||
import com.zsw.starter.Client;
|
||||
import com.zsw.starter.Server;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Hello world!
|
||||
*
|
||||
*/
|
||||
@Slf4j
|
||||
public class App
|
||||
{
|
||||
public static void main( String[] args )
|
||||
{
|
||||
log.info("hello,world. {}",1);
|
||||
System.out.println( "Hello World!" );
|
||||
Server server = new Server();
|
||||
server.run();
|
||||
|
||||
Client client = new Client();
|
||||
client.run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.zsw.starter;
|
||||
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import com.zsw.starter.handler.ClientHandler;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.codec.json.JsonObjectDecoder;
|
||||
import io.netty.handler.codec.string.StringEncoder;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
public class Client {
|
||||
|
||||
private void start(int i) throws InterruptedException {
|
||||
NioEventLoopGroup group = new NioEventLoopGroup();
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(group)
|
||||
.channel(NioSocketChannel.class)
|
||||
.option(ChannelOption.TCP_NODELAY, true)
|
||||
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
|
||||
.handler(new ChannelInitializer<SocketChannel>() {
|
||||
protected void initChannel(SocketChannel ch) {
|
||||
// 注册名称
|
||||
ch.pipeline().addLast("idleStateHandler", new IdleStateHandler(60, 60, 60, TimeUnit.SECONDS));
|
||||
ch.pipeline().addLast(new JsonObjectDecoder());
|
||||
ch.pipeline().addLast(new StringEncoder());
|
||||
ch.pipeline().addLast(new ClientHandler(i));
|
||||
}
|
||||
});
|
||||
ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 8899);
|
||||
channelFuture.sync();
|
||||
channelFuture.channel().closeFuture().sync();
|
||||
}
|
||||
|
||||
public void run(){
|
||||
for (int i = 0; i < 10; i++) {
|
||||
// try {
|
||||
// Thread.sleep(200);
|
||||
// } catch (InterruptedException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
int finalI = i;
|
||||
ThreadUtil.execAsync(()->{
|
||||
log.info("client:{} ready", finalI);
|
||||
try {
|
||||
this.start(finalI);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.zsw.starter;
|
||||
|
||||
import com.zsw.starter.handler.ServerHandler;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioChannelOption;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.handler.codec.json.JsonObjectDecoder;
|
||||
import io.netty.handler.codec.string.StringEncoder;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
public class Server {
|
||||
|
||||
private void start() throws InterruptedException {
|
||||
NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
|
||||
//new 一个工作线程组
|
||||
NioEventLoopGroup workGroup = new NioEventLoopGroup(200);
|
||||
ServerBootstrap bootstrap = new ServerBootstrap()
|
||||
.group(bossGroup, workGroup)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(SocketChannel socketChannel) throws Exception {
|
||||
ChannelPipeline pipline = socketChannel.pipeline();
|
||||
pipline.addLast("heart",new IdleStateHandler(5,5,10, TimeUnit.SECONDS));
|
||||
// pipline.addFirst(new JsonObjectDecoder());
|
||||
pipline.addLast(new StringEncoder());
|
||||
pipline.addLast(new ServerHandler());
|
||||
}
|
||||
})
|
||||
.localAddress(8899)
|
||||
.option(ChannelOption.SO_BACKLOG, 1024)
|
||||
.childOption(NioChannelOption.SO_KEEPALIVE, true);
|
||||
ChannelFuture future = bootstrap.bind().sync();
|
||||
log.info("打印服务启动,端口:{} ",8899);
|
||||
}
|
||||
|
||||
public void run(){
|
||||
try {
|
||||
this.start();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.zsw.starter.handler;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
|
||||
@Slf4j
|
||||
public class ClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
|
||||
int i ;
|
||||
public ClientHandler(int i) {
|
||||
this.i = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
|
||||
String channelId = channelHandlerContext.channel().id().toString();
|
||||
byte[] bytes = new byte[byteBuf.readableBytes()];
|
||||
byteBuf.getBytes(byteBuf.readerIndex(), bytes);
|
||||
String info = new String(bytes, StandardCharsets.UTF_8);
|
||||
log.info("info:{}",info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
super.channelActive(ctx);
|
||||
log.info("客户端连接:{}",ctx.channel().id());
|
||||
ctx.writeAndFlush("ctx-"+i);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.zsw.starter.handler;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelId;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import lombok.Synchronized;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
|
||||
@Slf4j
|
||||
public class ServerHandler extends SimpleChannelInboundHandler<ByteBuf> {
|
||||
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
|
||||
|
||||
String channelId = channelHandlerContext.channel().id().toString();
|
||||
byte[] bytes = new byte[byteBuf.readableBytes()];
|
||||
byteBuf.getBytes(byteBuf.readerIndex(), bytes);
|
||||
String info = new String(bytes, StandardCharsets.UTF_8);
|
||||
log.info("channelHandlerContext:{}",channelHandlerContext.channel().id());
|
||||
test(channelHandlerContext.channel().id());
|
||||
|
||||
// Thread.sleep(5000L);
|
||||
Socket socket = new Socket("192.168.10.188", 9100);
|
||||
OutputStream socketOut = socket.getOutputStream();
|
||||
OutputStreamWriter writer = new OutputStreamWriter(socketOut, "GBK");
|
||||
socketOut.write(27);
|
||||
socketOut.write(27);
|
||||
String str = StrUtil.format("ctx:{},text:{}\n",channelHandlerContext.channel().id(),info);
|
||||
writer.write(str);
|
||||
writer.flush();
|
||||
|
||||
writer.write(27);
|
||||
writer.write(100);
|
||||
writer.write(4);
|
||||
writer.write(10);
|
||||
writer.flush();
|
||||
|
||||
writer.write(0x1D);
|
||||
writer.write("V");
|
||||
writer.write(48);
|
||||
writer.write(0);
|
||||
writer.flush();
|
||||
|
||||
log.info("停止5秒后完成");
|
||||
socket.close();
|
||||
writer.close();
|
||||
socketOut.close();
|
||||
}
|
||||
|
||||
|
||||
private synchronized void test(ChannelId id){
|
||||
log.info("测试同步开始...{}",id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration debug="false" scan="false">
|
||||
<property name="log.path" value="logs"/>
|
||||
|
||||
<!-- <!– 彩色日志格式 –>-->
|
||||
<!-- <property name="CONSOLE_LOG_PATTERN"-->
|
||||
<!-- value="%clr([${spring.application.name}:${server.port}:%X{tenant}:%X{userid}]) %clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>-->
|
||||
|
||||
<!-- <!– 普通日志格式 –>-->
|
||||
<!-- <property name="CONSOLE_LOG_PATTERN_NO_COLOR"-->
|
||||
<!-- value="[${spring.application.name}:${server.port}:%X{tenant}:%X{userid}] %d{yyyy-MM-dd HH:mm:ss.SSS}[%5p] ${PID} [%X{trace}] [%t:%r] [%logger{50}.%M:%L] %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />-->
|
||||
|
||||
<property name="CONSOLE_LOG_PATTERN"
|
||||
value=" %clr(%d{yyyy-MM-dd HH:mm:ss:SSS}) %clr(){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
|
||||
|
||||
<!-- 普通日志格式 -->
|
||||
<property name="CONSOLE_LOG_PATTERN_NO_COLOR"
|
||||
value=" %d{yyyy-MM-dd HH:mm:ss}[%5p] [%X{trace}] [%t:%r] [%logger{50}.%M:%L] %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />
|
||||
|
||||
|
||||
<!-- 彩色日志依赖的渲染类 -->
|
||||
<conversionRule conversionWord="clr"
|
||||
converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
|
||||
<conversionRule conversionWord="wex"
|
||||
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
|
||||
<conversionRule conversionWord="wEx"
|
||||
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
|
||||
<!-- <conversionRule conversionWord="traceId" converterClass="com.zsw.pos.common.converter.ZswLogPrefixConverter"/>-->
|
||||
|
||||
<!-- Console log output -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Log file info output -->
|
||||
<appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/info.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${log.path}/%d{yyyy-MM, aux}/info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
|
||||
<maxFileSize>50MB</maxFileSize>
|
||||
<maxHistory>30</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${CONSOLE_LOG_PATTERN_NO_COLOR}</pattern>
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Log file error output -->
|
||||
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/error.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
|
||||
<maxFileSize>50MB</maxFileSize>
|
||||
<maxHistory>30</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${CONSOLE_LOG_PATTERN_NO_COLOR}</pattern>
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>ERROR</level>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
|
||||
<root level="INFO">
|
||||
<appender-ref ref="console"/>
|
||||
<appender-ref ref="error"/>
|
||||
<appender-ref ref="info"/>
|
||||
</root>
|
||||
|
||||
<!-- 服务日志 -->
|
||||
<logger name="root" level="info" />
|
||||
|
||||
|
||||
</configuration>
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.zsw;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* Unit test for simple App.
|
||||
*/
|
||||
public class AppTest
|
||||
extends TestCase
|
||||
{
|
||||
/**
|
||||
* Create the test case
|
||||
*
|
||||
* @param testName name of the test case
|
||||
*/
|
||||
public AppTest( String testName )
|
||||
{
|
||||
super( testName );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the suite of tests being tested
|
||||
*/
|
||||
public static Test suite()
|
||||
{
|
||||
return new TestSuite( AppTest.class );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rigourous Test :-)
|
||||
*/
|
||||
public void testApp()
|
||||
{
|
||||
assertTrue( true );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user