java+nanomsg(jnanomsg)

本文讲述了在原有MQTT服务基础上,使用Nanomsg的req, rep模式处理大文件(如视频、图片)传输的问题。通过引入jnangomsg库,解决了依赖问题,并在Windows和Linux环境下编译动态库。遇到的挑战包括Java中缺少nn_setsockopt方法的rcvmaxsize选项,最终通过查找资料和GitHub上的代码实现了设置接收缓冲区大小的功能,成功实现了大文件的传输。
摘要由CSDN通过智能技术生成

应用概述:
公司原本业务是服务端通过mqtt下发指令给相机端执行,现有需求将相机捕捉的一些图片或者 视频发送给服务端,然后服务端进行相应的存储。由于原本架构用的emqx(mqtt broker)适用于一些短的topic发送,视频和照片太大,所以就用到了nanomsg。当然我要求的是里面的req,rep模式。

1、依赖引入

与java结合官方文档
仓库和jnanomsg依赖

 <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发送的消息了。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值