我正在实现两个应用程序,其中一个应用程序用于发布关于主题的消息,另一个应用程序是同一主题的子应用程序。这两个应用程序正常工作,没有tls代码。
但是使用tls代码行,只要发布者应用程序在主题上发布消息,订阅者应用程序就会自动断开连接,即调用MQTTAsync_ConnectionLost回调。这两个应用程序遵循异步通信机制。
请求某人请求帮助,以解决问题。订阅者和出版商的日志如下所述。
发布商应用日志代码:
等待Hello World的发布!关于具有ClientID的客户端的主题MQTTExamplesSSL:ExampleClientPubSSL
成功连接
已确认令牌值为1的消息
成功断开连接
tls代码的订阅者应用日志:
成功连接
使用QoS2为客户端ExampleClientSubSSL订阅主题MQTTExamplesSSL
按Q退出
订阅成功
连接丢失
原因:(null)
重新连接
现在连接成功
分段错误
mytest_publishssl.c和mytest_subscribessl.c的代码文件:
mytest_publishssl.c:
public class PGPFlatFileItemReader extends FlatFileItemReader<Object>
implements InitializingBean {
/*
* if this flag is true that means file
* is commpressed
*/
private boolean isCompressed = true;
private String passphrase;
private String secretKeyFilePath;
private String publicKeyFilePath;
private String publicKeyUserId;
private String inputFilePath;
public PGPFlatFileItemReader() {
SecurityUtil.loadSecuritySetting();
}
/**
* @return the isCompressed
*/
public boolean isCompressed() {
return isCompressed;
}
/**
* @param isCompressed
* the isCompressed to set
*/
public void setCompressed(boolean isCompressed) {
this.isCompressed = isCompressed;
}
/**
* @return the passphrase
*/
public String getPassphrase() {
return passphrase;
}
/**
* @param passphrase
* the passphrase to set
*/
public void setPassphrase(String passphrase) {
this.passphrase = passphrase;
}
/**
* @return the secretKeyFilePath
*/
public String getSecretKeyFilePath() {
return secretKeyFilePath;
}
/**
* @param secretKeyFilePath
* the secretKeyFilePath to set
*/
public void setSecretKeyFilePath(String secretKeyFilePath) {
this.secretKeyFilePath = secretKeyFilePath;
}
/**
* @return the publicKeyFilePath
*/
public String getPublicKeyFilePath() {
return publicKeyFilePath;
}
/**
* @param publicKeyFilePath
* the publicKeyFilePath to set
*/
public void setPublicKeyFilePath(String publicKeyFilePath) {
this.publicKeyFilePath = publicKeyFilePath;
}
/**
* @return the publicKeyUserId
*/
public String getPublicKeyUserId() {
return publicKeyUserId;
}
/**
* @param publicKeyUserId
* the publicKeyUserId to set
*/
public void setPublicKeyUserId(String publicKeyUserId) {
this.publicKeyUserId = publicKeyUserId;
}
/**
* @return the inputFilePath
*/
public String getInputFilePath() {
return inputFilePath;
}
/**
* @param inputFilePath
* the inputFilePath to set
*/
public void setInputFilePath(String inputFilePath) {
this.inputFilePath = inputFilePath;
}
@Override
public void afterPropertiesSet() throws Exception {
super.afterPropertiesSet();
FileDecrypter fileDecrypter = new FileDecrypter();
if (this.isCompressed) {
this.uncompressFile(fileDecrypter.decryptFile(inputFilePath, secretKeyFilePath, passphrase.toCharArray(),
"sample.txt", true, 2));
inputFilePath = inputFilePath + Constants.INBOUND_UNC_FILE;
}
InputStream clearStream = fileDecrypter.decryptFile(inputFilePath, secretKeyFilePath, passphrase.toCharArray(),
"sample.txt", false, 2);
InputStreamResource in = new InputStreamResource(clearStream);
this.setResource(in);
}
private void uncompressFile(InputStream unc)
throws IOException, NoSuchProviderException, PGPException, SpringBatchException {
BufferedReader bufferRead = new BufferedReader(new InputStreamReader(unc));
ArrayList<String> rawdata = new ArrayList<String>();
FileEncrypter fileEncrypter = new FileEncrypter();
PGPPublicKey encKey;
String outFileName = inputFilePath + Constants.INBOUND_UNC_FILE;
if (JavaUtil.isObjectNull(publicKeyFilePath)) {
throw new SpringBatchException(ExceptionCodes.PUBLIC_KEY_NOTFOUND, "For Public Key Path");
}
encKey = SecurityUtil.readPublicKey(publicKeyFilePath, publicKeyUserId);
String line = bufferRead.readLine();
while (line != null) {
if (rawdata.size() < Constants.batchSize) {
rawdata.add(line + "\n");
} else if (rawdata.size() == Constants.batchSize) {
rawdata.add(line + "\n");
StringBuilder RecordsBuilder = new StringBuilder();
for (String record : rawdata) {
RecordsBuilder.append(record);
}
fileEncrypter.encryptBigText(outFileName, RecordsBuilder.toString(), encKey, false, true);
rawdata.clear();
}
line = bufferRead.readLine();
if (line == null) {
for (String record : rawdata) {
if (rawdata.size() > 0) {
fileEncrypter.encryptBigText(outFileName, record, encKey, false, true);
}
}
rawdata.clear();
}
}
if (rawdata.size() > 0) {
for (String record : rawdata) {
fileEncrypter.encryptBigText(outFileName, record, encKey, false, true);
}
}
FileEncrypter.setCalledForFirstTime(false);
FileEncrypter.closeStreams();
if (!JavaUtil.isObjectNull(FileEncrypter.fBufferedOut)) {
FileEncrypter.fBufferedOut.close();
}
}
}
mytest_subscribessl.c
#include <stdio.h>
#include "MQTTAsync.h"
#define ADDRESS "ssl://192.168.0.104:8883"
#define CLIENTID "ExampleClientPubSSL"
#define TOPIC "MQTTExamplesSSL"
#define PAYLOAD "Hello World!"
#define QOS 2
#define TIMEOUT 10000L
const char* server_key_file = "ca.pem";
volatile MQTTAsync_token deliveredtoken;
int finished = 0;
void connlost(void *context, char *cause)
{
MQTTAsync client = (MQTTAsync)context;
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
int rc;
printf("\nConnection lost\n");
printf(" cause: %s\n", cause);
printf("Reconnecting\n");
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start connect, return code %d\n", rc);
finished = 1;
}
}
void onDisconnect(void* context, MQTTAsync_successData* response)
{
printf("Successful disconnection\n");
finished = 1;
}
void onSend(void* context, MQTTAsync_successData* response)
{
MQTTAsync client = (MQTTAsync)context;
MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
int rc;
printf("Message with token value %d delivery confirmed\n", response->token);
opts.onSuccess = onDisconnect;
opts.context = client;
if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start sendMessage, return code %d\n", rc);
exit(-1);
}
//printf("Message sent is success \n");
}
int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message)
{
int i;
char* payloadptr;
printf("Message arrived\n");
printf(" topic: %s\n", topicName);
printf(" message: ");
payloadptr = message->payload;
for(i=0; i<message->payloadlen; i++)
{
putchar(*payloadptr++);
}
putchar('\n');
printf("End of the message \n");
printf("Inside the message arrived function \n");
return 1;
}
void onConnectFailure(void* context, MQTTAsync_failureData* response)
{
printf("Connect failed, rc %d\n", response ? response->code : 0);
finished = 1;
}
void onConnect(void* context, MQTTAsync_successData* response)
{
MQTTAsync client = (MQTTAsync)context;
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
int rc;
printf("Successful connection\n");
opts.onSuccess = onSend;
opts.context = client;
pubmsg.payload = PAYLOAD;
pubmsg.payloadlen = strlen(PAYLOAD);
pubmsg.qos = QOS;
pubmsg.retained = 0;
deliveredtoken = 0;
if ((rc = MQTTAsync_sendMessage(client, TOPIC, &pubmsg, &opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start sendMessage, return code %d\n", rc);
exit(-1);
}
}
int main(int argc, char* argv[])
{
MQTTAsync client;
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
MQTTAsync_SSLOptions sslopts = MQTTAsync_SSLOptions_initializer;
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
MQTTAsync_token token;
int rc;
MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
MQTTAsync_setCallbacks(client, NULL, connlost, NULL, NULL);
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
conn_opts.username = "Pravallika";
conn_opts.password = "Pravallika";
conn_opts.onSuccess = onConnect;
conn_opts.onFailure = onConnectFailure;
conn_opts.context = client;
conn_opts.ssl = &sslopts;
if (server_key_file != NULL)
conn_opts.ssl->trustStore = server_key_file; /*file of certificates trusted by client*/
//opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
//conn_opts.ssl->enabledCipherSuites = 1;
if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start connect, return code %d\n", rc);
exit(-1);
}
printf("Waiting for publication of %s\n"
"on topic %s for client with ClientID: %s\n",
PAYLOAD, TOPIC, CLIENTID);
while (!finished)
#if defined(WIN32)
Sleep(100);
#else
usleep(10000L);
#endif
MQTTAsync_destroy(&client);
return rc;
}
如果我遗漏任何tls功能,请提供帮助。