软硬结合调试技巧
条评论目的
有些读者已经跑完demo2,当他尝试去修改代码时,往往发现达不到他所预期的效果,但又不知怎么做,其本质就是不知道怎么调试。这里我以demo2为例来示范调试技巧。
调试方法
调试的作用是当发现异常时,不断地调试,判断可能出现异常的地方,不断地缩小范围,直到找到发生异常的代码段,然后修复导致异常的代码。
- 打印调试法:在关键的地方打印关注的数据,看打印的信息来判断该环节是否符合预期。
- 断点调试法:进入调试模式并打断点,当代码运行到断点时代码会暂时到该处,此时可以看各变量是否符合预期,并可一步步地往下执行单行代码。
调试
我们来看看从左到右,即从TCP客户端到后端(服务器)到前端(网页),数据是怎么变化的。
首先在vscode里执行命令npm run start
启动demo2,可以看到,用于方便调试模拟硬件充当TCP客户端的bin\tcp-client.js
连接上了TCP服务器,发送的第一条消息是123456
,而TCP服务器将其信息打印出来:127.0.0.1:56813 receive: 123456
(第一条消息是充当设备ID的,后面消息才是模拟温度数据)。同理,后面的数据则是127.0.0.1:56813 receive: 20.83
,代码TCP客户端向TCP服务器发送了20.83
这条数据。通过查看打印的信息,我们就可以知道,TCP客户端向TCP服务器发送了什么数据,如果发现数据异常可以从这里看出来。
TCP服务器会把接收到的数据存放到数据库,当打开网页时查询历史数据时,就会把最近的历史数据发送到前端。我们打开MongoDB图形化客户端Robo 3T连接到MongoDB,查看所保存的数据。可以看到,数据库保存数据的格式,跟代码mongodb.insert({id:socket.id,data:socket.lastValue})
是一致的,是{id:...,data:...}
的样子:
然后,打开网页http://127.0.0.1:8002
,马上展示历史数据,并且打开调试工具,从console打印出来的信息可以看到websocket发来的实时数据。
历史数据的HTTP请求,可以在network里找到,并看到响应回来的数据,跟后端从数据库查询数据并响应的代码相对应:
websocket的通信,也是可以在network里找到,可以看到前端向服务器发送了一条{"equipmentId":"123456"}
数据代表订阅该设备的实时数据,然后不断地接收从后端发过来的实时数据:
判断出现问题的环节
那么,回到原来的问题:当我修改了部分代码,然后发现前端页面显示数据不正常时,如何去判断是哪个环节出了问题?
首先,就是在调试工具network看HTTP请求与websocket请求是否得到预期的数据?若得到预期的数据,说明就是前端代码出了问题。若得到就说明上一环节出了问题。若没发出请求,说明是前端代码出了问题,没有向后端请求数据。
来到上一环节服务器端,检查从TCP客户端接收的数据是否如得到所预期的数据,若没有说明是上一环节的问题(硬件或者网络问题),若正常得到数据,则说明不是TCP客户端的问题,检查服务器端这一环节。没有历史数据,则查看数据库是否如你预期那样保存了数据,若没有说明保存数据库这一环节出了问题。
这样,通过逆向的数据流分析,一环环地往上进行排查,判断是哪个环节出了问题。
打断点分析
很多时候,我们需要更详细的上下文信息来调试,则需要打断点:
vscode断点调试
首先要找到你要调试的文件,由于我们是想调试整个项目,所以我们要找到整个项目的入口文件,express框架的入口就是bin/www
,这个文件启动就会启动整个项目。
在启动调试之前或之后,可以点击代码行数前,单击出红点,那就是你想要调试的断点,当代码运行到断点处时就会暂停:
这样就能断点调试你的后端代码。
前端断点调试
类似的,前端断点调试是打开调试工具,进入Sources栏,找到JS文件的地方并在代码行数前点击生成断点:
特别地,前端代码有时被压缩打包(如webpack打包处理)后,通过手动打断点可能不行,可以在前端代码里输入debugger
,就会打断点。
其它工具
- postman常用于HTTP API的调试,如同调试TCP的网络调试助手,Postman教程大全-简书。
- websocket在线调试工具:websocket.org,或者百度搜索websocket在线调试工具。