package com.iot.home.gatewaymgmt.tcp.client.socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iot.home.gatewaymgmt.common.constant.ConstantCode;
import com.iot.home.gatewaymgmt.common.enums.HomeBusinessCodeEnum;
import com.iot.home.gatewaymgmt.common.utils.EncryptionUtil;
import com.iot.home.gatewaymgmt.tcp.client.TCPClientProxy;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Data;
@Component
@Data
public class TantronSocketClient {
private static final Logger logger = LoggerFactory.getLogger(TantronSocketClient.class);
@Autowired
private TCPClientProxy tcpClientProxy;
public Socket socket = null;
public OutputStream os = null;
public InputStream is = null;
@PostConstruct
public void start() {
logger.info("tantron socket client 正在启动...");
new TantronSocketClient().new SocketThread("119.23.27.49",9000,"TTGSZWHDDEBUG02",tcpClientProxy).start();
}
@PreDestroy
public void stop() {
logger.info("tantron socket client 正在关闭...");
try {
socket.close();
is.close();
os.close();
} catch (Exception e) {
logger.info("tantron socket client关闭完成...");
}
}
public void writeTantron(String msg) {
try {
os.write(msg.getBytes());
os.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 发送心跳包
*/
public void sendHeartbeat() {
try {
String heartbeat = "hd";
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
timer(heartbeat);
// Thread.sleep(10 * 1000);// 10s发送一次心跳
// os.write(heartbeat.getBytes());
// os.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
} catch (Exception e) {
e.printStackTrace();
}
}
private class SocketThread extends Thread {
private String ip;
private int port;
private String serial;
private TCPClientProxy tcpClientProxy;
public SocketThread(String ip, int port, String serial,TCPClientProxy tcpClientProxy) {
super();
this.ip = ip;
this.port = port;
this.serial = serial;
}
@Override
public void run() {
// long startTime = System.currentTimeMillis();
// sendHeartbeat();
while (true) {
try {
if (socket == null || socket.isClosed()) {
logger.warn("tantron socket reconnection...");
socket = new Socket(ip, port); // 连接socket
os = socket.getOutputStream();
os.write(serial.getBytes());
os.flush();
}
Thread.sleep(100);
is = socket.getInputStream();
int size = is.available();
if (size <= 0) {
// if ((System.currentTimeMillis() - startTime) > 3 * 10 * 1000) { //
// 如果超过30秒没有收到服务器发回来的信息,说明socket连接可能已经被远程服务器关闭
// socket.close(); // 这时候可以关闭socket连接
// startTime = System.currentTimeMillis();
// }
continue;
// } else {
// startTime = System.currentTimeMillis();
}
byte[] resp = new byte[size];
is.read(resp);
String response = new String(resp, "utf-8");
logger.info("tantron socket server response:{}", response);
if (!"WEB_ACCEPT".equals(response)) {
tantronSync(tcpClientProxy,response);
}
} catch (Exception e) {
e.printStackTrace();
try {
socket.close();
is.close();
os.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}
/**
*
* { "Gate_SERIAL":"TTGSZWHDDEBUG02","Gate_STATUS": { "id": "0","action": "connect","value":"offline" } }
* #{"Gate_STATUS": { "id": "4","action": "wind","value":”3” },“Gate_SERIAL”:"TTGSZWHDDEBUG01"}#
*/
private void tantronSync(TCPClientProxy tcpClientProxy,String tantronReponse) {
logger.info("synctantron device status....");
long now = System.currentTimeMillis();
JSONArray list = new JSONArray();
String[] resSplit = tantronReponse.split("#");
int j=1;
if(resSplit.length==1) {
j=0;
}
for (int i = j; i < resSplit.length; i++) {
JSONObject tantronResJSON = JSONObject.parseObject(resSplit[i]);
JSONObject gateStatus = tantronResJSON.getJSONObject("Gate_STATUS");
String gateSerial = tantronResJSON.getString("Gate_SERIAL");
String id = gateStatus.getString("id");
String action = gateStatus.getString("action");
String value = gateStatus.getString("value");
JSONObject att = new JSONObject();
att.put(action, value);
JSONObject device = new JSONObject();
device.put("bussiness_name", HomeBusinessCodeEnum.TANTRON.getType());
device.put("device_sn", EncryptionUtil.getMD5(gateSerial + id, false, 16));
device.put("status_modified_at", now);
device.put("updated_at", now);
device.put("attribute", att);
list.add(device);
}
JSONObject deviceStatus = new JSONObject();
deviceStatus.put("method", "dr_thr_report_dev_status");
deviceStatus.put("timestamp", now);
deviceStatus.put("msg_tag", "tantron_uploaddevicestatus_" + now);
deviceStatus.put("req_id", ConstantCode.SUCCESS_CODE);
JSONObject paramsJS = new JSONObject();
paramsJS.put("list", list);
deviceStatus.put("params", paramsJS);
logger.info("write device status params:{}", deviceStatus);
try {
if (tcpClientProxy.isChannelAvailable()) {
ByteBuf respBuf = Unpooled.copiedBuffer((deviceStatus.toJSONString() + "\r\n").getBytes());
tcpClientProxy.getChannel().writeAndFlush(respBuf);
} else {
throw new Exception("channel has not initialized yet!");
}
} catch (Exception e) {
logger.error("tcpclient send socket failed:" + e);
}
}
/**
* 定时器
*/
public void timer(String heartbeat) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
os.write(heartbeat.getBytes());
os.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}, 10000);
}
}