应用概述:
公司原本业务是服务端通过mqtt下发指令给相机端执行,现有需求将相机捕捉的一些图片或者 视频发送给服务端,然后服务端进行相应的存储。由于原本架构用的emqx(mqtt broker)适用于一些短的topic发送,视频和照片太大,所以就用到了nanomsg。当然我要求的是里面的req,rep模式。
1、依赖引入
<repositories>
<repository>
<id>clojars.org</id>
<url>https://mirrors.ustc.edu.cn/clojars/</url>
</repository>
</repositories>
<!--nng-->
<dependency>
<groupId>jnanomsg</groupId>
<artifactId>jnanomsg</artifactId>
<version>0.4.3</version>
</dependency>
</dependencies>
为何url和官网不同,因为外网真是很慢,依赖加不进去,只能用镜像。就像你刚下maven时候配置的阿里云镜像一个道理吧。
2、代码
官网demo可能太老,我根本跑不起来。还是从网上找的demo。
/**
* @author mlcheng
* @date 2022/10/17 11:13
*/
public class ReqRep {
private static String url = "tcp://192.168.1.106:7789";
public static void main(String[] args) {
reply();
request();
}
private static void request() {
final ReqSocket socket = new ReqSocket();
socket.connect(url);
new Thread(new Runnable() {
public void run() {
while (true) {
try {
socket.send("request");
Thread.sleep(1000);
System.out.println( socket.recvString());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
private static void reply() {
final RepSocket socket = new RepSocket();
socket.bind(url);
new Thread(new Runnable() {
public void run() {
while (true) {
try {
System.out.println(socket.recv());
Thread.sleep(1000);
socket.send("reply");
System.out.println("----send已经发送");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
这是打通的样子,但其实还少东西,你运行起来还是报错。
3、加入library
这是报错信息,还需要library nanomsg
原因:我也迷迷糊,大概意思人家是c语言写的,你java要用当然不能直接用了。
引用大佬讲解:nanomsg的使用,需要针对不同的平台编译并得到动态库,然后引入项目。当前自己在window10-x86-64 和 linux-x86-64的环境下编译了两个动态库。(本次使用的是nanomsg5.1.0)
windows:直接将nanomsg.dll和nanomsg.lib置于类路径下
linux:在类路径下创建目录 linux-x86-64,并将libnanomsg.so文件放入其下
编译(cmake,vs捣鼓捣鼓才行,java上哪会去)出来太麻烦还是用大佬的连接:获取dll,lib
4、完善
上面三步骤后,基本上就打通了,但是测试的时候reply端接收request发送的消息的字节长度有限制,需要进行改进,毕竟20兆的视频可是1024x1024x20=20971520 个字节
网上关于nanomsg和java的东西太少了,对于我这样菜鸟来说,太难了,只找到官网上零星一点点
零星一点点
反正最重要的一个就是nn_setsockopt方法,但是java中的nn_setsockopt方法。。。。没有这个rcvmaxsize
跟领导讨论一番后,他居然说你照葫芦画瓢写个带NN_RCVMAXSIZE的setSockopt的方法,我只能深情的说了句这是底层源码。
解决: 还是得是网上找,果然在github上找到了一个大佬重写了一些底层,然后还有这个方法。
附上连接:github地址
private static void reply() {
Charset charset = StandardCharsets.UTF_8;
final RepSocket socket = new RepSocket();
socket.bind(url);//20971520
socket.setSocketOpt(Nanomsg.SocketOption.NN_RCVMAXSIZE,42971520);
new Thread(new Runnable() {
public void run() {
while (true) {
try {
// String a = socket.recvString();
// System.out.println("-----------长度"+a.length());
System.out.println(charset.decode(socket.recv()).toString());
Thread.sleep(1000);
socket.send("reply");
System.out.println("----send已经发送");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
完美,我设置的是40多兆也能接收到request发送的消息了。