diff --git a/example_output.jpg b/example_output.jpg
new file mode 100644
index 0000000..b56b519
Binary files /dev/null and b/example_output.jpg differ
diff --git a/file-read/src/main/java/com/wyl/file/sequence/Sequential.java b/file-read/src/main/java/com/wyl/file/sequence/Sequential.java
index 955dc1e..8dbf946 100644
--- a/file-read/src/main/java/com/wyl/file/sequence/Sequential.java
+++ b/file-read/src/main/java/com/wyl/file/sequence/Sequential.java
@@ -7,15 +7,16 @@ import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class Sequential {
- public static int fileWrite(String filePath, String content, int index) {
+ public static int fileWrite(String filePath, String content) {
File file = new File(filePath);
RandomAccessFile randomAccessTargetFile;
MappedByteBuffer map;
try {
randomAccessTargetFile = new RandomAccessFile(file, "rw");
FileChannel targetFileChannel = randomAccessTargetFile.getChannel();
- map = targetFileChannel.map(FileChannel.MapMode.READ_WRITE, 0, (long) 1024 * 1024 * 1024);
- map.position(index);
+ byte[] bytes = content.getBytes();
+ map = targetFileChannel.map(FileChannel.MapMode.READ_WRITE, 0, bytes.length);
+ map.position(0);
map.put(content.getBytes());
return map.position();
}
diff --git a/file-read/src/test/java/com/wyl/file/FileTest.java b/file-read/src/test/java/com/wyl/file/FileTest.java
index d5c653d..653b097 100644
--- a/file-read/src/test/java/com/wyl/file/FileTest.java
+++ b/file-read/src/test/java/com/wyl/file/FileTest.java
@@ -16,18 +16,17 @@ public class FileTest {
public void SequentialWriteFile() {
Integer index = 0;
-
File file = new File("./wyl.log");
MappedByteBuffer map;
try (RandomAccessFile randomAccessTargetFile = new RandomAccessFile(file, "rw")) {
FileChannel targetFileChannel = randomAccessTargetFile.getChannel();
- map = targetFileChannel.map(FileChannel.MapMode.READ_WRITE, pos.get(), (long) 1024 * 1024 * 1024);
- if (map.isLoaded()) {
-
+ map = targetFileChannel.map(FileChannel.MapMode.READ_WRITE, pos.get(), 2);
+ while (index<2)
+ {
+ map.position(index);
+ map.put("1".getBytes());
+ index = map.position();
}
- map.position(index);
- map.put("123\n".getBytes());
- final int position = map.position();
}
catch (Exception e) {
e.printStackTrace();
diff --git a/javacv/pom.xml b/javacv/pom.xml
new file mode 100644
index 0000000..c60922d
--- /dev/null
+++ b/javacv/pom.xml
@@ -0,0 +1,26 @@
+
+
+
+ JavaBasiceDemo
+ com.wyl.example
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ javacv
+
+
+ 8
+ 8
+
+
+
+
+ org.bytedeco
+ javacv-platform
+ 1.5.8
+
+
+
\ No newline at end of file
diff --git a/javacv/src/main/java/com/wyl/javacv/ImageToVideoExample.java b/javacv/src/main/java/com/wyl/javacv/ImageToVideoExample.java
new file mode 100644
index 0000000..af1eb61
--- /dev/null
+++ b/javacv/src/main/java/com/wyl/javacv/ImageToVideoExample.java
@@ -0,0 +1,52 @@
+package com.wyl.javacv;
+
+import org.opencv.core.Mat;
+import org.opencv.core.Size;
+import org.opencv.videoio.VideoWriter;
+
+import java.io.File;
+
+import static org.opencv.imgcodecs.Imgcodecs.imread;
+
+public class ImageToVideoExample {
+
+ public static void main(String[] args) {
+ // 图像文件夹路径
+ String imageFolderPath = "/Users/wyl/project/java/wyl/JavaBasiceDemo/javacv/src/main/resources/";
+
+ // 获取图像文件列表
+ File[] imageFiles = new File(imageFolderPath).listFiles();
+
+ // 设置视频编码器参数
+ int fourcc = VideoWriter.fourcc('X', 'V', 'I', 'D'); // 使用XVID编码器
+ double fps = 24; // 视频帧率
+ Mat image = imread(imageFiles[0].getAbsolutePath());
+ Size frameSize = new Size(image.cols(), image.rows()); // 视频帧尺寸
+
+ // 创建视频写入器
+ VideoWriter writer = new VideoWriter("/Users/wyl/project/java/wyl/JavaBasiceDemo/javacv/src/main/resources/output.avi", fourcc, fps, frameSize, true);
+
+ // 逐个读取图像并写入视频
+ for (File imageFile : imageFiles) {
+ // 加载图像
+ image = imread(imageFile.getAbsolutePath());
+
+ // 检查图像是否加载成功
+ if (image.empty()) {
+ System.out.println("无法加载图像:" + imageFile.getName());
+ System.exit(1);
+ }
+
+ // 写入视频
+ writer.write(image);
+
+ // 释放内存
+ image.release();
+ }
+
+ // 释放视频写入器
+ writer.release();
+
+ System.out.println("视频合成完成!");
+ }
+}
diff --git a/javacv/src/main/java/com/wyl/javacv/JavaCVExample.java b/javacv/src/main/java/com/wyl/javacv/JavaCVExample.java
new file mode 100644
index 0000000..59b0e34
--- /dev/null
+++ b/javacv/src/main/java/com/wyl/javacv/JavaCVExample.java
@@ -0,0 +1,33 @@
+package com.wyl.javacv;
+
+
+import org.bytedeco.opencv.opencv_core.Mat;
+
+import static org.bytedeco.opencv.global.opencv_highgui.imshow;
+import static org.bytedeco.opencv.global.opencv_highgui.waitKey;
+import static org.bytedeco.opencv.global.opencv_imgcodecs.imread;
+import static org.bytedeco.opencv.global.opencv_imgcodecs.imwrite;
+
+public class JavaCVExample {
+
+ public static void main(String[] args) {
+ // 加载图像
+ Mat image = imread("/Users/wyl/project/java/wyl/JavaBasiceDemo/javacv/src/main/resources/OIP.jpg");
+
+ // 检查图像是否加载成功
+ if (image.empty()) {
+ System.out.println("无法加载图像");
+ System.exit(1);
+ }
+
+ // 显示图像
+// imshow("图像窗口", image);
+// waitKey(0);
+
+ // 保存图像
+ imwrite("/Users/wyl/project/java/wyl/JavaBasiceDemo/javacv/src/main/resources/example_output.jpg", image);
+
+ // 释放内存
+ image.release();
+ }
+}
diff --git a/javacv/src/main/resources/OIP.jpg b/javacv/src/main/resources/OIP.jpg
new file mode 100644
index 0000000..a1957b4
Binary files /dev/null and b/javacv/src/main/resources/OIP.jpg differ
diff --git a/javacv/src/main/resources/R.jpeg b/javacv/src/main/resources/R.jpeg
new file mode 100644
index 0000000..4d785a5
Binary files /dev/null and b/javacv/src/main/resources/R.jpeg differ
diff --git a/javacv/src/main/resources/example_output.jpg b/javacv/src/main/resources/example_output.jpg
new file mode 100644
index 0000000..b56b519
Binary files /dev/null and b/javacv/src/main/resources/example_output.jpg differ
diff --git a/kafka/src/test/java/com/wyl/kafka/test/ConsumerTest.java b/kafka/src/test/java/com/wyl/kafka/test/ConsumerTest.java
index 8fc9450..6af4df2 100644
--- a/kafka/src/test/java/com/wyl/kafka/test/ConsumerTest.java
+++ b/kafka/src/test/java/com/wyl/kafka/test/ConsumerTest.java
@@ -6,9 +6,20 @@ import com.wyl.kafka.producers.KafkaProducerExample;
import com.wyl.kafka.producers.KafkaProducerSend;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.Consumer;
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.apache.kafka.clients.consumer.ConsumerRecords;
+import org.apache.kafka.clients.consumer.KafkaConsumer;
+import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
+import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
+import java.io.*;
+import java.util.Arrays;
+import java.util.Properties;
+
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+
@Slf4j
public class ConsumerTest {
final static String TOPIC_NAME = "wyl-filebeat-test";
@@ -85,4 +96,35 @@ public class ConsumerTest {
KafkaConsumerPoll.PollMessageSeekEnd(consumer, TOPIC_NAME, 1);
}
+
+ @Test
+ public void imageSave() throws IOException {
+
+ // 创建 Kafka 消费者配置
+ Properties consumerProps = new Properties();
+ consumerProps.put("bootstrap.servers", "localhost:9092");
+ consumerProps.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
+ consumerProps.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
+ consumerProps.put("group.id","test");
+ consumerProps.put("max.request.size", "2097152");
+ // 创建 Kafka 生产者和消费者
+ KafkaConsumer consumer = new KafkaConsumer<>(consumerProps);
+
+ // 接收图片消息从 Kafka
+ consumer.subscribe(Arrays.asList("wyl-events"));
+ while (true) {
+ ConsumerRecords records = consumer.poll(100);
+ for (ConsumerRecord record : records) {
+ byte[] imageBytes = record.value().getBytes(ISO_8859_1);
+ // 将图片字节数组保存到文件中
+ // 这里假设图片文件名为 received-image.jpg
+ File receivedFile = new File("/Users/wyl/Desktop/wyl01.png");
+ FileOutputStream fileOutputStream = new FileOutputStream(receivedFile);
+ fileOutputStream.write(imageBytes);
+ fileOutputStream.close();
+ System.out.println(11);
+ }
+ }
+ }
+
}
diff --git a/kafka/src/test/java/com/wyl/kafka/test/ProducerTest.java b/kafka/src/test/java/com/wyl/kafka/test/ProducerTest.java
index 5afaf25..a51a7e7 100644
--- a/kafka/src/test/java/com/wyl/kafka/test/ProducerTest.java
+++ b/kafka/src/test/java/com/wyl/kafka/test/ProducerTest.java
@@ -2,10 +2,20 @@ package com.wyl.kafka.test;
import com.wyl.kafka.producers.KafkaProducerExample;
import com.wyl.kafka.producers.KafkaProducerSend;
+import jdk.jfr.internal.tool.Main;
import lombok.extern.slf4j.Slf4j;
+import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
+import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
+import java.io.*;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.Properties;
+
@Slf4j
public class ProducerTest {
final static String TOPIC_NAME = "wyl-filebeat-test";
@@ -21,4 +31,73 @@ public class ProducerTest {
final Producer stringStringProducer = KafkaProducerExample.KafkaProducerTransactional();
KafkaProducerSend.sendMessageTransactional(stringStringProducer, TOPIC_NAME, "test123");
}
+
+ @Test
+ public void imageSend() throws IOException, InterruptedException {
+
+ // 创建 Kafka 生产者配置
+ Properties producerProps = new Properties();
+ producerProps.put("bootstrap.servers", "localhost:9092");
+ producerProps.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
+ producerProps.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
+ producerProps.put("max.request.size", "2097152");
+
+ // 创建 Kafka 生产者和消费者
+ KafkaProducer producer = new KafkaProducer<>(producerProps);
+
+ // 发送图片消息到 Kafka
+ File file = new File("/Users/wyl/Desktop/wyl.png");
+ InputStream inputStream = new FileInputStream(file);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ byte[] imageData = outputStream.toByteArray();
+ String s = new String(imageData,StandardCharsets.ISO_8859_1);
+ ProducerRecord record = new ProducerRecord<>("wyl-events", s);
+ producer.send(record,(m,e)->{
+ if(Objects.nonNull(e))
+ {
+ e.printStackTrace();
+ }
+ System.out.println(m);
+
+ });
+ Thread.sleep(100000);
+ }
+
+ public static void main(String[] args) throws IOException {
+ byte[] byteArray = { -119, 66, 67 };
+ String str = new String(byteArray,StandardCharsets.ISO_8859_1);
+ System.out.println(str);
+ byte[] bytes = str.getBytes(StandardCharsets.ISO_8859_1);
+ System.out.println(bytes);
+ }
+
+ public static void main1(String[] args) throws IOException {
+ File file = new File("/Users/wyl/Desktop/wyl.png");
+ InputStream inputStream = new FileInputStream(file);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ byte[] imageData = outputStream.toByteArray();
+ String s = new String(imageData);
+ }
+
+ public static void main2(String[] args) {
+ byte[] byteArray = { -119, 66, 67 };
+ Charset[] charsets = { StandardCharsets.UTF_8, Charset.forName("ISO-8859-1"), Charset.forName("GBK") };
+ for (Charset charset : charsets) {
+ String str = new String(byteArray, charset);
+ System.out.println(charset.name() + ": " + str);
+ byte[] newByteArray = str.getBytes(charset);
+ System.out.println(charset.name() + ": " + Arrays.toString(newByteArray));
+ }
+
+ }
}
diff --git a/mqtt/pom.xml b/mqtt/pom.xml
new file mode 100644
index 0000000..ccae63b
--- /dev/null
+++ b/mqtt/pom.xml
@@ -0,0 +1,27 @@
+
+
+
+ JavaBasiceDemo
+ com.wyl.example
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ mqtt
+
+
+ 8
+ 8
+
+
+
+
+ org.eclipse.paho
+ org.eclipse.paho.client.mqttv3
+ 1.2.5
+
+
+
+
\ No newline at end of file
diff --git a/mqtt/src/main/java/com/wyl/mqtt/ClientMQTT.java b/mqtt/src/main/java/com/wyl/mqtt/ClientMQTT.java
new file mode 100644
index 0000000..914fa29
--- /dev/null
+++ b/mqtt/src/main/java/com/wyl/mqtt/ClientMQTT.java
@@ -0,0 +1,108 @@
+package com.wyl.mqtt;
+
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.paho.client.mqttv3.*;
+import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
+
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+public class ClientMQTT {
+ MqttClient client;
+ MqttConnectOptions options;
+
+ public ClientMQTT() {
+ try {
+ // host为主机名,clientid即连接MQTT的客户端ID,一般以唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存
+ client = new MqttClient("tcp://127.0.0.1:61613", "wyl01", new MemoryPersistence());
+ // MQTT的连接设置
+ options = new MqttConnectOptions();
+ // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接
+ options.setCleanSession(true);
+ // 设置连接的用户名
+ options.setUserName("admin");
+ // 设置连接的密码
+ options.setPassword("password".toCharArray());
+ // 设置超时时间 单位为秒
+ options.setConnectionTimeout(10);
+ // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
+ options.setKeepAliveInterval(20);
+ //设置自动连接
+ options.setAutomaticReconnect(true);
+ // 设置回调
+ client.setCallback(new MqttCallbackExtended() {
+ //连接成功回调,需要重新订阅主题
+ @Override
+ public void connectComplete(boolean reconnect, String serverURI) {
+ sendNotify(true);
+ subscribe();
+ }
+
+ @Override
+ public void connectionLost(Throwable cause) {
+ retryConnection(3);
+ }
+
+ @Override
+ public void deliveryComplete(IMqttDeliveryToken token) {
+ token.isComplete();
+ }
+
+ @Override
+ public void messageArrived(String topic, MqttMessage message) {
+ }
+ });
+ client.connect(options);
+ subscribe();
+ } catch (Exception e) {
+ log.error("mqtt异常" + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ private void subscribe() {
+ try {
+ //订阅队列
+ client.subscribe("wyl001", 2, (topic, message) -> {
+ String msg = new String(message.getPayload(), StandardCharsets.UTF_8);
+ log.warn("mqtt收到信息:"+msg);
+ //处理消息
+ });
+ } catch (MqttException e) {
+ log.error("mqtt异常" + e.getMessage());
+ }
+ }
+
+ private void retryConnection(int retryNumber) {
+ //当重试多次,依旧失败,就是机器故障,需要通知人工处理
+ if (retryNumber < 0) {
+ sendNotify(false);
+ }
+ try {
+ client.reconnect();
+ TimeUnit.SECONDS.sleep(30);
+ if (!client.isConnected()) {
+ retryConnection(--retryNumber);
+ }
+ } catch (MqttException | InterruptedException e) {
+ log.error("mqtt异常:"+e.getMessage());
+ }
+ }
+
+
+ //发送重试通知
+ private void sendNotify(boolean isSuccess) {
+ if (isSuccess){
+ log.debug("mqtt连接成功");
+ }else {
+ log.error("mqtt连接失败");
+ }
+ }
+
+
+ public static void main(String[] args) {
+ ClientMQTT clientMQTT = new ClientMQTT();
+ clientMQTT.subscribe();
+ }
+}
\ No newline at end of file
diff --git a/mqtt/src/main/java/com/wyl/mqtt/ClientMQTT2.java b/mqtt/src/main/java/com/wyl/mqtt/ClientMQTT2.java
new file mode 100644
index 0000000..be060a2
--- /dev/null
+++ b/mqtt/src/main/java/com/wyl/mqtt/ClientMQTT2.java
@@ -0,0 +1,111 @@
+package com.wyl.mqtt;
+
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.paho.client.mqttv3.*;
+import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
+
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+public class ClientMQTT2 {
+ MqttClient client;
+ MqttConnectOptions options;
+
+ public ClientMQTT2() {
+ try {
+ // host为主机名,clientid即连接MQTT的客户端ID,一般以唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存
+ client = new MqttClient("tcp://127.0.0.1:61613", "wyl02", new MemoryPersistence());
+ // MQTT的连接设置
+ options = new MqttConnectOptions();
+ // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接
+ options.setCleanSession(true);
+ // 设置连接的用户名
+ options.setUserName("admin");
+ // 设置连接的密码
+ options.setPassword("password".toCharArray());
+ // 设置超时时间 单位为秒
+ options.setConnectionTimeout(10);
+ // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
+ options.setKeepAliveInterval(20);
+ //设置自动连接
+ options.setAutomaticReconnect(true);
+ // 设置回调
+ client.setCallback(new MqttCallbackExtended() {
+ //连接成功回调,需要重新订阅主题
+ @Override
+ public void connectComplete(boolean reconnect, String serverURI) {
+ sendNotify(true);
+ subscribe();
+ }
+
+ @Override
+ public void connectionLost(Throwable cause) {
+ retryConnection(3);
+ }
+
+ @Override
+ public void deliveryComplete(IMqttDeliveryToken token) {
+ token.isComplete();
+ }
+
+ @Override
+ public void messageArrived(String topic, MqttMessage message) {
+ }
+ });
+ MqttTopic mqttTopic = client.getTopic("wyl");
+ //setWill方法,如果项目中需要知道客户端是否掉线可以调用该方法。设置最终端口的通知消息
+ options.setWill(mqttTopic, "close".getBytes(), 2, true);
+ client.connect(options);
+ subscribe();
+ } catch (Exception e) {
+ log.error("mqtt异常" + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ private void subscribe() {
+ try {
+ //订阅队列
+ client.subscribe("wyl", 2, (topic, message) -> {
+ String msg = new String(message.getPayload(), StandardCharsets.UTF_8);
+ log.warn("mqtt收到信息:"+msg);
+ //处理消息
+ });
+ } catch (MqttException e) {
+ log.error("mqtt异常" + e.getMessage());
+ }
+ }
+
+ private void retryConnection(int retryNumber) {
+ //当重试多次,依旧失败,就是机器故障,需要通知人工处理
+ if (retryNumber < 0) {
+ sendNotify(false);
+ }
+ try {
+ client.reconnect();
+ TimeUnit.SECONDS.sleep(30);
+ if (!client.isConnected()) {
+ retryConnection(--retryNumber);
+ }
+ } catch (MqttException | InterruptedException e) {
+ log.error("mqtt异常:"+e.getMessage());
+ }
+ }
+
+
+ //发送重试通知
+ private void sendNotify(boolean isSuccess) {
+ if (isSuccess){
+ log.debug("mqtt连接成功");
+ }else {
+ log.error("mqtt连接失败");
+ }
+ }
+
+
+ public static void main(String[] args) {
+ ClientMQTT2 clientMQTT = new ClientMQTT2();
+ clientMQTT.subscribe();
+ }
+}
\ No newline at end of file
diff --git a/mqtt/src/main/java/com/wyl/mqtt/ClientMQTT3.java b/mqtt/src/main/java/com/wyl/mqtt/ClientMQTT3.java
new file mode 100644
index 0000000..6efaef9
--- /dev/null
+++ b/mqtt/src/main/java/com/wyl/mqtt/ClientMQTT3.java
@@ -0,0 +1,111 @@
+package com.wyl.mqtt;
+
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.paho.client.mqttv3.*;
+import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
+
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+public class ClientMQTT3 {
+ MqttClient client;
+ MqttConnectOptions options;
+
+ public ClientMQTT3() {
+ try {
+ // host为主机名,clientid即连接MQTT的客户端ID,一般以唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存
+ client = new MqttClient("tcp://127.0.0.1:61613", "wyl03", new MemoryPersistence());
+ // MQTT的连接设置
+ options = new MqttConnectOptions();
+ // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接
+ options.setCleanSession(true);
+ // 设置连接的用户名
+ options.setUserName("admin");
+ // 设置连接的密码
+ options.setPassword("password".toCharArray());
+ // 设置超时时间 单位为秒
+ options.setConnectionTimeout(10);
+ // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
+ options.setKeepAliveInterval(20);
+ //设置自动连接
+ options.setAutomaticReconnect(true);
+ // 设置回调
+ client.setCallback(new MqttCallbackExtended() {
+ //连接成功回调,需要重新订阅主题
+ @Override
+ public void connectComplete(boolean reconnect, String serverURI) {
+ sendNotify(true);
+ subscribe();
+ }
+
+ @Override
+ public void connectionLost(Throwable cause) {
+ retryConnection(3);
+ }
+
+ @Override
+ public void deliveryComplete(IMqttDeliveryToken token) {
+ token.isComplete();
+ }
+
+ @Override
+ public void messageArrived(String topic, MqttMessage message) {
+ }
+ });
+ MqttTopic mqttTopic = client.getTopic("wyl");
+ //setWill方法,如果项目中需要知道客户端是否掉线可以调用该方法。设置最终端口的通知消息
+ options.setWill(mqttTopic, "close".getBytes(), 2, true);
+ client.connect(options);
+ subscribe();
+ } catch (Exception e) {
+ log.error("mqtt异常" + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ private void subscribe() {
+ try {
+ //订阅队列
+ client.subscribe("wyl", 2, (topic, message) -> {
+ String msg = new String(message.getPayload(), StandardCharsets.UTF_8);
+ log.warn("mqtt收到信息:"+msg);
+ //处理消息
+ });
+ } catch (MqttException e) {
+ log.error("mqtt异常" + e.getMessage());
+ }
+ }
+
+ private void retryConnection(int retryNumber) {
+ //当重试多次,依旧失败,就是机器故障,需要通知人工处理
+ if (retryNumber < 0) {
+ sendNotify(false);
+ }
+ try {
+ client.reconnect();
+ TimeUnit.SECONDS.sleep(30);
+ if (!client.isConnected()) {
+ retryConnection(--retryNumber);
+ }
+ } catch (MqttException | InterruptedException e) {
+ log.error("mqtt异常:"+e.getMessage());
+ }
+ }
+
+
+ //发送重试通知
+ private void sendNotify(boolean isSuccess) {
+ if (isSuccess){
+ log.debug("mqtt连接成功");
+ }else {
+ log.error("mqtt连接失败");
+ }
+ }
+
+
+ public static void main(String[] args) {
+ ClientMQTT3 clientMQTT = new ClientMQTT3();
+ clientMQTT.subscribe();
+ }
+}
\ No newline at end of file
diff --git a/mqtt/src/main/java/com/wyl/mqtt/MqttClientPublish.java b/mqtt/src/main/java/com/wyl/mqtt/MqttClientPublish.java
new file mode 100644
index 0000000..d5d5124
--- /dev/null
+++ b/mqtt/src/main/java/com/wyl/mqtt/MqttClientPublish.java
@@ -0,0 +1,95 @@
+package com.wyl.mqtt;
+
+import org.eclipse.paho.client.mqttv3.*;
+import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
+
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class MqttClientPublish {
+
+ private static AtomicInteger count = new AtomicInteger();
+ private static int qos = 1;
+ private static String clientId = "JavaClientPublish";
+ private static String broker = "tcp://127.0.0.1:1883";
+ private static String topic = "wyl01";
+ private static final Object lock = new Object();
+ public static final int THREAD_COUNT = 2;
+ private static CountDownLatch countDownLatch = new CountDownLatch(THREAD_COUNT);
+
+ public static void main(String[] args) throws Exception {
+ MqttConnectOptions connOpts = new MqttConnectOptions();
+ connOpts.setServerURIs(new String[] {broker});
+ connOpts.setMaxInflight(THREAD_COUNT * 10);
+ connOpts.setCleanSession(false);
+ connOpts.setAutomaticReconnect(true);
+ connOpts.setKeepAliveInterval(30);
+ connOpts.setUserName("wyl");
+ connOpts.setPassword("wyl".toCharArray());
+ MemoryPersistence persistence = new MemoryPersistence();
+ MqttAsyncClient client = new MqttAsyncClient(connOpts.getServerURIs()[0],clientId, persistence);
+ CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT);
+
+ client.connect(connOpts,null,new IMqttActionListener(){
+ //监听器快速返回控制非常重要,否则MQTT客户端的操作将会停止
+ @Override
+ public void onSuccess(IMqttToken asyncActionToken) {
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ new Sender(barrier, client).start();
+ }
+ }
+
+ @Override
+ public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
+ exception.printStackTrace();
+ }
+ });
+ countDownLatch.await();
+
+ System.out.println("发布完毕!");
+
+ }
+
+ private static class Sender extends Thread {
+ private CyclicBarrier barrier;
+ private MqttAsyncClient asyncClient;
+
+ public Sender(CyclicBarrier barrier, MqttAsyncClient asyncClient) {
+ this.barrier = barrier;
+ this.asyncClient = asyncClient;
+ }
+
+ @Override
+ public void run() {
+ try {
+ barrier.await();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ int index = count.incrementAndGet();
+ String content = index + "";
+ MqttMessage message = new MqttMessage();
+ message.setQos(qos);
+ message.setPayload(content.getBytes());
+ message.setId(index);
+ try {
+ asyncClient.publish(topic, message,null,new IMqttActionListener(){
+
+ @Override
+ public void onSuccess(IMqttToken asyncActionToken) {
+ countDownLatch.countDown();
+ }
+
+ @Override
+ public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
+
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/mqtt/src/main/java/com/wyl/mqtt/MqttClientV1.java b/mqtt/src/main/java/com/wyl/mqtt/MqttClientV1.java
new file mode 100644
index 0000000..0815a7a
--- /dev/null
+++ b/mqtt/src/main/java/com/wyl/mqtt/MqttClientV1.java
@@ -0,0 +1,190 @@
+package com.wyl.mqtt;
+
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
+import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
+import org.eclipse.paho.client.mqttv3.MqttTopic;
+import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
+
+@Slf4j
+public class MqttClientV1 {
+
+ public static org.eclipse.paho.client.mqttv3.MqttClient mqttClient = null;
+ private static MemoryPersistence memoryPersistence = null;
+ private static MqttConnectOptions mqttConnectOptions = null;
+
+ private static MqttClientV1 instance = null;
+
+ public static MqttClientV1 getInstance() throws Exception {
+ if (instance == null) {
+ synchronized (MqttClientV1.class) {
+ if (instance == null) {
+ instance = new MqttClientV1();
+ }
+ }
+ }
+ return instance;
+ }
+
+ public MqttClientV1(){
+ init("admin");
+ }
+
+ public void init(String clientId) {
+ //初始化连接设置对象
+ mqttConnectOptions = new MqttConnectOptions();
+ //初始化MqttClient
+ if(null != mqttConnectOptions) {
+// true可以安全地使用内存持久性作为客户端断开连接时清除的所有状态
+ mqttConnectOptions.setCleanSession(true);
+// 设置连接超时
+ mqttConnectOptions.setConnectionTimeout(30);
+ mqttConnectOptions.setUserName("admin");
+ mqttConnectOptions.setPassword("password".toCharArray());
+// 设置持久化方式
+ memoryPersistence = new MemoryPersistence();
+ if(null != memoryPersistence && null != clientId) {
+ try {
+ mqttClient = new org.eclipse.paho.client.mqttv3.MqttClient("tcp://127.0.0.1:61613", clientId,memoryPersistence);
+ } catch (MqttException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }else {
+
+ }
+ }else {
+ log.error("mqttConnectOptions对象为空");
+ }
+ //设置连接和回调
+ if(null != mqttClient) {
+ if(!mqttClient.isConnected()) {
+ try {
+ log.info("创建连接:" + mqttClient.isConnected());
+ mqttClient.connect(mqttConnectOptions);
+ } catch (MqttException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+ }else {
+ log.error("mqttClient为空");
+ }
+ }
+
+ // 关闭连接
+ public void closeConnect() {
+ //关闭存储方式
+ if(null != memoryPersistence) {
+ try {
+ memoryPersistence.close();
+ } catch (MqttPersistenceException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }else {
+ log.error("memoryPersistence is null");
+ }
+
+// 关闭连接
+ if(null != mqttClient) {
+ if(mqttClient.isConnected()) {
+ try {
+ mqttClient.disconnect();
+ mqttClient.close();
+ } catch (MqttException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }else {
+ log.error("mqttClient is not connect");
+ }
+ }else {
+ log.error("mqttClient is null");
+ }
+ }
+
+ // 发布消息
+ public void publishMessage(String pubTopic,String message,int qos) {
+ if(null != mqttClient&& mqttClient.isConnected()) {
+ MqttMessage mqttMessage = new MqttMessage();
+ mqttMessage.setQos(qos);
+ mqttMessage.setPayload(message.getBytes());
+ MqttTopic topic = mqttClient.getTopic(pubTopic);
+ if(null != topic) {
+ try {
+ MqttDeliveryToken publish = topic.publish(mqttMessage);
+ if(!publish.isComplete()) {
+ //log.info("消息发布成功");
+ }
+ } catch (MqttException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ }else {
+ reConnect();
+ }
+
+ }
+ // 重新连接
+ public void reConnect() {
+ if(null != mqttClient) {
+ if(!mqttClient.isConnected()) {
+ if(null != mqttConnectOptions) {
+ try {
+ mqttClient.connect(mqttConnectOptions);
+ } catch (MqttException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }else {
+ log.error("mqttConnectOptions is null");
+ }
+ }else {
+ log.error("mqttClient is null or connect");
+ }
+ }else {
+ init("admin");
+ }
+
+ }
+ // 订阅主题
+ public void subTopic(String topic) {
+ if(null != mqttClient&& mqttClient.isConnected()) {
+ try {
+ mqttClient.subscribe(topic, 1);
+ } catch (MqttException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }else {
+ log.error("mqttClient is error");
+ }
+ }
+
+
+ // 清空主题
+ public void cleanTopic(String topic) {
+ if(null != mqttClient&& !mqttClient.isConnected()) {
+ try {
+ mqttClient.unsubscribe(topic);
+ } catch (MqttException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }else {
+ log.error("mqttClient is error");
+ }
+ }
+
+ public static void main(String [] args){
+ MqttClientV1 mqttClient = new MqttClientV1();
+ mqttClient.publishMessage("wyl", "12312312312", 1);
+ }
+}
\ No newline at end of file
diff --git a/mqtt/src/main/java/com/wyl/mqtt/SimpleMqttClient.java b/mqtt/src/main/java/com/wyl/mqtt/SimpleMqttClient.java
new file mode 100644
index 0000000..a5d85a1
--- /dev/null
+++ b/mqtt/src/main/java/com/wyl/mqtt/SimpleMqttClient.java
@@ -0,0 +1,146 @@
+package com.wyl.mqtt;
+
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.paho.client.mqttv3.*;
+import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+@Slf4j
+public class SimpleMqttClient {
+
+ //全局唯一 单例
+ private static IMqttAsyncClient client;
+
+ private static IMqttAsyncClient getClient() {
+ return client;
+ }
+ private static void setClient(IMqttAsyncClient client) {
+ SimpleMqttClient.client = client;
+ }
+
+ /**
+ * 连接MQTT服务器
+ */
+ public void connect(String serverURI, String clientID, String username, String password) {
+
+ IMqttAsyncClient client = null;
+ try {
+ client = new MqttAsyncClient(serverURI, clientID, new MemoryPersistence());
+
+ MqttConnectOptions options = new MqttConnectOptions();
+ options.setCleanSession(false);
+ options.setUserName(username);
+ options.setPassword(password.toCharArray());
+ options.setServerURIs(new String[]{serverURI});
+ options.setConnectionTimeout(100);
+ options.setAutomaticReconnect(true);
+ //设置心跳
+ options.setKeepAliveInterval(30);
+ client.setCallback(new MqttCallbackExtended() {
+ @Override
+ public void connectComplete(boolean b, String s) {
+ log.info("重连成功!");
+ //publish("BUS_TS_REPLY_TOPIC_湘AB7182", "7E81074000010000000060013608025900000F7E", 0, false);
+
+ }
+
+
+ @Override
+ public void connectionLost(Throwable throwable) {
+ log.error("Lost connection!!! {}");
+ throwable.printStackTrace();
+ }
+
+ @Override
+ public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
+ log.info("接收消息主题 : " + topic);
+ log.info("接收消息Qos : " + mqttMessage.getQos());
+ }
+
+
+ @Override
+ public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
+ log.debug("send success ? --> {}, {}", iMqttDeliveryToken.isComplete(), 1);
+ }
+ });
+
+
+ try {
+ client.connect(options);
+ SimpleMqttClient.setClient(client);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 发布
+ *
+ * @param qos 连接方式
+ * @param retained 是否保留
+ * @param topic 主题
+ * @param pushMessage 消息体
+ */
+ public void publish(String topic, byte[] message, int qos, boolean retained) {
+
+ if(client != null && client.isConnected()) {
+ try {
+ IMqttDeliveryToken token = client.publish(topic, message, qos, retained);
+ token.waitForCompletion();
+ log.debug("Is the message sent successfully? --> {}, {}", token.isComplete());
+ } catch (MqttException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * 订阅某个主题
+ *
+ * @param topic 主题
+ * @param qos 连接方式
+ */
+ public void subscribe(String topic, int qos) {
+ log.info("开始订阅主题: {}" , topic);
+ if (client != null && client.isConnected()) {
+ try {
+ IMqttToken token = client.subscribe(topic, qos);
+ //token.waitForCompletion();
+ } catch (MqttException e) {
+ e.printStackTrace();
+ log.error("subscribe topic {} qos {} error!", topic, qos);
+ }
+ }
+ }
+ /**
+ * 订阅多主题
+ *
+ * @param topic 主题
+ * @param qos 连接方式
+ */
+ public void subscribe(String[] topics, int[] qos) {
+ log.info("开始订阅主题集合:{}", Arrays.asList(topics));
+ if (client != null && client.isConnected()) {
+ try {
+ IMqttToken token = client.subscribe(topics, qos);
+ //token.waitForCompletion();
+ } catch (MqttException e) {
+ e.printStackTrace();
+ log.error("subscribe topic {} qos {} error!", topics, qos);
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ SimpleMqttClient simpleMqttClient = new SimpleMqttClient();
+ simpleMqttClient.connect("tcp://127.0.0.1:1883", "123", "wyl","wyl");
+ simpleMqttClient.publish("wyl001", "123".getBytes(StandardCharsets.UTF_8), 0, false);
+ }
+}
+
diff --git a/pom.xml b/pom.xml
index 02d4715..c7c053d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,6 +17,8 @@
spring-boot
redis
DelayQueue
+ javacv
+ mqtt
pom
@@ -39,7 +41,7 @@
org.apache.kafka
kafka-clients
- 2.8.1
+ 3.4.0
com.xuxueli