Windows平臺客戶端調用,有些麻煩,特別是一般個人用戶。反正鵝是找了好久Windows下C#的免費客戶端,找到那個OpenJDK編譯的dll,還不好用。
於是設想,使用JNI寫一個java的MqBridge,java類中有3個方法
public class test.MqBridge {
org.apache.rocketmq.client.producer.DefaultMQProducer producer;
descriptor: Lorg/apache/rocketmq/client/producer/DefaultMQProducer;
public test.MqBridge();
descriptor: ()V
//帶NAMESRV_ADDR
public void start(java.lang.String) throws org.apache.rocketmq.client.exception.MQClientException, java.lang.InterruptedException;
descriptor: (Ljava/lang/String;)V
//使用環境變量的NAMESRV_ADDR
public void start() throws org.apache.rocketmq.client.exception.MQClientException, java.lang.InterruptedException;
descriptor: ()V
public void stop();
descriptor: ()V
//發送,第1參數是topic,第2個參數是消息內容
public int send(java.lang.String, java.lang.String);
descriptor: (Ljava/lang/String;Ljava/lang/String;)I
}
經過使用VC調用測試,發送正常
RocketMQLog:WARN No appenders could be found for logger (io.netty.util.internal.PlatformDependent0).
RocketMQLog:WARN Please initialize the logger system properly.
Call java start()
SendResult [sendStatus=SEND_OK, msgId=7F0000010EA000387F443B6B330C0000, offsetMsgId=C0A8008200002AA70000000000
0B1772, messageQueue=MessageQueue [topic=device_data, brokerName=broker-a, queueId=3], queueOffset=426]
Call java send()
Call java stop()
調用過程代碼
jclass clsBridge = env->FindClass("test/MqBridge");//類
if(NULL==clsBridge){
cout<<"Can't find/load the MqBridge class ";printErrMsg(GetLastError());cout<<endl;
return false;
}
jobject objBridge = env->AllocObject(clsBridge);//實例
if(NULL==objBridge){
cout<<"Create instance of MqBridge class failed"<<endl;
return false;
}
//調用start方法
char addr[]="192.168.0.130:9876";
jstring addrJ=env->NewStringUTF(addr);
jmethodID midStart = env->GetMethodID(clsBridge, "start", "(Ljava/lang/String;)V");
env->CallVoidMethod(objBridge, midStart, addrJ);
cout<<"Call java start()"<<endl;
//發送消息,可以反覆調用send
char topic[]="device_data";
char msg[]="test rockmq";
jstring topicJ=env->NewStringUTF(topic);
jstring msgJ =env->NewStringUTF(msg);
jmethodID midSend = env->GetMethodID(clsBridge, "send", "(Ljava/lang/String;Ljava/lang/String;)I");
env->CallObjectMethod(objBridge, midSend, topicJ, msgJ);
cout<<"Call java send()"<<endl;
//結束,關停
jmethodID midStop = env->GetMethodID(clsBridge, "stop", "()V");
env->CallVoidMethod(objBridge, midStop);
cout<<"Call java stop()"<<endl;
測試環境 1(32位編譯):
JDK1.8(32位) + VC2008+Windows7 X64
測試環境 2(64位編譯):
JDK1.8(64位) + VC2019+Windows7 X64
測試環境 3(32位編譯):
JDK1.8(32位) + VC2019+Windows7 X64
關鍵的classpath
classPath=-Djava.class.path=D:/vc_java/bin;C:/jdk1.8.0_311_x86/lib;D:/rocketmq-all-4.8.0-bin-release/lib/rocketmq-client-4.8.0.jar;D:/rocketmq-all-4.8.0-bin-release/lib/rocketmq-common-4.8.0.jar;D:/rocketmq-all-4.8.0-bin-release/lib/rocketmq-remoting-4.8.0.jar;D:/rocketmq-all-4.8.0-bin-release/lib/rocketmq-logging-4.8.0.jar;D:/rocketmq-all-4.8.0-bin-release/lib/netty-all-4.0.42.Final.jar;D:/rocketmq-all-4.8.0-bin-release/lib/commons-lang3-3.4.jar;D:/rocketmq-all-4.8.0-bin-release/lib/fastjson-1.2.69.jar;D:/rocketmq-all-4.8.0-bin-release/lib/commons-validator-1.6.jar
一般的性能要求是可以應付的,對於性能要求不是極致的話,可以這樣考慮。也可以編譯成.dll,供其它語言使用。