论文部分内容阅读
摘要:浏览器里的Web应用和计算机的串口硬件进行通信时,需要针对不同的浏览器开发不同的插件。采用HTML5内置的WebSocket技术和QT开发框架,通过WebSocket协议连接本地服务,并通过本地服务绑定串口完成全双工通信的方案,实现了跨浏览器的Web应用与客户端计算机串口通信的技术,解决了为不同浏览器产品及版本开发多种插件的问题。经过测试验证,达到了预期目标。
关键词:WebSocket;HTML5技术;串口通信
中图分类号:TP393文献标志码:A文章编号:1008-1739(2020)14-62-4
0引言
随着互联网的不断发展,软件趋向于网络化,很多计算机上的应用都做成了B/S架构,客户端打开浏览器就可以进行访问。但是出于安全考虑,浏览器与操作系统进行了隔离,浏览器不允许Web应用直接访问客户端的硬件,访问硬件就只能开发插件。每种浏览器各自的API不兼容,Chrome浏览器用NPAPI来执行一个本地程序获取硬件,Firefox浏览器使用JS-Ctypes技术实现插件,然后调用C++代码等来获取本地硬件。浏览器迭代速度快、接口变化大,开发插件时常遇到浏览器更新导致不能用,客户体验非常差,而且每次都开发对应版本的插件费时费力。WebSocket是HTML5规范中的一个部分,借鉴了Socket思想,为了Web应用程序和服务端全双工通信而专门制定的一种新的应用层协议。
1 WebSocket协议及帧结构
WebSocket Protocol是HTML5中一种新的协议,实现了浏览器与服务器全双工通信(full-duplex)。在这之前都是客户端主动请求服务端,请求一次应答一次,很多时候实现消息更新都是采用Ajax轮询,有延迟。有了WebSocket,双方都可以主动发给对端,实现真正的推送。WebSocket连接创建后,客户端和服务端进行数据交换時,协议控制的数据包头部较小。在不包含头部的情况下,服务端到客户端的包头只有2~10 Byte(取决于数据包长度),客户端到服务端需要加上额外的4 Byte掩码。而HTTP协议每次通信都需要携带完整的头部[1]。RFC文档给出的WebSocket协议格式,如图1所示。
WebSocket协议报文是分帧传输,FIN:1 bit,代表是否是尾帧,如果为1,即为最后片段;RSV1,RSV2,RSV3:每个占1 bit,为扩展保留的,若建立连接时使用了扩展,那么这些位的含义应自定义好;opcode:4 bit,定义负载数据(payload data)的类型,如表1所示。
WebSocket有控制帧和数据帧2种,opcode最高位为1的都是控制帧,opcode最高位为0的都是数据帧。应用级的数据传输帧,有文本帧和二进制帧2种。协议级别的控制报文帧,有关闭帧、ping帧和pong帧3种。关闭帧:opcode 0x8,连接任一端想关闭WebSocket,就发一个关闭帧给对端,对端收到该帧,若之前没有发过关闭帧,则必须回复一个关闭帧。ping帧和pong帧:用来心跳检测和判断对端是否还连接,连接建立后任一端都可以发送ping帧,收到ping的一端必须回复pong帧。
masked:1 bit,表示是否进行掩码处理,客户端发送给服务端时为1,服务端发送给客户端时为0。根据WebSocket的定义,客户端发送数据需要进行掩码处理,接收数据无需反掩码操作,服务端发送数据无需进行掩码处理,接收数据需要反掩码操作。
payload length:7 bit,如果第2个字节的后面7 bit的十进制值≤125,则直接用7 bit表示数据长度;如果该值为126,表示数据长度是126~65 535,这时要用3~4 Byte,每个字节8 bit,即16 bit来表示数据长度;如果该值为127,则说明数据长度已经>65 535,16 bit也已经不足以表示数据长度了,这时就用3~10 Byte,即64 bit来表示数据长度。
masking key:当masked为1的时候才存在,用于对需要的数据进行解密。
payload data:负载数据,就是要传输的数据。如果masked为1,该数据会被加密,要通过与masking key的值进行异或运算解密才能获取真正的负载数据。负载数据=扩展数据+应用数据。扩展数据包含在总负载数据长度中,其实就是自定义一个协议,如果有扩展数据,扩展数据就加在应用数据前面,并且要协商好扩展数据长度如何计算。应用数据是指扩展数据之后帧的剩余部分。
2方案设计
2.1本地服务的结构
本地服务主要实现WebSocket的服务端的串口控制和数据转发。WebSocket服务端用来处理客户端的浏览器Web应用连接,串口控制用来操作计算机的串口设备,本地服务内部转接双方的数据实现数据转发传输[2],本地服务结构如图2所示。
启动服务后,WebSocket服务等待客户端连接,打开串口控制等待数据收发。Web应用在浏览器打开后以客户端的形式和WebSocket服务建立通信连接。WebSocket服务承担起数据转发的任务。从Web端的数据包装成WebSocket数据发送给WebSocket服务端[3]。接收到数据的服务端把数据直接转发到串口。从串口发来的数据经过WebSocket服务包装成WebSocket数据发送给浏览器Web应用。
2.2数据的交换
设计2个缓存如图3所示,分别收发来自WebSocket和串口的数据。从WebSocket收到数据后,从缓存1位置按照字节写到缓存,写1 Byte更新一次写位置。更新写位置标志后串口从1位置开始读数据,读1 Byte更新一次读位置,直到写位置,把新的数据读出来后再发送出去。当读写位置到达缓存的末尾后,转到缓存开始的1位置重新开始读写。按照这种写一次读一次的形式循环,从WebSocket到串口数据实现了转发[5]。同样原理,在串口使用收到的数据也按字节存到另一个缓存,写一个字节更新一次写位置,WebSocket的发送按字节读一个字节更新一个位置,读出数据后把数据发送出去。
3设计实现
程序采用QT开发实现[6],QT是一个跨平台的C++图形用户界面应用程序框架,是完全面向对象的,很容易扩展,并且允许真正的组件编程,程序功能主要实现了2个类。
3.1 WebSocket服务类
WebSocket作为服务端程序实现的类,如图4所示。要接收来自客户端的连接,首先要用initServer()方法初始化服务器,属性有IP地址和port端口号,然后使用socketOpen()方法开启服务接受客户端的接入,客户端接入后给客户端自动分配端口号。连接后可使用messageReceived()方法处理收到的消息,使用sendData()方法发送数据,程序关闭时可用socketClose()方法断开服务关闭连接。
3.2串口控制类
WebSocket服务启动后会首先初始化打开串口,等待数据到来,程序实现的类如图4所示的Serial类。
设置串口属性set_uart_attr()方法包含的属性有PortName串口名,串口对于操作系统来说是一个文件,设置PortName为本机的串口名。BaudRate获取或设置串行波特率。DataBits获取或设置每个字节的标准数据位长度。StopBits获取或设置每个字节的标准停止位数。Parity获取或设置奇偶校验检查协议[4]。属性参数的改变可以通过配置文件设置,也可以通过WebSocket下发设置。
设置好参数后就可以打开串口,open_uart()方法打开一个新的串行端口连接,并启动读写线程,读写线程等待串口消息的到来。read_data()方法从缓冲区读取一些字节并将这些字节写入字节数组中指定的偏移量处,write_data()方法将指定的字符串写入串行端口。
4测试验证
测试过程中用到的工具软件有虚拟串口和串口助手。虚拟串口为解决计算机的物理串口个数的限制,在进行串口调试实验时,实现串口的回路。虚拟串口(VSPD)成对的形式添加串口,例如,COM1和COM2成对,那么COM1的数据就能发到COM2,COM2会自动接收COM1发送的数据。
串口助手用来模拟串口设备用于发送和接收数据,调试工具及串口发送效果如图5所示。
测试步骤:启动本地服务打开2个工具软件。
模拟设备发送:在调试助手输入aabbccdd数据点发送,虚拟串口把数据发送给连着串口1的本地WebSocket服务,收到数据后WebSocket服务立即进行转发,把数据包装成WebSocket协议格式,推送到浏览器,在浏览器收到后显示到文本框里,Web应用发送效果如图6所示。
模擬控制设备:在Web待发信息输入框中输入123456点发送,数据通过WebSocket协议包装经过WebSocket服务数据转发,把数据转发到串口1,再经过虚拟串口转接,最后在串口助手的接收文本框里显示。
5结束语
通过WebSocket技术实现了Web应用访问硬件,在主流浏览器测试均取得了成功,避免了为适应各种浏览器开发多种插件。本地服务的方式比较完美地实现了Web应用和串口的通信,同时也提供了一种思路,进一步的扩展也可以和其他的计算机硬件设备进行交互。外设开发厂商只需要开发一套程序就可以支持所有浏览器,节省外设开发厂商的成本。B/S程序的开发者也只用针对一套程序接口来调用外部设备,不需要考虑浏览器的差异。用户只需安装一次外设驱动,就可以使所有浏览器都可以调用外设。
参考文献
[1]陆晨,冯向阳,苏厚勤.HTML5 WebSocket握手协议的研究与实现[J].计算机应用与软件,2015,32(1):128-131,178.
[2]张宏桥,蒋虎,曾晓华,等.基于WebSocket的串口控制系统的研究[J].软件工程,2019,22(6):22-25.
[3]汪国辉.基于浏览器双向连接的研究与实现[D].北京:北京邮电大学,2013.
[4]谭思亮,邹群超.Visual C++串口通信工程开发实例导航[M].北京:人民邮电出版社,2003.
[5]包文祥,胡广朋.基于WebSocket的实时通信机制的设计与实现[J].计算机与数字工程,2019,47(7):1836-1840.
[6]霍亚飞.Qt Creator快速入门:第3版[M].北京:北京航空航天大学出版社,2017.
关键词:WebSocket;HTML5技术;串口通信
中图分类号:TP393文献标志码:A文章编号:1008-1739(2020)14-62-4
0引言
随着互联网的不断发展,软件趋向于网络化,很多计算机上的应用都做成了B/S架构,客户端打开浏览器就可以进行访问。但是出于安全考虑,浏览器与操作系统进行了隔离,浏览器不允许Web应用直接访问客户端的硬件,访问硬件就只能开发插件。每种浏览器各自的API不兼容,Chrome浏览器用NPAPI来执行一个本地程序获取硬件,Firefox浏览器使用JS-Ctypes技术实现插件,然后调用C++代码等来获取本地硬件。浏览器迭代速度快、接口变化大,开发插件时常遇到浏览器更新导致不能用,客户体验非常差,而且每次都开发对应版本的插件费时费力。WebSocket是HTML5规范中的一个部分,借鉴了Socket思想,为了Web应用程序和服务端全双工通信而专门制定的一种新的应用层协议。
1 WebSocket协议及帧结构
WebSocket Protocol是HTML5中一种新的协议,实现了浏览器与服务器全双工通信(full-duplex)。在这之前都是客户端主动请求服务端,请求一次应答一次,很多时候实现消息更新都是采用Ajax轮询,有延迟。有了WebSocket,双方都可以主动发给对端,实现真正的推送。WebSocket连接创建后,客户端和服务端进行数据交换時,协议控制的数据包头部较小。在不包含头部的情况下,服务端到客户端的包头只有2~10 Byte(取决于数据包长度),客户端到服务端需要加上额外的4 Byte掩码。而HTTP协议每次通信都需要携带完整的头部[1]。RFC文档给出的WebSocket协议格式,如图1所示。
WebSocket协议报文是分帧传输,FIN:1 bit,代表是否是尾帧,如果为1,即为最后片段;RSV1,RSV2,RSV3:每个占1 bit,为扩展保留的,若建立连接时使用了扩展,那么这些位的含义应自定义好;opcode:4 bit,定义负载数据(payload data)的类型,如表1所示。
WebSocket有控制帧和数据帧2种,opcode最高位为1的都是控制帧,opcode最高位为0的都是数据帧。应用级的数据传输帧,有文本帧和二进制帧2种。协议级别的控制报文帧,有关闭帧、ping帧和pong帧3种。关闭帧:opcode 0x8,连接任一端想关闭WebSocket,就发一个关闭帧给对端,对端收到该帧,若之前没有发过关闭帧,则必须回复一个关闭帧。ping帧和pong帧:用来心跳检测和判断对端是否还连接,连接建立后任一端都可以发送ping帧,收到ping的一端必须回复pong帧。
masked:1 bit,表示是否进行掩码处理,客户端发送给服务端时为1,服务端发送给客户端时为0。根据WebSocket的定义,客户端发送数据需要进行掩码处理,接收数据无需反掩码操作,服务端发送数据无需进行掩码处理,接收数据需要反掩码操作。
payload length:7 bit,如果第2个字节的后面7 bit的十进制值≤125,则直接用7 bit表示数据长度;如果该值为126,表示数据长度是126~65 535,这时要用3~4 Byte,每个字节8 bit,即16 bit来表示数据长度;如果该值为127,则说明数据长度已经>65 535,16 bit也已经不足以表示数据长度了,这时就用3~10 Byte,即64 bit来表示数据长度。
masking key:当masked为1的时候才存在,用于对需要的数据进行解密。
payload data:负载数据,就是要传输的数据。如果masked为1,该数据会被加密,要通过与masking key的值进行异或运算解密才能获取真正的负载数据。负载数据=扩展数据+应用数据。扩展数据包含在总负载数据长度中,其实就是自定义一个协议,如果有扩展数据,扩展数据就加在应用数据前面,并且要协商好扩展数据长度如何计算。应用数据是指扩展数据之后帧的剩余部分。
2方案设计
2.1本地服务的结构
本地服务主要实现WebSocket的服务端的串口控制和数据转发。WebSocket服务端用来处理客户端的浏览器Web应用连接,串口控制用来操作计算机的串口设备,本地服务内部转接双方的数据实现数据转发传输[2],本地服务结构如图2所示。
启动服务后,WebSocket服务等待客户端连接,打开串口控制等待数据收发。Web应用在浏览器打开后以客户端的形式和WebSocket服务建立通信连接。WebSocket服务承担起数据转发的任务。从Web端的数据包装成WebSocket数据发送给WebSocket服务端[3]。接收到数据的服务端把数据直接转发到串口。从串口发来的数据经过WebSocket服务包装成WebSocket数据发送给浏览器Web应用。
2.2数据的交换
设计2个缓存如图3所示,分别收发来自WebSocket和串口的数据。从WebSocket收到数据后,从缓存1位置按照字节写到缓存,写1 Byte更新一次写位置。更新写位置标志后串口从1位置开始读数据,读1 Byte更新一次读位置,直到写位置,把新的数据读出来后再发送出去。当读写位置到达缓存的末尾后,转到缓存开始的1位置重新开始读写。按照这种写一次读一次的形式循环,从WebSocket到串口数据实现了转发[5]。同样原理,在串口使用收到的数据也按字节存到另一个缓存,写一个字节更新一次写位置,WebSocket的发送按字节读一个字节更新一个位置,读出数据后把数据发送出去。
3设计实现
程序采用QT开发实现[6],QT是一个跨平台的C++图形用户界面应用程序框架,是完全面向对象的,很容易扩展,并且允许真正的组件编程,程序功能主要实现了2个类。
3.1 WebSocket服务类
WebSocket作为服务端程序实现的类,如图4所示。要接收来自客户端的连接,首先要用initServer()方法初始化服务器,属性有IP地址和port端口号,然后使用socketOpen()方法开启服务接受客户端的接入,客户端接入后给客户端自动分配端口号。连接后可使用messageReceived()方法处理收到的消息,使用sendData()方法发送数据,程序关闭时可用socketClose()方法断开服务关闭连接。
3.2串口控制类
WebSocket服务启动后会首先初始化打开串口,等待数据到来,程序实现的类如图4所示的Serial类。
设置串口属性set_uart_attr()方法包含的属性有PortName串口名,串口对于操作系统来说是一个文件,设置PortName为本机的串口名。BaudRate获取或设置串行波特率。DataBits获取或设置每个字节的标准数据位长度。StopBits获取或设置每个字节的标准停止位数。Parity获取或设置奇偶校验检查协议[4]。属性参数的改变可以通过配置文件设置,也可以通过WebSocket下发设置。
设置好参数后就可以打开串口,open_uart()方法打开一个新的串行端口连接,并启动读写线程,读写线程等待串口消息的到来。read_data()方法从缓冲区读取一些字节并将这些字节写入字节数组中指定的偏移量处,write_data()方法将指定的字符串写入串行端口。
4测试验证
测试过程中用到的工具软件有虚拟串口和串口助手。虚拟串口为解决计算机的物理串口个数的限制,在进行串口调试实验时,实现串口的回路。虚拟串口(VSPD)成对的形式添加串口,例如,COM1和COM2成对,那么COM1的数据就能发到COM2,COM2会自动接收COM1发送的数据。
串口助手用来模拟串口设备用于发送和接收数据,调试工具及串口发送效果如图5所示。
测试步骤:启动本地服务打开2个工具软件。
模拟设备发送:在调试助手输入aabbccdd数据点发送,虚拟串口把数据发送给连着串口1的本地WebSocket服务,收到数据后WebSocket服务立即进行转发,把数据包装成WebSocket协议格式,推送到浏览器,在浏览器收到后显示到文本框里,Web应用发送效果如图6所示。
模擬控制设备:在Web待发信息输入框中输入123456点发送,数据通过WebSocket协议包装经过WebSocket服务数据转发,把数据转发到串口1,再经过虚拟串口转接,最后在串口助手的接收文本框里显示。
5结束语
通过WebSocket技术实现了Web应用访问硬件,在主流浏览器测试均取得了成功,避免了为适应各种浏览器开发多种插件。本地服务的方式比较完美地实现了Web应用和串口的通信,同时也提供了一种思路,进一步的扩展也可以和其他的计算机硬件设备进行交互。外设开发厂商只需要开发一套程序就可以支持所有浏览器,节省外设开发厂商的成本。B/S程序的开发者也只用针对一套程序接口来调用外部设备,不需要考虑浏览器的差异。用户只需安装一次外设驱动,就可以使所有浏览器都可以调用外设。
参考文献
[1]陆晨,冯向阳,苏厚勤.HTML5 WebSocket握手协议的研究与实现[J].计算机应用与软件,2015,32(1):128-131,178.
[2]张宏桥,蒋虎,曾晓华,等.基于WebSocket的串口控制系统的研究[J].软件工程,2019,22(6):22-25.
[3]汪国辉.基于浏览器双向连接的研究与实现[D].北京:北京邮电大学,2013.
[4]谭思亮,邹群超.Visual C++串口通信工程开发实例导航[M].北京:人民邮电出版社,2003.
[5]包文祥,胡广朋.基于WebSocket的实时通信机制的设计与实现[J].计算机与数字工程,2019,47(7):1836-1840.
[6]霍亚飞.Qt Creator快速入门:第3版[M].北京:北京航空航天大学出版社,2017.