package com.northglass.listener;
|
|
import java.io.DataInputStream;
|
import java.io.DataOutputStream;
|
import java.io.IOException;
|
import java.net.ServerSocket;
|
import java.net.Socket;
|
import java.text.SimpleDateFormat;
|
import java.util.Date;
|
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.slf4j.MDC;
|
import org.springframework.context.ApplicationContext;
|
|
import com.northglass.constants.StateConstants.ConnectState;
|
import com.northglass.constants.StateConstants.GaoliweiFunctionNumber;
|
import com.northglass.entity.GaoliweiMachine;
|
import com.northglass.service.gaoliwei.GaoliweiMachineService;
|
import com.northglass.util.CRCUtil;
|
import com.northglass.util.HexUtil;
|
import com.northglass.web.gaoliwei.GaoliweiController;
|
|
public class GaoliweiMachineServerListener extends AbstractServerListener implements Runnable {
|
|
private static final Logger LOGGER = LoggerFactory.getLogger(GaoliweiMachineServerListener.class);
|
|
private GaoliweiMachine gaoliweiMachine;
|
private GaoliweiMachineService service;
|
|
/**
|
* 备用,共8个字节
|
*/
|
protected static final String BACKUP = "0000000000000000";
|
|
/**
|
* 加密方式00,表示不加密
|
*/
|
protected static final String NO_ENCRYPT = "00";
|
|
public String button = "0";
|
public String button1 = "0";
|
|
public String getButton() {
|
return button;
|
}
|
|
public void setButton(String button) {
|
this.button = button;
|
}
|
|
public String getButton1() {
|
return button1;
|
}
|
|
public void setButton1(String button1) {
|
this.button1 = button1;
|
}
|
|
|
private StringBuffer MESSAGE_BUFFER = new StringBuffer();
|
|
public GaoliweiMachineServerListener(Long gaoliweiMachineId) {
|
ApplicationContext context = initializeSpringContext();
|
service = context.getBean(GaoliweiMachineService.class);
|
this.gaoliweiMachine = service.getById(gaoliweiMachineId);
|
|
MDC.put("logFileName", "GaoliweiMachine_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()));
|
}
|
|
/**
|
* 启动服务器监听连接,等待客户端连接
|
*
|
* @throws IOException
|
*/
|
private void connect(ServerSocket serverSocket) throws IOException {
|
if (serverSocket.isClosed()) {
|
return;
|
}
|
LOGGER.debug(gaoliweiMachine.getConnectState());
|
Socket socket = serverSocket.accept();
|
LOGGER.debug("客户端已连接,客户端IP:" + socket.getInetAddress());
|
service.setConnectState(gaoliweiMachine, ConnectState.CONNECTED);
|
gaoliweiMachine.getServerConnection().setSocket(socket);
|
|
//添加连接时间
|
service.getendtime("gaoliweiMachine"+gaoliweiMachine.getNumber());
|
}
|
|
/**
|
* 服务器监听消息循环,先从客户端接收消息,再向客户端发送消息
|
*
|
* @throws IOException
|
*/
|
private void listen() throws IOException {
|
Socket socket = gaoliweiMachine.getServerConnection().getSocket();
|
LOGGER.debug(gaoliweiMachine.getConnectState());
|
socket.setSoTimeout(10000);
|
while (true) {
|
DataInputStream in = new DataInputStream(socket.getInputStream());
|
byte b = in.readByte();
|
MESSAGE_BUFFER.append(HexUtil.byteToHexString(b));
|
|
if (!existMessage()) {
|
continue;
|
}
|
String message = getNextMessage();
|
// machineService.saveMessage(MessageType.CLIENT, message, socket.getInetAddress().getHostAddress(), socket.getLocalPort());
|
|
String returnMessage="";
|
try{
|
returnMessage = service.generateReturnMessage(message, gaoliweiMachine);
|
}catch(ThreadDeath se){
|
LOGGER.debug("磨边机【"+gaoliweiMachine.getNumber()+"】线程出现死锁!");
|
gaoliweiMachine.setState("线程死锁");
|
}
|
// String returnMessage = service.generateReturnMessage(message, gaoliweiMachine);
|
|
if (returnMessage.equals("connect")) {
|
in.close();
|
socket.close();
|
ServerSocket serverSocket = null;
|
try {
|
serverSocket = new ServerSocket(gaoliweiMachine.getPort());
|
LOGGER.debug("高力威【" + gaoliweiMachine.getNumber() + "】启动监听,等待客户端连接,端口:" + gaoliweiMachine.getPort());
|
gaoliweiMachine.getServerConnection().setServerSocket(serverSocket);
|
|
connect(serverSocket);
|
|
// 一直循环,若连接断开,则在Exception处理环节重新连接,并继续监听消息
|
while (!Thread.currentThread().isInterrupted()) {
|
try {
|
listen();
|
}
|
catch (IOException se) {
|
service.getright("gaoliweiMachine"+gaoliweiMachine.getNumber());
|
LOGGER.debug("高力威连接已断开!");
|
se.printStackTrace();
|
LOGGER.debug("高力威等待重新连接……");
|
service.setConnectState(gaoliweiMachine, ConnectState.CONNECTING);
|
connect(serverSocket);
|
}
|
}
|
}
|
catch (IOException e) {
|
e.printStackTrace();
|
}
|
}else if (returnMessage != null && !"".equals(returnMessage) && !returnMessage.equals("connect")) {
|
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
|
out.write(HexUtil.stringToInt(returnMessage));
|
out.flush();
|
}else if (GaoliweiController.getButton().equals("1") && gaoliweiMachine.getId()==1L) {
|
LOGGER.debug("MES连线系统主动完成任务1!");
|
returnMessage = getFinishId();
|
GaoliweiController.setButton("0");
|
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
|
out.write(HexUtil.stringToInt(returnMessage));
|
out.flush();
|
}else if (GaoliweiController.getButton1().equals("1") && gaoliweiMachine.getId()==2L) {
|
LOGGER.debug("MES连线系统主动完成任务2!");
|
returnMessage = getFinishId();
|
GaoliweiController.setButton1("0");
|
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
|
out.write(HexUtil.stringToInt(returnMessage));
|
out.flush();
|
}
|
|
|
|
// DataInputStream in = new DataInputStream(socket.getInputStream());
|
// bufSize = in.read(msg);
|
// String message = HexUtil.byteToHexString(bufSize, msg);
|
//
|
// String returnMessage = service.generateReturnMessage(message, identifyMachine);
|
//
|
// // 客户端会一直向服务器发数据
|
// if(returnMessage!=null){
|
// DataOutputStream out = new DataOutputStream(socket.getOutputStream());
|
// out.write(HexUtil.stringToInt(returnMessage));
|
// out.flush();
|
// }
|
}
|
}
|
|
private boolean existMessage() {
|
|
// 若缓冲区长度小于消息最小长度,则缓冲区中的消息无效。
|
if (MESSAGE_BUFFER.length() < 84) {
|
return false;
|
}
|
|
String head = MESSAGE_BUFFER.substring(0, 10);
|
LOGGER.trace("head: " + head);
|
|
// 若缓冲区不以HEAD为起始,则删掉字符;
|
// 一个字符一个字符删是避免一次删多导致消息损坏。
|
if (!head.equalsIgnoreCase(HEAD)) {
|
MESSAGE_BUFFER.delete(0, 2);
|
return false;
|
}
|
|
// 获取消息长度
|
String messageLengthHex = MESSAGE_BUFFER.substring(MESSAGE_LENGTH_START, MESSAGE_LENGTH_END + 1);
|
int messageLength = HexUtil.hexToInt(messageLengthHex);
|
LOGGER.trace("messageLength: " + messageLength);
|
|
if (MESSAGE_BUFFER.length() < DATA_START + messageLength*2) {
|
return false;
|
}
|
|
String dataAndEnd = MESSAGE_BUFFER.substring(DATA_START, DATA_START + messageLength*2);
|
String end = dataAndEnd.substring(dataAndEnd.length() - 10, dataAndEnd.length());
|
LOGGER.trace("end: " + end);
|
|
if (head.equals(HEAD) && end.equals(END)) {
|
return true;
|
}
|
|
return false;
|
}
|
|
private String getNextMessage() {
|
// 获取消息长度
|
String messageLengthHex = MESSAGE_BUFFER.substring(MESSAGE_LENGTH_START, MESSAGE_LENGTH_END + 1);
|
int messageLength = HexUtil.hexToInt(messageLengthHex);
|
LOGGER.trace("messageLength: " + messageLength);
|
|
String message = MESSAGE_BUFFER.substring(0, DATA_START + messageLength*2);
|
MESSAGE_BUFFER.delete(0, DATA_START + messageLength*2);
|
|
// int messageEnd = MESSAGE_BUFFER.indexOf("3c454f463e");
|
// String message = "";
|
//
|
// if (messageEnd >= 0) {
|
// message = MESSAGE_BUFFER.substring(0, messageEnd + 10);
|
// MESSAGE_BUFFER = MESSAGE_BUFFER.delete(0, messageEnd + 10);
|
// }
|
|
return message;
|
}
|
|
|
@Override
|
public void run() {
|
ServerSocket serverSocket = null;
|
|
try {
|
serverSocket = new ServerSocket(gaoliweiMachine.getPort());
|
LOGGER.debug("高力威【" + gaoliweiMachine.getNumber() + "】启动监听,等待客户端连接,端口:" + gaoliweiMachine.getPort());
|
gaoliweiMachine.getServerConnection().setServerSocket(serverSocket);
|
|
connect(serverSocket);
|
|
// 一直循环,若连接断开,则在Exception处理环节重新连接,并继续监听消息
|
while (!Thread.currentThread().isInterrupted()) {
|
try {
|
listen();
|
}
|
catch (IOException se) {
|
service.getright("gaoliweiMachine"+gaoliweiMachine.getNumber());
|
LOGGER.debug("高力威连接已断开!");
|
se.printStackTrace();
|
|
LOGGER.debug("高力威等待重新连接……");
|
service.setConnectState(gaoliweiMachine, ConnectState.CONNECTING);
|
connect(serverSocket);
|
}
|
}
|
}
|
catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
|
public String getFinishId(){
|
String data = CRCUtil.sourceCRC("011000320001020020");
|
String head = generateHead(data,GaoliweiFunctionNumber.CONFIRM_SIGN);
|
return head + data + END;
|
}
|
|
/**
|
* 构造消息头部
|
*
|
* 通信头部 = 开始标志 + 信息长度 + 订单编号 + 功能号 + 加密方式 + 发送时刻 + 备用
|
*
|
* @param data
|
* @param functionNumber
|
* @return
|
*/
|
protected String generateHead(String data, String functionNumber) {
|
// 信息长度
|
int length = (data + END).length() / 2;
|
|
String orderNumber = "000000000000000000000000";
|
|
String head = HEAD
|
+ HexUtil.intTo2ByteHex(length)
|
+ orderNumber
|
+ functionNumber
|
+ NO_ENCRYPT
|
+ HexUtil.timeToHex(new Date())
|
+ BACKUP;
|
|
return head;
|
}
|
|
}
|