# Conflicts:
#	ktg-admin/pom.xml
#	pom.xml
This commit is contained in:
yinjinlu-pc\尹金路 2024-11-24 19:21:50 +08:00
commit 4d6d6192db
20 changed files with 16787 additions and 4339 deletions

View File

@ -73,11 +73,6 @@
<artifactId>ktg-print</artifactId>
</dependency>
<!-- IOT模块-->
<dependency>
<groupId>com.ktg</groupId>
<artifactId>ktg-iot</artifactId>
</dependency>
</dependencies>
@ -98,17 +93,17 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
</project>
</project>

View File

@ -20,7 +20,7 @@ import com.ktg.framework.security.handle.LogoutSuccessHandlerImpl;
/**
* spring security配置
*
*
* @author ruoyi
*/
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@ -31,7 +31,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
*/
@Autowired
private UserDetailsService userDetailsService;
/**
* 认证失败处理类
*/
@ -49,13 +49,13 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
*/
@Autowired
private JwtAuthenticationTokenFilter authenticationTokenFilter;
/**
* 跨域过滤器
*/
@Autowired
private CorsFilter corsFilter;
/**
* 解决 无法直接注入 AuthenticationManager
*
@ -115,6 +115,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
.antMatchers("/*/api-docs").anonymous()
.antMatchers("/druid/**").anonymous()
.antMatchers("/websocket/**").anonymous()
.antMatchers("/barcodePrint/printing/**").anonymous()
.antMatchers("/system/autocode/get/**").permitAll()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated()

View File

@ -37,5 +37,9 @@
<groupId>com.ktg</groupId>
<artifactId>ktg-common</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
</project>

View File

@ -0,0 +1,249 @@
package com.ktg.print.controller;
import com.ktg.common.constant.UserConstants;
import com.ktg.common.core.domain.AjaxResult;
import com.ktg.common.utils.StringUtils;
import com.ktg.print.domain.PrintBarcodeModel;
import com.ktg.print.domain.PrintPrinterConfig;
import com.ktg.print.protocol.PrintMessageProto;
import com.ktg.print.server.PrintClientInfoMessageHandler;
import com.ktg.print.server.PrintServerDefaultHandler;
import com.ktg.print.service.IPrintPrinterConfigService;
import io.netty.channel.Channel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.net.SocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author yanshikui
*/
@RestController
@RequestMapping("/barcodePrint")
public class PrintController {
@Autowired
private IPrintPrinterConfigService printPrinterConfigService;
/**
* 条码打印公共接口
* @param printBarcodeModel
* @return
*/
@PostMapping("/printing")
public AjaxResult printBarcodeLabel(@RequestBody PrintBarcodeModel printBarcodeModel) {
String printCode = printBarcodeModel.getPrintCode();
String printTemplate = printBarcodeModel.getPrintTemplate();
Map<String,String> params = printBarcodeModel.getParams();
PrintPrinterConfig printPrinterConfig = printPrinterConfigService.selectPrintPrinterConfigByPrinterId(Long.parseLong(printCode));
String ip = printPrinterConfig.getPrinterIp();
String printPort = printPrinterConfig.getPrinterPort().toString();
String printName = printPrinterConfig.getPrinterName();
PrintMessageProto.Printer.DataType dataType = PrintMessageProto.Printer.DataType.IQC_PrintMessage;
if (printPrinterConfig == null) {
return AjaxResult.error("打印机:" + printCode + "不存在");
}
//根据打印机编码id获取打印机你信息
String clientIp = printPrinterConfig.getClientIp();
if (StringUtils.isEmpty(clientIp)) {
return AjaxResult.error("请检查打印机客户端信息配置!");
}
PrintMessageProto.Printer msg = null;
PrintMessageProto.Printer.PrintInfo printInfo = PrintMessageProto.Printer.PrintInfo.newBuilder().setIp(ip).setCode(printCode).setName(printName).setPort(printPort).build();
switch (printTemplate) {
case UserConstants.BARCODE_TYPE_ITEM:
//物料标签打印
//封装模板数据
String materialCode = params.get("materialCode");
String materialName = params.get("materialName");
String specificationAndModel = params.get("specificationAndModel");
String param = params.get("param");
dataType = PrintMessageProto.Printer.DataType.Material_Products;
PrintMessageProto.Printer.MaterialProducts materialProducts = PrintMessageProto.Printer.MaterialProducts.newBuilder().setMaterialCode(materialCode).setMaterialName(materialName).setSpecificationAndModel(specificationAndModel).setParam(param).build();
// 构造对应的消息对象
msg = PrintMessageProto.Printer.newBuilder().setMaterialProducts(materialProducts).setDataType(dataType).setPrintInfo(printInfo).build();
break;
case UserConstants.BARCODE_TYPE_PACKAGE:
// String materialCode = params.get("materialCode");
// String materialName = params.get("materialName");
// String specificationAndModel = params.get("specificationAndModel");
// String param = params.get("param");
// PrintMessageProto.Printer.DataType dataType = PrintMessageProto.Printer.DataType.Material_Products;
// PrintMessageProto.Printer.MaterialProducts materialProducts = PrintMessageProto.Printer.MaterialProducts.newBuilder().setMaterialCode(materialCode).setMaterialName(materialName).setSpecificationAndModel(specificationAndModel).setParam(param).build();
// // 构造对应的消息对象
// msg = PrintMessageProto.Printer.newBuilder().setMaterialProducts(materialProducts).setDataType(dataType).setPrintInfo(printInfo).build();
// break;
case UserConstants.BARCODE_TYPE_STOCK:
//仓库标签打印
//封装模板数据
// String warehouseCode = params.get("warehouseCode");
// String warehouseName = params.get("warehouseName");
// String personInCharge = params.get("personInCharge");
// dataType = PrintMessageProto.Printer.DataType.Warehouse_;
// PrintMessageProto.Printer.Warehouse warehouse = PrintMessageProto.Printer.Warehouse.newBuilder().setWarehouseCode(warehouseCode).setWarehouseName(warehouseName).setPersonInCharge(personInCharge).build();
// // 构造对应的消息对象
// msg = PrintMessageProto.Printer.newBuilder().setWarehouse(warehouse).setDataType(dataType).setPrintInfo(printInfo).build();
// break;
case UserConstants.BARCODE_TYPE_MACHINERY:
//设备标签打印
//封装模板数据
String equipmentCode = params.get("equipmentCode");
String equipmentName = params.get("equipmentName");
String specificationAndModel_1 = params.get("specificationAndModel");
String param1 = params.get("param");
dataType = PrintMessageProto.Printer.DataType.Equipment_;
PrintMessageProto.Printer.Equipment equipment = PrintMessageProto.Printer.Equipment.newBuilder().setEquipmentCode(equipmentCode).setEquipmentName(equipmentName).setSpecificationAndModel(specificationAndModel_1).setParam(param1).build();
// 构造对应的消息对象
msg = PrintMessageProto.Printer.newBuilder().setEquipment(equipment).setDataType(dataType).setPrintInfo(printInfo).build();
break;
case UserConstants.BARCODE_TYPE_WORKSTATION:
//工作站标签打印
//封装模板数据
String workstationCode = params.get("workstationCode");
String workstationName = params.get("workstationName");
String belongingProcess = params.get("belongingProcess");
String param2 = params.get("param");
dataType = PrintMessageProto.Printer.DataType.Workstation_;
PrintMessageProto.Printer.Workstation workstation = PrintMessageProto.Printer.Workstation.newBuilder().setWorkstationCode(workstationCode).setWorkstationName(workstationName).setBelongingProcess(belongingProcess).setParam(param2).build();
// 构造对应的消息对象
msg = PrintMessageProto.Printer.newBuilder().setWorkstation(workstation).setDataType(dataType).setPrintInfo(printInfo).build();
break;
case UserConstants.BARCODE_TYPE_WAREHOUSE:
// 仓库标签打印
//封装模板数据
String warehouseCode = params.get("warehouseCode");
String warehouseName = params.get("warehouseName");
String personInCharge = params.get("personInCharge");
String param3 = params.get("param");
dataType = PrintMessageProto.Printer.DataType.Warehouse_;
PrintMessageProto.Printer.Warehouse warehouse = PrintMessageProto.Printer.Warehouse.newBuilder().setWarehouseCode(warehouseCode).setWarehouseName(warehouseName).setPersonInCharge(personInCharge).setParam(param3).build();
// 构造对应的消息对象
msg = PrintMessageProto.Printer.newBuilder().setWarehouse(warehouse).setDataType(dataType).setPrintInfo(printInfo).build();
break;
case UserConstants.BARCODE_TYPE_STORAGELOCATION:
// 库区标签打印
//封装模板数据
String warehouseLocationCode = params.get("warehouseLocationCode");
String warehouseLocationName = params.get("warehouseLocationName");
String position = params.get("position");
String param4 = params.get("param");
dataType = PrintMessageProto.Printer.DataType.Warehouse_Location;
PrintMessageProto.Printer.WarehouseLocation location = PrintMessageProto.Printer.WarehouseLocation.newBuilder().setWarehouseLocationCode(warehouseLocationCode).setWarehouseLocationName(warehouseLocationName).setPosition(position).setParam(param4).build();
// 构造对应的消息对象
msg = PrintMessageProto.Printer.newBuilder().setWarehouseLocation(location).setDataType(dataType).setPrintInfo(printInfo).build();
break;
case UserConstants.BARCODE_TYPE_STORAGEAREA:
// 库位标签打印
//封装模板数据
String warehouseAreaCode = params.get("warehouseAreaCode");
String warehouseAreaName = params.get("warehouseAreaName");
dataType = PrintMessageProto.Printer.DataType.Warehouse_Area;
String param5 = params.get("param");
PrintMessageProto.Printer.WarehouseArea warehouseArea = PrintMessageProto.Printer.WarehouseArea.newBuilder().setWarehouseAreaCode(warehouseAreaCode).setWarehouseAreaName(warehouseAreaName).setParam(param5).build();
// 构造对应的消息对象
msg = PrintMessageProto.Printer.newBuilder().setWarehouseArea(warehouseArea).setDataType(dataType).setPrintInfo(printInfo).build();
break;
case UserConstants.BARCODE_TYPE_TRANSORDER:
// 流转单标签打印
//封装模板数据
//String sampleCode =params.get("sampleCode");
//String qcObject =params.get("qcObject");
//String sampleTime =params.get("sampleTime");
//String batchCode =params.get("batchCode");
//PrintMessageProt//o.Printer.IQCPrintMessage iQCPrintMessage = PrintMessageProto.Printer.IQCPrintMessage.newBuilder().setSampleCode(sampleCode).setQcObject(qcObject).setSampleTime(sampleTime).setBatchCode(batchCode).build();
// 构造对应的消息对象
// msg = PrintMessageProto.Printer.newBuilder().setIqcPrintMessage(iQCPrintMessage).setDataType(dataType).setPrintInfo(printClientInfoMessage).build();
break;
case UserConstants.BARCODE_TYPE_CLIENT:
// 客户标签打印
//封装模板数据
//String sampleCode =params.get("sampleCode");
//String qcObject =params.get("qcObject");
//String sampleTime =params.get("sampleTime");
//String batchCode =params.get("batchCode");
//PrintMessageProt//o.Printer.IQCPrintMessage iQCPrintMessage = PrintMessageProto.Printer.IQCPrintMessage.newBuilder().setSampleCode(sampleCode).setQcObject(qcObject).setSampleTime(sampleTime).setBatchCode(batchCode).build();
// 构造对应的消息对象
// msg = PrintMessageProto.Printer.newBuilder().setIqcPrintMessage(iQCPrintMessage).setDataType(dataType).setPrintInfo(printClientInfoMessage).build();
break;
case UserConstants.BARCODE_TYPE_VENDOR:
// 供应商标签打印
//封装模板数据
//String sampleCode =params.get("sampleCode");
//String qcObject =params.get("qcObject");
//String sampleTime =params.get("sampleTime");
//String batchCode =params.get("batchCode");
//PrintMessageProt//o.Printer.IQCPrintMessage iQCPrintMessage = PrintMessageProto.Printer.IQCPrintMessage.newBuilder().setSampleCode(sampleCode).setQcObject(qcObject).setSampleTime(sampleTime).setBatchCode(batchCode).build();
// 构造对应的消息对象
// msg = PrintMessageProto.Printer.newBuilder().setIqcPrintMessage(iQCPrintMessage).setDataType(dataType).setPrintInfo(printClientInfoMessage).build();
break;
case UserConstants.BARCODE_TYPE_WORKSHOP:
// 工作站标签打印
//封装模板数据
//String sampleCode =params.get("sampleCode");
//String qcObject =params.get("qcObject");
//String sampleTime =params.get("sampleTime");
//String batchCode =params.get("batchCode");
//PrintMessageProt//o.Printer.IQCPrintMessage iQCPrintMessage = PrintMessageProto.Printer.IQCPrintMessage.newBuilder().setSampleCode(sampleCode).setQcObject(qcObject).setSampleTime(sampleTime).setBatchCode(batchCode).build();
// 构造对应的消息对象
// msg = PrintMessageProto.Printer.newBuilder().setIqcPrintMessage(iQCPrintMessage).setDataType(dataType).setPrintInfo(printClientInfoMessage).build();
break;
case UserConstants.BARCODE_TYPE_WORKORDER:
// 生产工单标签打印
//封装模板数据
//String sampleCode =params.get("sampleCode");
//String qcObject =params.get("qcObject");
//String sampleTime =params.get("sampleTime");
//String batchCode =params.get("batchCode");
//PrintMessageProt//o.Printer.IQCPrintMessage iQCPrintMessage = PrintMessageProto.Printer.IQCPrintMessage.newBuilder().setSampleCode(sampleCode).setQcObject(qcObject).setSampleTime(sampleTime).setBatchCode(batchCode).build();
// 构造对应的消息对象
// msg = PrintMessageProto.Printer.newBuilder().setIqcPrintMessage(iQCPrintMessage).setDataType(dataType).setPrintInfo(printClientInfoMessage).build();
break;
case UserConstants.BARCODE_TYPE_TOOL:
// 工装夹具标签打印
//封装模板数据
//String sampleCode =params.get("sampleCode");
//String qcObject =params.get("qcObject");
//String sampleTime =params.get("sampleTime");
//String batchCode =params.get("batchCode");
//PrintMessageProt//o.Printer.IQCPrintMessage iQCPrintMessage = PrintMessageProto.Printer.IQCPrintMessage.newBuilder().setSampleCode(sampleCode).setQcObject(qcObject).setSampleTime(sampleTime).setBatchCode(batchCode).build();
// 构造对应的消息对象
// msg = PrintMessageProto.Printer.newBuilder().setIqcPrintMessage(iQCPrintMessage).setDataType(dataType).setPrintInfo(printClientInfoMessage).build();
break;
case UserConstants.BARCODE_TYPE_SN:
// SN标签打印
//封装模板数据
//String sampleCode =params.get("sampleCode");
//String qcObject =params.get("qcObject");
//String sampleTime =params.get("sampleTime");
//String batchCode =params.get("batchCode");
//PrintMessageProt//o.Printer.IQCPrintMessage iQCPrintMessage = PrintMessageProto.Printer.IQCPrintMessage.newBuilder().setSampleCode(sampleCode).setQcObject(qcObject).setSampleTime(sampleTime).setBatchCode(batchCode).build();
// 构造对应的消息对象
// msg = PrintMessageProto.Printer.newBuilder().setIqcPrintMessage(iQCPrintMessage).setDataType(dataType).setPrintInfo(printClientInfoMessage).build();
break;
default:
// 默认执行代码块
//封装模板数据
//String sampleCode =params.get("sampleCode");
//String qcObject =params.get("qcObject");
//String sampleTime =params.get("sampleTime");
//String batchCode =params.get("batchCode");
//PrintMessageProt//o.Printer.IQCPrintMessage iQCPrintMessage = PrintMessageProto.Printer.IQCPrintMessage.newBuilder().setSampleCode(sampleCode).setQcObject(qcObject).setSampleTime(sampleTime).setBatchCode(batchCode).build();
// 构造对应的消息对象
// msg = PrintMessageProto.Printer.newBuilder().setIqcPrintMessage(iQCPrintMessage).setDataType(dataType).setPrintInfo(printClientInfoMessage).build();
// break;
}
// 获取信道数据并发送消息对象给指定打印机客户端
//打印机名称和打印机客户端地址映射 一对一关系
ConcurrentHashMap<String, SocketAddress> socketAddress = PrintClientInfoMessageHandler.socketAddressMap;
//根据客户端和通道信息
ConcurrentHashMap<SocketAddress, Channel> channels = PrintServerDefaultHandler.chanelMap;
Channel channel = channels.get(socketAddress.get(clientIp));
channel.writeAndFlush(msg);
return AjaxResult.success("打印成功");
}
}

View File

@ -0,0 +1,12 @@
package com.ktg.print.domain;
import lombok.Data;
import java.util.Map;
@Data
public class PrintBarcodeModel {
private Map<String, String> params;
private String printCode;
private String printTemplate;
}

View File

@ -1,35 +0,0 @@
package com.ktg.print.printserver;
import com.ktg.print.protocol.PrintMessageProto;
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.util.concurrent.GlobalEventExecutor;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class PrintClientInfoMessageHandler extends SimpleChannelInboundHandler<PrintMessageProto.PrintClientInfoMessage> {
//接收到客户端发送的客户端信息后才会保存client信息
private Map<String, Channel> clients = new ConcurrentHashMap<>();
private ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, PrintMessageProto.PrintClientInfoMessage clientInfoMessag) throws Exception {
if(!clients.containsKey(clientInfoMessag.getSid())){
clients.put(clientInfoMessag.getSid(),channelHandlerContext.channel());
}
channelHandlerContext.fireChannelRead(clientInfoMessag);
group.add(channelHandlerContext.channel());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
group.remove(ctx.channel());
}
}

View File

@ -1,30 +0,0 @@
package com.ktg.print.printserver;
import com.ktg.print.protocol.PrintMessageProto;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class PrintServerChannelInitializer extends ChannelInitializer {
@Autowired
private PrintServerDefaultHandler serverDefaultHandler;
@Autowired
private PrintClientInfoMessageHandler printClientInfoMessageHandler;
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new ProtobufVarint32FrameDecoder());
ch.pipeline().addLast(new ProtobufDecoder(PrintMessageProto.PrintClientInfoMessage.getDefaultInstance()));
ch.pipeline().addLast(new ProtobufEncoder());
ch.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());
ch.pipeline().addLast(printClientInfoMessageHandler);
ch.pipeline().addLast(serverDefaultHandler);
}
}

View File

@ -1,18 +0,0 @@
package com.ktg.print.printserver;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class PrintServerCloseListener implements DisposableBean {
@Resource
private PrinterServer printerServer;
@Override
public void destroy() throws Exception {
printerServer.stop();
}
}

View File

@ -1,70 +0,0 @@
package com.ktg.print.printserver;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.CharsetUtil;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component
@ChannelHandler.Sharable
public class PrintServerDefaultHandler extends ChannelInboundHandlerAdapter {
private static final Logger logger = LoggerFactory.getLogger("PrinterServerHandler");
/**
* 客户端连接建立
* @param ctx
* @throws Exception
*/
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
logger.info("打印机客户端已连接!");
}
/**
* 客户端连接移除
* @param ctx
* @throws Exception
*/
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
logger.info("打印机客户端已断开!");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg){
try{
ByteBuf data = (ByteBuf) msg;
logger.info("msg recived:"+data.toString(CharsetUtil.UTF_8));
String replyMessage = "Server reply: " + data.toString(CharsetUtil.UTF_8)+"\n";
ByteBuf replyByteBuf = ctx.alloc().buffer();
replyByteBuf.writeBytes(replyMessage.getBytes());
ctx.writeAndFlush(replyByteBuf);
}catch (Exception e){
logger.error(e.getMessage());
}
}
/**
* 异常发生关闭通道移除客户端
* @param ctx
* @param cause
* @throws Exception
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.channel().close();
}
}

View File

@ -1,20 +0,0 @@
package com.ktg.print.printserver;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class PrintServerOpenListener implements ApplicationRunner {
@Resource
private PrinterServer printerServer;
@Override
public void run(ApplicationArguments args) throws Exception {
printerServer.start();
}
}

View File

@ -1,67 +0,0 @@
package com.ktg.print.printserver;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
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.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 基于netty的socket服务器端与标签打印机的客户端建立长连接实现网络远程打印
*/
@Component
public class PrinterServer {
@Autowired
private PrintServerChannelInitializer printServerChannelInitializer;
@Value("${netty.server.port}")
private int port;
@Value("${netty.server.threadcount}")
private int bossThreadCount;
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
private Channel serverChannel;
PrinterServer(){
bossGroup = new NioEventLoopGroup();
workerGroup = new NioEventLoopGroup();
}
public void start(){
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(printServerChannelInitializer);
ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
serverChannel = channelFuture.channel();
serverChannel.closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public void stop(){
if(serverChannel !=null){
serverChannel.close();
serverChannel = null;
}
}
}

View File

@ -1,36 +0,0 @@
syntax = "proto3";
package com.ktg.print.protocol;
option java_package = "com.ktg.print.protocol";
option java_outer_classname = "PrintMessageProto";
message IQCPrintMessage {
string sampleCode = 1;
string qcObject = 2;
string sampleTime = 3;
string batchCode = 4;
}
message PQCPrintMessage {
string sampleCode = 1;
string qcObject = 2;
string sampleTime = 3;
string sampleLocation = 4;
}
message OQCPrintMessage {
string sampleCode = 1;
string qcObject = 2;
string sampleTime = 3;
string batchCode = 4;
string packageType = 5;
}
//
message PrintClientInfoMessage {
string ip = 1;
string location = 2;
string sid = 3;
}

View File

@ -0,0 +1,124 @@
syntax = "proto3";
package com.ktg.print.protocol;
option java_package = "com.ktg.print.protocol";
option java_outer_classname = "PrintMessageProto";
message Printer{
enum DataType{
IQC_PrintMessage = 0;//proto3枚举enum编号从0开始
PQC_PrintMessage = 1;
OQC_PrintMessage = 2;
Print_ClientInfoMessage = 3;
Printing_OfCirculation = 4;
Material_Products = 5;
Warehouse_=6;
Warehouse_Location=7;
Warehouse_Area=8;
Equipment_=9;
Workstation_=10;
}
//data_type来识别哪个枚举类型(DataType是People的第一个属性data_type)
DataType data_type = 1;
PrintInfo printInfo = 14;
//
oneof dataBody{
IQCPrintMessage iqcPrintMessage = 2;
PQCPrintMessage pqcPrintMessage = 3;
OQCPrintMessage oqPrintMessage = 4;
PrintClientInfoMessage printClientInfoMessage = 5;
PrintingOfCirculation printingOfCirculation = 6;
MaterialProducts materialProducts = 7;
Warehouse warehouse = 8;
WarehouseLocation warehouseLocation = 9;
WarehouseArea warehouseArea = 10;
Equipment equipment = 11;
Workstation workstation = 12;
}
message IQCPrintMessage {
string sampleCode = 1;
string qcObject = 2;
string sampleTime = 3;
string batchCode = 4;
}
message PQCPrintMessage {
string sampleCode = 1;
string qcObject = 2;
string sampleTime = 3;
string sampleLocation = 4;
}
message OQCPrintMessage {
string sampleCode = 1;
string qcObject = 2;
string sampleTime = 3;
string batchCode = 4;
string packageType = 5;
}
//
message PrintClientInfoMessage {
string ip = 1;
string location = 2;
string sid = 3;
}
message PrintingOfCirculation{
string workOrderNumber = 1;
string materialCode = 2;
string materialName = 3;
string specificationAndModel = 4;
string processingProcedure = 5;
string param = 6;
}
message MaterialProducts{
string materialCode = 1;
string materialName = 2;
string specificationAndModel = 3;
string param = 4;
}
message Warehouse{
string warehouseCode = 1;
string warehouseName = 2;
string personInCharge = 3;
string param = 4;
}
message WarehouseLocation{
string warehouseLocationCode = 1;
string warehouseLocationName = 2;
string position = 3;
string param = 4;
}
message WarehouseArea{
string warehouseAreaCode = 1;
string warehouseAreaName = 2;
string param = 3;
}
message Equipment{
string equipmentCode = 1;
string equipmentName = 2;
string specificationAndModel = 3;
string param = 4;
}
message Workstation{
string workstationCode = 1;
string workstationName = 2;
string belongingProcess = 3;
string param = 4;
}
//
message PrintInfo {
string ip = 1;
string code = 2;
string name = 3;
string port = 4;
}
}

View File

@ -0,0 +1,80 @@
package com.ktg.print.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class R<T> implements Serializable {
/**
* 成功失败标识
*/
private boolean flag;
/**
* 响应数据
*/
private T data;
/**
* 状态码
*/
private Integer code;
/**
* 响应消息
*/
private String message;
public static Integer SUCCESS_200 = 200;
public static Integer FAIL_500 = 500;
public static <T> R<T> success() {
return R.success(null);
}
public static <T> R<T> success(T result) {
R<T> systemResult = new R<>();
systemResult.setFlag(true);
systemResult.setData(result);
systemResult.setMessage("成功");
systemResult.setCode(SUCCESS_200);
return systemResult;
}
public static <T> R<T> success(String msg) {
R<T> systemResult = new R<>();
systemResult.setFlag(true);
systemResult.setMessage(msg);
return systemResult;
}
public static <T> R<T> fail(T result) {
R<T> systemResult = new R<>();
systemResult.setFlag(false);
systemResult.setCode(FAIL_500);
systemResult.setData(result);
return systemResult;
}
public static <T> R<T> fail(String msg) {
R<T> systemResult = new R<>();
systemResult.setFlag(false);
systemResult.setCode(FAIL_500);
systemResult.setMessage(msg);
return systemResult;
}
public static <T> R<T> fail(T result, String msg) {
R<T> systemResult = new R<>();
systemResult.setFlag(false);
systemResult.setCode(FAIL_500);
systemResult.setMessage(msg);
systemResult.setData(result);
return systemResult;
}
}

View File

@ -0,0 +1,19 @@
package com.ktg.print.server;
import com.ktg.print.protocol.PrintMessageProto;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import java.net.SocketAddress;
import java.util.concurrent.ConcurrentHashMap;
public class PrintClientInfoMessageHandler extends SimpleChannelInboundHandler<PrintMessageProto.Printer> {
public static ConcurrentHashMap<String, SocketAddress> socketAddressMap = new ConcurrentHashMap<>();
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, PrintMessageProto.Printer printClientInfoMessage) throws Exception {
//打印机名称和打印机客户端地址映射 一对一关系
socketAddressMap.put(printClientInfoMessage.getPrintClientInfoMessage().getLocation(), channelHandlerContext.channel().remoteAddress());
}
}

View File

@ -0,0 +1,81 @@
package com.ktg.print.server;
import com.ktg.print.protocol.PrintMessageProto;
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.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Component
public class PrintServer implements DisposableBean {
EventLoopGroup bossGroup = null;
EventLoopGroup workerGroup = null;
int port = 9016;
@PostConstruct
public void nettyServerInit() {
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(new service());
}
@Override
public void destroy() throws Exception {
if (bossGroup!=null) {
bossGroup.shutdownGracefully();
}
if (workerGroup!=null) {
workerGroup.shutdownGracefully();
}
}
public class service implements Runnable {
@Override
public void run() {
bossGroup = new NioEventLoopGroup(1);
workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new ProtobufVarint32FrameDecoder());
ch.pipeline().addLast(new ProtobufDecoder(PrintMessageProto.Printer.getDefaultInstance()));
ch.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());
ch.pipeline().addLast(new ProtobufEncoder());
ch.pipeline().addLast(new PrintClientInfoMessageHandler());
ch.pipeline().addLast(new PrintServerDefaultHandler());
}
});
ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
System.out.println("==========Netty服务端启动成功========");
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
if (bossGroup!=null) {
bossGroup.shutdownGracefully();
}
if (workerGroup!=null) {
workerGroup.shutdownGracefully();
}
}
}
}
}

View File

@ -0,0 +1,27 @@
package com.ktg.print.server;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.net.SocketAddress;
import java.util.concurrent.ConcurrentHashMap;
public class PrintServerDefaultHandler extends ChannelInboundHandlerAdapter {
public static ConcurrentHashMap<SocketAddress, Channel> chanelMap = new ConcurrentHashMap<>();
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
//客户端和通道映射 也是一对一关系
chanelMap.put(ctx.channel().remoteAddress(), ctx.channel());
System.out.println("客户端连接已建立:" + ctx.channel().remoteAddress());
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
chanelMap.remove(ctx.channel().remoteAddress());
System.out.println("客户端连接已关闭:" + ctx.channel().remoteAddress());
}
}

View File

@ -0,0 +1,21 @@
//package com.ktg.print.server;
//
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.ApplicationArguments;
//import org.springframework.boot.ApplicationRunner;
//import org.springframework.stereotype.Component;
//
//import javax.annotation.Resource;
//
//@Component
//public class PrintServerOpenListener implements ApplicationRunner {
//
// @Autowired
// private PrintServer printerServer;
//
// @Override
// public void run(ApplicationArguments args) throws Exception {
// printerServer.start();
// }
//
//}

16
pom.xml
View File

@ -3,7 +3,7 @@
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.ktg</groupId>
<artifactId>ktg</artifactId>
<version>3.8.2</version>
@ -11,7 +11,7 @@
<name>ktg</name>
<url>http://www.029tec.com</url>
<description>MES生产执行管理系统</description>
<properties>
<ktg.version>3.8.2</ktg.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -34,7 +34,7 @@
<velocity.version>1.7</velocity.version>
<jwt.version>0.9.1</jwt.version>
</properties>
<!-- 依赖声明 -->
<dependencyManagement>
<dependencies>
@ -219,13 +219,6 @@
<version>${ktg.version}</version>
</dependency>
<!-- IOT模块 -->
<dependency>
<groupId>com.ktg</groupId>
<artifactId>ktg-iot</artifactId>
<version>${ktg.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
@ -238,7 +231,6 @@
<module>ktg-common</module>
<module>ktg-mes</module>
<module>ktg-print</module>
<module>ktg-iot</module>
</modules>
<packaging>pom</packaging>
@ -287,4 +279,4 @@
</pluginRepository>
</pluginRepositories>
</project>
</project>