目的

 有些读者已经跑完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在线调试工具。