node.js用dgram接收udp信号进行解析,并用websocket发送到浏览器前台

2 篇文章 0 订阅
1 篇文章 0 订阅

最近在做一个实验,接收udp信号发送过来的卫星航迹数据,在后台解算出它的航迹数据,然后将航迹数据发送到浏览器前端,将卫星的航迹图在浏览器前端可视化出来。

一、接收udp信号数据,在后台对原始数据解析解算

在这里插入图片描述

上图看到的是是一个udp信号发送模拟器,它发送的是卫星的航迹数据,发送端是在本机的6001端口,接收客户端是在本机的6000端口。(即发送器将udp信号数据从6001端口发送到6000端口
在node.js中,可用“dgram”数据报模块绑定本机的6000端口,接收到发送过来的udp数据。代码如下:

// 创建服务端,6000端口
    const dgram = require('dgram');
    let server = dgram.createSocket('udp4');
    //绑定端口和主机地址
    server.bind(6000);

上面三行代码中,第一行引入了“dgram”数据报模块,引入了该模块就能创建一个声明为“server”的对象,然后用“server”的“bind()”方法,绑定6000端口,就为后面接收到udp数据做准备

//有新数据包被接收时,触发    
	 var pp=[];      //定义一个数组,存放一帧数据中四个航迹点的数据
    server.on('message', function (msg, rinfo) {

        const buf1=msg.slice(0,2);			//切分出航迹信息的HEAD
        const buf2=msg.slice(2,4);			//切分出航迹信息的N
        const buf3=msg.slice(4,6);			//切分出航迹信息的TYPE
        const buf4=msg.slice(6,42);			//切分出第一个航迹点的所有数据
        const buf5=msg.slice(42,78);		//切分出第二个航迹点所有数据
        const buf6=msg.slice(78,114);		//切分出第三个航迹点所有数据
        const buf7=msg.slice(114,150);		//切分出第四个航迹点所有数据

    	//输出各航迹点的数据
        var p1=output(buf4);    //得到一帧数据中第一个点的数据
        var p2=output(buf5);    //得到一帧数据中第二个点的数据
        var p3=output(buf6);    //得到一帧数据中第三个点的数据
        var p4=output(buf7);    //得到一帧数据中第四个点的数据
        var p=[];
        p.push(p1,p2,p3,p4);    //定义一个数组,存放一帧数据中的四个航迹点数据
        pp=p                    //将数组p里面的数据放到数组pp中,便于后续操作
        console.log(pp);
        console.log('\n');

        // 解析一个航迹点的各种信息
        function output(pointBuff){
           let pState=pointBuff.readUIntBE(0,2).toString(16);					//解析出航迹点的标志位,分为0,1,2
           pState=parseInt(pState,16); 		//将16进制字符串信息转化为10进制数字
           let pNum=pointBuff.readUIntBE(2,1).toString(16);						//解析出航迹点的批号,分为1,2,3,4
           pNum=parseInt(pNum,16); 
           let pDistance=pointBuff.readUIntBE(4,2).toString(16);				//解析出航迹点的距离
           pDistance=parseInt(pDistance,16); 
           let pAngle=pointBuff.readUIntBE(6,2).toString(16);					//解析出航迹点的角度
           pAngle=parseInt(pAngle,16); 
           let pV=pointBuff.readUIntBE(8,2).toString(16);						//解析出航迹点的航速
           pV=parseInt(pV,16); 
           let pDre=pointBuff.readUIntBE(10,2).toString(16);					//解析出航迹点的航向
           pDre=parseInt(pDre,16); 
           let pHeight=pointBuff.readUIntBE(12,2).toString(16);					//解析出航迹点的高度
           pHeight=parseInt(pHeight,16); 
           const pRem="##";														//航迹点其他略去信息

           //定义一个数组,存放一个航迹点的各种信息
           const p=new Array(8);
           p[0]=pState;p[1]=pNum;p[2]=pDistance;p[3]=pAngle;p[4]=pV;
           p[5]=pDre;p[6]=pHeight;p[7]=pRem;
           // console.log("第"+pNum+"个航迹点数据为:")
           // console.log(p);
           // console.log("\n");
           return p;
        }
    });

上面的代码是“server”对象的on方法,当接收到数据时候,就会触发“message”事件。由于udp发送过来的数据是以Buffer字节流的形式发送的,所以在该事件中,自己根据实验要求写了一个function函数“output”,用来解析接收到的udp数据。
字节流的解析思路和方法在上一篇博客中也有粗略介绍。
这一段代码的最后结果和目的是得到存放解析后航迹点数据的数组pp

二、将解析后的航迹数据发送到浏览器前端

1、后端部分
在node.js中,可以用到H5里面的websocket API,将后端的数据发送到前端。
首先,需要引入外部依赖包模块,才能在node.js中运用websocket。将控制台切换到该node.js文件所在目录,然后输入“npm install nodejs-websocket --save”即可在该node.js文件用运用websocket。
代码如下:

// 引入websocket模块外部依赖包,(npm install nodejs-websocket --save)
        var ws=require('nodejs-websocket');

引入了外部模块,就可以相应的对象了,

 var wss=ws.createServer(conn =>{
            console.log("服务端与客户端正在连接");

            conn.on('text',function(data){
            console.log("收到的信息"+data);    //接收客户端发送的消息
            conn.send(pp.toString());  //当接收到客户端消息的时候,向客户端发送航迹点数据(将航迹点数据转化为字符串或者字节流才能发送)
            })

            conn.on('close',function(){
              console.log("closed");
            })

            conn.on('error',function(){
              console.log('error');
            })
        });

这里的对象名为“wss”,创建wss的时候,也触发一个回调函数,传来的参数是“conn”,conn的“text”事件是当接收到前端发送数据时候触发,在该事件中,利用conn.send()方法将存放航迹点数据的数组pp发送给前端。
运用websocket将数据从后端发送到前端,需要后端和前端都绑定相同的地址和端口,由于现在都是在本机,所以后端和前端都需要绑定相同端口。在本实验中,绑定的是本机3000端口,如下:

 wss.listen(3000,function(){
            console.log("正在监听3000端口");
        })

2、前端部分
在浏览器前端(html文件),也创建websocket,绑定和后端同样的端口,如下:

// 创建websocket连接
        const ws= new WebSocket('ws://localhost:3000');

当websocket连接打开时候,向后端发送数据,从而触发上面提到的后端的“text”事件,使得后端可以给前端发送数据。

 // websocket连接打开时候触发事件
       ws.onopen=function(e){
            console.log("服务器连接成功");
            //每隔一秒向服务器发送消息,以便后面每隔一秒收到消息
            setInterval(function(){
              ws.send("hello");
            },1000)
            
       }

这样,就可以接收后端发送来的数据了,可以将它在前端打印出来,代码如下:

  // 接收服务器的消息
        ws.onmessage= function (e) {
          var pp=(e.data).split(",");         //将接收到的航迹点数据由字符串转为数组
          console.log(pp);
        };

最后结果如下图,在浏览器控制台打印出了一系列航迹点数据
在这里插入图片描述

总结
经过以上步骤,就将航迹点的udp信号数据,在后端完成解析解算,然后发送到前端了。发送到前端后,就可以运用javascript的e-chart库和jquery库将航迹点数据以动态和图表的形式展示在前端了

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值