一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

一种信息处理方法及装置与流程

2023-01-05 22:46:58 来源:中国专利 TAG:


1.本发明涉及通信领域,特别涉及一种信息处理方法及装置。


背景技术:

2.众所周知,消息队列遥测传输(message queuing telemetry transport,mqtt)协议构建于网络协议栈之上,已广泛运用到物联网连接领域,可以实现客户端和服务器端的协议层连接和传输。
3.但是,在进行消息传输时,往往在一个线程的大循环中发起且循环调用,很容易造成资源的浪费,如何解决上述问题,是需要考虑的。


技术实现要素:

4.本发明的目的在于提供一种信息处理方法及装置,以避免造成资源的浪费。
5.为了达到上述目的,本发明提供了一种信息处理方法,所述方法包括:在确定不存在对应于消息队列遥测传输mqtt协议客户端的第一线程的输入信息的情况下,控制所述第一线程进入阻塞状态,释放所述第一线程所占用的处理器时间片;利用释放的所述处理器时间片,执行除所述第一线程外的其他线程。
6.可选的,在所述第一线程为主线程时,所述输入信息为输入消息队列中的信息;在所述第一线程为发送线程时,所述输入消息为输出消息队列中的信息;在所述第一线程为接收线程时,所述输入消息为服务器发出的消息;其中,所述输入消息队列中包括输入至所述主线程的信息,所述输出消息队列包括经过所述主线程处理,并输入至所述发送线程的信息。
7.可选的,在控制所述第一线程进入阻塞状态之后,还包括:在监听到对应于所述消息队列遥测传输mqtt协议客户端的第一线程的输入信息时,控制所述第一线程由所述阻塞状态更新为唤醒状态。
8.可选的,所述方法还包括:采用异步通信方式向服务器发送第一数据信息以及接收所述服务器反馈的第二数据信息;其中,所述第一数据信息包括针对所述第一线程的输入信息。
9.可选的,所述采用异步通信方式向服务器发送第一数据信息以及接收所述服务器反馈的第二数据信息,包括:通过发送线程向所述服务器发送第一数据信息,以及,通过接收线程接收所述服务器反馈的第二数据信息,其中所述发送线程和所述接收线程采用异步工作模式。
10.可选的,所述方法还包括:根据目标参数,确定目标通信方式;其中,所述目标通信方式用于与服务器进行通信,所述目标通信方式为同步通信方式或者异步通信方式。
11.本发明的另一实施例提供了一种信息处理装置,所述装置包括:确定模块,用于确定不存在对应于消息队列遥测传输mqtt协议客户端的第一线程的输入信息;控制模块,用于控制所述第一线程进入阻塞状态,释放所述第一线程所占用的处理器时间片;控制模块,
还用于利用释放的所述处理器时间片,执行除所述第一线程外的其他线程。
12.可选的,在所述第一线程为主线程时,所述输入信息为输入消息队列中的信息;在所述第一线程为发送线程时,所述输入消息为输出消息队列中的信息;在所述第一线程为接收线程时,所述输入消息为服务器发出的消息;其中,所述输入消息队列中包括输入至所述主线程的信息,所述输出消息队列包括经过所述主线程处理,并输入至所述发送线程的信息。
13.本发明的另一实施例提供了一种电子设备,包括:处理器、存储器及存储在所述存储器上并可在所述处理器上运行的程序,所述程序被所述处理器执行时实现如上所述的信息处理方法。
14.本发明的另一实施例提供了一种计算机可读存储介质,所述计算机可读存储介质上存储计算机程序,所述计算机程序被处理器执行时,实现如上所述的信息处理方法的步骤。
15.本发明的上述技术方案至少有如下有益效果:
16.本发明实施例的信息处理方法,在确定第一线程不存在输入信息的情况下,通过控制第一线程进入阻塞状态并释放其占用的处理器时间片,可以避免处于阻塞状态的第一线程对处理器时间片的占用。并且,利用释放的所述处理器时间片,执行除所述第一线程外的其它线程,可以提高处理器对其它线程的处理效率。
附图说明
17.图1为本发明实施例提供的一种信息处理方法的流程示意图之一;
18.图2为本发明实施例提供的一种信息处理方法的架构示意图;
19.图3为本发明实施例提供的一种信息处理方法的流程示意图之二;
20.图4为本发明实施例提供的一种信息处理方法的流程示意图之三;
21.图5为本发明实施例提供的一种信息处理方法的流程示意图之四;
22.图6为本发明实施例提供的一种信息处理方法的流程示意图之五;
23.图7a为本发明实施例提供的一种信息处理方法的流程示意图之六;
24.图7b为本发明实施例提供的一种信息处理方法的流程示意图之七;
25.图7c为本发明实施例提供的一种信息处理方法的流程示意图之八;
26.图8为本发明实施例提供的一种信息处理装置的模块示意图。
具体实施方式
27.为使本发明要解决的技术问题、技术方案和优点更加清楚,下面将结合附图及具体实施例进行详细描述。在下面的描述中,提供诸如具体的配置和组件的特定细节仅仅是为了帮助全面理解本发明的实施例。因此,本领域技术人员应该清楚,可以对这里描述的实施例进行各种改变和修改而不脱离本发明的范围和精神。另外,为了清楚和简洁,省略了对已知功能和构造的描述。
28.应理解,说明书通篇中提到的“一个实施例”或“一实施例”意味着与实施例有关的特定特征、结构或特性包括在本发明的至少一个实施例中。因此,在整个说明书各处出现的“在一个实施例中”或“在一实施例中”未必一定指相同的实施例。此外,这些特定的特征、结
构或特性可以任意适合的方式结合在一个或多个实施例中。
29.在本发明的各种实施例中,应理解,下述各过程的序号的大小并不意味着执行顺序的先后,各过程的执行顺序应以其功能和内在逻辑确定,而不应对本发明实施例的实施过程构成任何限定。
30.应理解,本文中术语“和/或”,仅仅是一种描述关联对象的关联关系,表示可以存在三种关系,例如,a和/或b,可以表示:单独存在a,同时存在a和b,单独存在b这三种情况。另外,本文中字符“/”,一般表示前后关联对象是一种“或”的关系。
31.在本发明所提供的实施例中,应理解,“与a相应的b”表示b与a相关联,根据a可以确定b。但还应理解,根据a确定b并不意味着仅仅根据a确定b,还可以根据a和/或其它信息确定b。
32.参见图1,本发明的一实施例提供了一种信息处理方法,包括以下步骤:
33.步骤11:在确定不存在对应于消息队列遥测传输mqtt协议客户端的第一线程的输入信息的情况下,控制所述第一线程进入阻塞状态,释放所述第一线程所占用的处理器时间片。
34.在控制第一线程进入阻塞状态之后,第一线程会暂时停止对输入信息的接收或者处理。通过在第一线程处于阻塞状态时,释放第一线程所占用的处理器时间片,可以避免处于阻塞状态下的第一线程对处理器时间片的占用。
35.需要说明的是,所述阻塞状态可以理解为:一个正在执行的线程在某些特殊情况下(例如可以是执行耗时的输入/输出操作),会放弃处理器的使用权,进入阻塞状态。
36.步骤12:利用释放的所述处理器时间片,执行除所述第一线程外的其它线程。
37.本发明实施例提供的信息处理方法,在确定第一线程不存在输入信息的情况下,通过控制第一线程进入阻塞状态并释放其占用的处理器时间片,可以避免处于阻塞状态的第一线程对处理器时间片的占用。并且,利用释放的所述处理器时间片,执行除所述第一线程外的其它线程,可以提高处理器对其它线程的处理效率。
38.本发明实施例提供的信息处理方法,在所述第一线程为主线程时,所述输入信息为输入消息队列中的信息;在所述第一线程为发送线程时,所述输入消息为输出消息队列中的信息;在所述第一线程为接收线程时,所述输入消息为服务器发出的信息;其中,所述输入消息队列中包括输入至所述主线程的信息,所述输出消息队列包括经过所述主线程处理,并输入至所述发送线程的信息。
39.需要说明的是,所述服务器可以是提供物联网平台的服务器。
40.接收线程通过下层协议栈接收服务器发出的信息。
41.本发明实施例提供的信息处理方法,在控制所述第一线程进入阻塞状态之后,还包括:在监听到对应于所述消息队列遥测传输mqtt协议客户端的第一线程的输入信息时,控制所述第一线程由所述阻塞状态更新为唤醒状态。
42.需要说明的是,第一线程在更新为唤醒状态之后,可以继续对输入信息进行处理,从而进行后续操作。
43.本发明实施例提供的信息处理方法,所述方法还包括:采用异步通信方式与服务器进行通信。
44.需要说明的是,异步通信方式可以理解为,在发送第一数据信息之后,无需等待服
务器针对第一数据信息的反馈(该反馈例如可以是确认接收到第一数据信息的消息),便可以继续向服务器发送数据信息,提高数据发送的效率。尤其是在数据量较大的情况下,采用异步通信方式,可以提高数据的吞吐量,保证数据发送的时效性。
45.当然,也可以采用同步通信方式与服务器进行通信。
46.本发明实施例提供的信息处理方法,所述采用异步通信方式与服务器进行通信,包括:通过发送线程向所述服务器发送第一数据信息,以及,通过接收线程接收所述服务器反馈的第二数据信息,其中,所述发送线程和所述接收线程采用异步工作模式。
47.需要说明的是,发送线程和接收线程为两个独立的线程,两者采用异步工作模式,互不影响,可以提高与服务器进行通信的效率。
48.本发明实施例提供的信息处理方法,所述方法还包括:根据目标参数,确定目标通信方式;其中,所述目标通信方式用于与服务器进行通信,所述目标通信方式为同步通信方式或者异步通信方式。
49.需要说明的是,同步通信方式可以理解为,在发送第一数据信息之后,需要等待服务器针对第一数据信息的反馈(该反馈例如可以是确认接收到第一数据信息的消息),再继续向服务器发送数据信息。
50.目标参数例如可以是数据量的大小,例如,数据量较大,则可以采用异步通信方式,数据量较小,则可以采用同步通信方式。目标参数例如还可以是用时的长短,例如,期望用时短获取到数据,则可以采用异步通信方式,对用时没有要求,则既可以采用同步通信方式,也可以采用异步通信方式。
51.接下来参见图2,为本发明实施例提供的一种信息处理方法的架构示意图。在图2所示的架构示意图中,mqtt协议客户端由三个独立线程实现的模块构成:mqtt主处理模块、mqtt发送模块、mqtt接收模块。其中,mqtt主处理模块对应mqtt主线程,mqtt发送模块对应mqtt发送线程,mqtt接收模块对应mqtt接收线程。下面对各个模块的功能进行阐述。
52.mqtt主处理模块:mqtt客户端主逻辑处理模块,实现客户端相关结构、实体和回调函数初始化,客户端网络和mqtt协议层连接,客户端所需主题订阅和接收保持,客户端所需主题发布和发送保持及客户端错误状态处理等功能。mqtt主处理模块采用状态机跳转的工作方式,分为初始化状态、连接状态和保持状态。
53.其中,初始化状态下完成相关结构、实例和回调函数初始化工作,以及mqtt发送模块对应的mqtt发送线程、mqtt接收模块对应的mqtt接收线程的初始化,其中,mqtt发送线程和mqtt接收线程为相互独立的两个线程。
54.连接状态下完成网络连接和mqtt协议层连接,所需主题订阅,以及心跳循环定时器启动。
55.保持状态下转入由输入事件驱动的响应工作模式,无输入事件时则转入阻塞状态。不同的输入事件由不同的自定义类型头区分,对应“保持发送”、“保持接收”和“错误处理”三个模块分类处理。其中,保持发送包括mqtt协议客户端相关主题发布,主题订阅,主题退订和心跳请求发送。保持接收包括各类发送报文的响应报文接收,已订阅主题数据接收。错误处理包括服务器端响应超时处理,发送、接收返回错误处理,以及发送失败情况反馈上层应用。
56.本发明实施例提供的mqtt主处理模块输入接口,为mqtt客户端操作系统提供的消
息队列机制实现。可实现多线程、多输入源统一对mqtt主线程输入不同的事件请求,并根据优先级设定进行排队。在输入消息队列为空时则阻塞mqtt主处理线程。mqtt主处理模块的输出接口为另一个消息队列,连接mqtt主处理线程和mqtt发送线程,实现不同事件的mqtt数据报文发送请求。
57.mqtt发送模块:实现mqtt主处理模块中不同事件请求的mqtt协议报文发送功能。通过mqtt主处理模块的输出接口获取待发送报文,并调用下层网络协议栈接口进行发送。当报文发送返回错误时,通过mqtt主处理模块的输入接口注入错误事件,触发mqtt主处理模块的错误处理动作。当mqtt主处理模块的输出接口消息队列为空时,mqtt发送线程将被阻塞。
58.mqtt接收模块:实现对mqtt服务器端发送到本mqtt协议客户端的协议报文接收功能。调用下层网络协议栈的阻塞式接收接口获得报文,通过mqtt主处理模块的输入接口注入“报文接收事件”,触发mqtt主处理模块的“保持接收”模块对报文进行后续处理。当报文接收返回错误时,通过mqtt主处理模块的输入接口注入错误事件,触发mqtt主处理模块的错误处理动作;当没有数据接收时,mqtt接收线程也将被阻塞。
59.除此以外,本发明在mqtt主处理模块初始化时,初始化了一组用以报文发送定时的发送定时器和一个用以心跳触发的循环定时器,该定时器利用操作系统提供的软件定时器机制,在软件定时器线程中执行。mqtt主线程从连接状态转入保持状态前会启动心跳触发定时器,以预设的心跳保持时间触发心跳到时。当心跳到时发生时,初始化时注册的到时回调处理函数会检查上次心跳请求发出后,是否有心跳应答超时的情况发生。如果无超时发生,则向mqtt主处理模块输入消息队列注入心跳请求事件,以触发主处理模块发送心跳请求报文。如果有心跳应答超时发生,则向输入消息队列注入心跳超时事件,触发主处理模块错误处理行为。
60.另外,当mqtt发送模块或mqtt接收模块完成了一次报文的发送或接收时,均会对心跳触发定时器进行重置。mqtt主处理模块的保持发送模块在每发送一个需要对端应答的报文后会启动一个发送定时器,如:主题发布publish(qos1、2)、主题订阅subscribe、已订阅主题的退订unsubscribe、心跳请求pingreq、发布收到pubrec。当定时器超时前如果接收到对端返回的对应报文,则清除对应的定时器,否则将触发定时器回调处理函数生成对应报文应答超时事件并注入主线程输入消息队列,从而触发mqtt主处理模块错误处理行为。
61.对mqtt主处理模块需要调用操作系统线程创建和启动接口函数启动为一个独立线程。可选的,mqtt主线程的启动方式可以通过计算机壳层shell接口函数输出到命令行实现如:“mqtt_start”,或提供用户层应用程序接口(application programming interface,api)。
62.在mqtt主线程内部,分为“mqtt_state_init”(初始化)、“mqtt_state_con”(连接)、“mqtt_state_keep”(保持)三个状态,由条件选择判断执行。mqtt主线程启动时预置先进入“mqtt_state_init”状态,即初始化流程执行。
63.接下来,参见图3,为mqtt主线程在初始化状态中的执行流程图。该流程图中,包括以下步骤:
64.步骤31:mqtt_state_init(初始化)。在初始化流程里线程将初始化。
65.步骤32:网络实例初始化。可选的,网络实例包括服务器端网络地址,端口号,连接
证书,网络连接、断开、读、写的回调函数,及其他网络连接所需的信息。
66.步骤33:mqtt协议客户端实例初始化。可选的,mqtt协议客户端实例包括:包括发送缓冲寄存器buffer、接收缓冲寄存器buffer,连接状态指示与心跳状态指示状态位,心跳间隔时间,mqtt消息主题(topic)过滤器结构,发送定时器、心跳定时器(可选的,所述发送定时器和心跳定时器均为软件定时器),以及其它mqtt协议客户端工作所需的信息。
67.步骤34:订阅主题初始化。
68.步骤35:订阅、发布失败回调处理函数初始化。可选的,包括初始化mqtt订阅的主题、服务质量及回调处理函数,mqtt订阅失败回调处理函数及mqtt发布失败回调处理函数。
69.步骤36:输入消息队列、输出消息队列初始化。mqtt主处理线程输入消息队列、输出消息队列:消息队列是由底层操作系统提供的一种线程间通信方法,可以由多发送方发送变长数据到一个线程中。在本发明中初始化为接收方阻塞的方式,即消息队列为空时接收消息队列的线程进入阻塞状态。对于mqtt主处理线程的输入消息队列,由于有多个来源的数据输入,可选的,实现以优先级排序的消息出队方法,即对“紧急事件”如心跳请求事件或错误处理事件优先传送给mqtt主线程处理。
70.需要说明的是,还可以对注入输入消息队列的不同消息,定义一个字节的自定义消息头。可选的,自定义消息头包含4bit“消息类型”字段和4bit“消息id”字段。其中,消息类型用以区分不同的请求事件,以触发mqtt主线程转入不同的处理模块或不同的运行状态。消息id(mid)用以区分和记录上层用户层(例如具有mqtt协议客户端的应用app)需发送的不同数据包。当发送出现错误或应答超时,将通过mid告知用户应用出现错误的数据包,以方便用户应用发起数据重发等后续处理策略。
71.对于mqtt协议报文接收的情况,可以同时有多个mqtt报文被发送到输入消息队列里等待mqtt主线程处理,但是要根据业务模型合理设置消息队列总容量,防止消息队列频繁充满的情况发生。对于mqtt主线程的输出消息队列,将接收不同mqtt动作(如:“主题订阅”、“主题退订”、“主题发布”、“发布应答”、“心跳请求”)的待发送报文到消息队列中排队,且也将初始化为接收方阻塞的方式,即输出消息队列为空时阻塞mqtt发送线程。
72.步骤37:mqtt发送线程、mqtt接收线程初始化。通过操作系统线程创建接口,将mqtt发送模块和mqtt接收模块初始化为两个独立的线程,在初始化状态下,mqtt发送模块和mqtt接收模块均只初始化而不启动。
73.步骤38:mqtt_state_con。mqtt主处理线程完成各项初始化工作后将自身状态转到“mqtt_state_con”连接状态。
74.接下来参见图4,为mqtt发送线程执行流程图。在该流程图中,包括以下步骤:
75.步骤41:输出消息队列。输出消息队列中存在输入至mqtt发送线程的消息。
76.步骤42:输出消息队列消息接收。其中,输出消息队列为mqtt发送线程的消息来源。
77.步骤43:协议栈发送接口。通过协议栈发送接口,mqtt发送线程将输出消息队列中的消息发送给下层协议栈。
78.步骤44:确定是否返回发送失败的消息。若是,则执行步骤45,若否,则执行步骤42。
79.步骤45:生成发送错误事件到输入消息队列。
80.步骤46:输入消息队列。其中,mqtt主线程通过输入消息队列,可以获得发送错误事件的信息,从而mqtt主线程可以对发送错误事件进行处理。
81.需要说明的是,在mqtt发送模块中包括:(1)mqtt主线程的输出消息队列的接收函数,该函数用以接收待发送的mqtt报文。mqtt报文发送接口为阻塞式接口,即当输出消息队列为空时,mqtt发送线程将被阻塞。(2)mqtt报文发送函数,该函数将调用下层网络协议栈的发送接口函数按收到的待发送报文和报文长度顺序进行发送。可选的,下层协议栈可以是tcp/ip协议栈接口或at协议栈接口,根据mqtt协议客户端选择的硬件模块进行配置。(3)“发送错误”的处理函数,该函数用以处理网络协议栈返回发送错误的情况。该函数在报文发送产生错误时生成消息头类型为“发送错误事件”消息,并调用主线程输入消息队列的发送函数注入到输入消息队列中,以触发mqtt主处理线程的错误处理动作。
82.接下来,参见图5,为mqtt接收线程执行流程图。在该流程图中,包括以下步骤:
83.步骤51:协议栈接收接口。其中,协议栈接收接口用于接收下层协议栈发送的消息,其中,该消息为服务器发送的。
84.步骤52:判断是否返回接收失败。若是,则执行步骤53,若否,则执行步骤55。
85.步骤53:生成发送错误事件到输入消息队列。
86.步骤54:生成报文接收事件到输入消息队列。
87.步骤55:输入消息队列。
88.mqtt主线程通过输入消息队列,可以获得发送错误事件的信息以及报文接收事件的信息,从而mqtt主线程可以对发送错误事件以及报文接收事件进行处理。
89.需要进一步说明的是,mqtt接收模块中包括:(1)mqtt报文接收函数。该函数将调用下层协议栈的接收接口函数接收来自网络的mqtt报文。可选的,下层协议栈可以是tcp/ip协议栈接口或者at协议栈接口。该接收接口函数需要实现为阻塞式接口,即当无数据接收时,mqtt接收线程将被阻塞。当接收到mqtt报文后,该线程将调用主线程输入消息队列的发送函数,生成并注入一个自定义消息头为“报文接收事件”消息,以触发mqtt主处理线程后续转到保持接收模块进行处理。(2)“接收错误”的处理函数,该函数用以处理协议栈返回接收错误的情况,该函数在报文接收产生错误时生成消息头类型为“接收错误事件”消息,并调用mqtt主线程输入消息队列的发送函数注入到输入消息队列中,以触发mqtt主线程的错误处理动作。
90.接下来参见图6,为mqtt主线程连接状态执行流程图。在该流程图中,包括以下步骤:
91.步骤61:mqtt_state_con。
92.步骤62:判断是否建立socket连接,若否,则返回步骤61,若是,则执行步骤63。
93.步骤63:启动mqtt发送线程和mqtt接收线程。
94.步骤64:生成登录令牌码。
95.步骤65:生成连接connect报文。
96.步骤66:发送connect报文。
97.步骤67:判断在计时内是否返回确认连接请求connack,若否的话执行步骤68,若是的话执行步骤69。
98.步骤68:判断是否返回错误码,若是的话,执行步骤610。若否的话,执行步骤611、
步骤612,并重新执行步骤61。
99.步骤610:输出错误提示。
100.步骤611:输出超时提示。
101.步骤612:断开socket连接。
102.步骤69:生成主题订阅subscribe报文。
103.步骤613:发送subscribe报文。
104.步骤614:判断在计时内是否返回suback。若否,则执行步骤615,若是,则执行步骤616。
105.步骤615:判断是否返回错误码。若是,则执行步骤617及步骤616。若否,则执行步骤618、步骤619,并重新执行步骤64。
106.步骤617:订阅失败回调处理。
107.步骤618:输出超时提醒。
108.步骤619:输出断开连接disconnect报文。
109.步骤616:启动心跳计时器。
110.步骤620:mqtt_state_keep。
111.接下来对上述步骤进行整体说明。首先客户端需要和服务器端建立socket网络连接,通过调用初始化时注册的网络实例回调函数建立socket。可选的,如果建立socket连接不成功主线程将在此循环重连。
112.启动mqtt发送和接收线程:调用操作系统提供的线程启动函数,将已初始化好的mqtt发送和接收线程转入就绪态。
113.需要说明的是,mqtt客户端中保存有mqtt客户端连接函数、mqtt主题订阅函数以及“心跳请求”启动函数。其中,mqtt客户端连接函数:mqtt客户端与服务器端的协议层连接一般需要“客户id”、“客户密钥”、“客户设备名”、“客户设备id”等信息。可选的,以上信息可以在mqtt客户端结构体中预置,mqtt客户端需要具有加密令牌生成函数,从而将以上信息通过某种加密算法进行计算得到登陆服务器端所需的令牌码。可选的,为了设计简便,将mqtt协议客户端连接函数的数据发送以及数据接收设计为同步方式。得到登陆令牌后调用mqtt报文编帧函数,将需要发送的报文头类型,服务质量等级,登陆令牌码等按照mqtt协议标准格式组合成“connect”报文并存入发送缓存区。然后,调用输出消息队列的发送接口将报文发给mqtt发送线程。此后mqtt主线程将定时等待mqtt接收线程返回的数据情况,即调用输入消息队列的接收接口。由于该接口之前初始化为阻塞接口,此时的阻塞时间需要设置为需等待的时间。定时到时后,可能会存在三种结果:(1)输入消息队列的接收接口有数据返回,调用mqtt报文解码函数,得到服务器端返回连接成功确认“connack”,此时mqtt主线程将客户端实例的连接指示状态位置位,接着执行后续mqtt主题订阅流程;(2)输入消息队列的接收接口有connack返回,调用mqtt数据帧解码函数,得到服务器端返回的拒绝连接或其他错误码,如:用户id错误、用户令牌错误、用户授权超期等,此时mqtt主线程将打印相关错误提示并挂起;(3)输入消息队列的接收接口无数据返回,mqtt主线程将输出相关超时错误打印,并调用网络实例“断开连接”的回调函数断开本次socket连接,然后回到“mqtt_state_con”状态的起始语句重新开始执行。
114.mqtt主题订阅函数:与mqtt协议客户端连接流程类似,主处理线程将根据初始化
的客户端实例结构中预置主题过滤器主题(topic),调用报文编帧函数组织“subscribe”的报文并通过输出消息队列发送。同样的在输入消息队列的接收接口计时等待,仍可能存在三种结果:(1)mqtt接收线程返回“suback”类型报文指示订阅成功,此时mqtt主线程将输出相关打印信息并继续进行后续流程执行;(2)mqtt接收线程返回suback报文,但解码得到相应错误码指示“订阅失败”,此时mqtt主处理线程将输出相关打印信息并调用已初始化的mqtt订阅失败回调处理函数将失败信息通知上层用户应用;(3)定时到时后仍无数据返回,可选的,此时mqtt主线程输出相关错误打印,并调用mqtt客户端断开连接函数,向服务器端发送“disconnect”类型报文,然后回到“mqtt_state_con”状态的起始语句重新开始执行,并且重新执行时由于检测到网络socket连接状态位仍保持为1,mqtt发送、接收线程已经启动,则跳过socket连接步骤和发送、接收线程启动步骤。
[0115]“心跳请求”启动函数:当主线程完成了主题订阅后将启动客户端“心跳保持”定时器,心跳定时器在初始化流程已初始化,按照客户端实例预置的心跳间隔时间设置为循环定时器,当发送或接收线程每完成一次报文发送或接收后,将重置该定时器。
[0116]
mqtt客户端完成与服务器端协议层连接后,主处理线程将自身状态转到“mqtt_state_keep”即“状态保持”状态。
[0117]
接下来参见图7a、图7b、图7c所示,为本发明实施例提供的一种mqtt主线程保持状态执行流程图。
[0118]
图7a中,包括以下步骤:
[0119]
步骤71a:mqtt_state_keep。
[0120]
步骤72a:输入消息队列消息接收。
[0121]
步骤73a:自定义消息头解析。
[0122]
步骤74a:保持接收。
[0123]
步骤75a:报文解析。
[0124]
步骤76a:判断是否为允许类型报文。若否,则执行步骤77a,若是,则执行步骤78a。
[0125]
步骤77a:丢弃报文。并重新执行步骤72a。
[0126]
步骤78a:判断是否存在对端应答报文,若是,则执行步骤79a、步骤710a或步骤711a中的一个步骤或多个步骤,若否,则执行步骤721a或者步骤722a中的一个步骤或多个步骤。
[0127]
步骤79a:判断对端报文为pubrec报文,执行步骤712a以及步骤713a。
[0128]
步骤712a:将pid对应定器重置。
[0129]
步骤713a:生成pubrel报文,发送到输出消息队列。并再次执行步骤72a。
[0130]
步骤710a:判断对端报文为pingresp报文,执行步骤714a。
[0131]
步骤714a:清除心跳已发送位。并重新执行步骤72a。
[0132]
步骤711a:判断对端报文为其他应答报文,执行步骤715a。
[0133]
步骤715a:关闭pid对应定时器。
[0134]
步骤716a:判断是否返回错误码,若是,则执行步骤717a,若否,则执行步骤719a。
[0135]
步骤717a:清除已记录的pid和mid。
[0136]
步骤718a:对用户层返回错误码和mid号。并重新执行步骤72a。
[0137]
步骤719a:清除已记录的pid和mid。
[0138]
步骤720a:对用户层返回发送成功的mid号。
[0139]
步骤721a:判断为publish报文,则执行步骤723a。
[0140]
步骤723a:判断是否为是否qos2报文,若是则执行步骤724a,若否,则执行步骤726a。
[0141]
步骤724a:生成pubrec报文,发送到输出消息队列。
[0142]
步骤725a:启动发送定时器并记录pid。并重新执行步骤72a。
[0143]
步骤726a:生成puback报文,发送到输出消息队列。并重新执行步骤72a。
[0144]
步骤722a:判断为pubrel报文。执行步骤727a。
[0145]
步骤727a:关闭pid对应定时器。
[0146]
步骤728a:生成pubcomp报文,发送到输出消息队列。并重新执行步骤72a。
[0147]
接下来参见图7b,包括以下步骤:
[0148]
步骤71b:mqtt_state_keep。
[0149]
步骤72b:输入消息队列消息接收。
[0150]
步骤73b:自定义消息头解析。
[0151]
步骤74b:保持发送。
[0152]
步骤75b:判断是否存在心跳请求事件。若否,则执行步骤77b,若是,则执行步骤76b。
[0153]
步骤77b:生成发布、订阅或退订报文。
[0154]
步骤78b:发送报文到输出消息队列。
[0155]
步骤79b:启动发送定时器并记录pid和mid。并执行步骤710b以及重新执行步骤72b。
[0156]
步骤76b:生成pingreq报文。
[0157]
步骤712b:发送报文到输出消息队列。
[0158]
步骤713b:置位心跳请求已发送状态位。并执行步骤714b以及重新执行步骤72b。
[0159]
步骤710b:判断是否有发送定时器超时,若是,则执行步骤711b,若否,则执行步骤72b。
[0160]
步骤711b:生成发送超时事件到输入消息队列,并注入pid和mid。
[0161]
步骤714b:判断心跳定时器到时是否有心跳请求置位,若是,则执行步骤715b,若否,则执行步骤716b。
[0162]
步骤715b:生成心跳超时事件到输入消息队列。
[0163]
步骤716b:生成心跳请求事件到输入消息队列,并重新执行步骤72b。
[0164]
接下来参见图7c,包括以下步骤:
[0165]
步骤71c:mqtt_state_keep。
[0166]
步骤72c:输入消息队列消息接收。
[0167]
步骤73c:自定义消息头解析。
[0168]
步骤74c:错误处理。
[0169]
步骤75c:判断是否发布、订阅和退订超时错误。若是,则执行步骤76c,若否,则执行步骤77c。
[0170]
步骤76c:记录超时报文mid。
[0171]
步骤78c:关闭、清空输入、输出消息队列。
[0172]
步骤79c:清除已订阅主题,清除客户端相关信息。
[0173]
步骤710c:断开socket网络连接。
[0174]
步骤711c:对用户层返回未完成mid号和错误信息。
[0175]
步骤712c:mqtt_state_con。
[0176]
步骤77c:判断遍历发送记录和输入消息队列是否能获得一个mid,若是,则执行步骤76c,若否,则执行步骤78c。
[0177]
接下来,对图7a至图7c作进一步说明。在保持状态下,包括如下步骤和模块:
[0178]
输入消息队列的输出接口:该接口以阻塞式实现,当输入消息队列为空时,mqtt主处理线程即进入阻塞。
[0179]
自定义消息头解析函数:由于消息队列中的“消息”(数据)对应于多种可能的“事件”,在每个消息头部自定义1byte的消息类型及消息id字段(mid)。可选的,消息类型包括:发布事件、心跳请求事件、订阅事件、退订事件、接收事件、心跳超时事件、发送超时事件、发送失败事件、接收失败事件,该字段占用自定义消息头的低4bit。消息id(mid)只针对上层用户层下发的发布、订阅、退订事件,以进行区分,占用自定义消息头的高4bit。即本设计客户端输入消息队列可同时容纳的用户层待发送消息最多为16条(不包括其它消息)。消息头解析函数解析消息类型后,通过条件选择转入不同的处理模块进行处理。
[0180]
mqtt协议客户端保持发送函数:该函数需要处理的事件为mqtt主题发布事件、mqtt主题订阅事件、mqtt主题退订事件和心跳请求事件。对于mqtt主题发布,可选的,该事件由用户应用程序输入消息队列,或者可同时支持由shell命令输入。当输入消息队列消息类型为“发布事件”时,转入本函数处理;调用报文编帧函数按mqtt协议报文格式要求将收到待发布数据组织成“publish”的报文并存入客户端实例的发送缓存区;调用输出消息队列输入接口将发送缓存区内报文发到输出消息队列;对于服务质量qos0的publish报文无需服务器端返回应答,而对于qos1、qos2的报文需要返回应答。可选的,对于上层应用实现为异步io模式,在每个qos1、qos2等级报文发送到消息队列后,启动一个发送定时器,该定时器是在初始化中已经过初始化的,并记录报文的报文标识符“packet identifier”(pid)和用户应用自定义消息id号(mid)。在定时器到时前如果服务器端返回了“puback”报文(对qos1),或“pubrec”报文(对qos2),则关闭并清除相关记录信息或延时(对pubrec报文)该发送定时器。如果定时器到时无报文返回,则调用超时回调函数向输入消息队列发送一个“发送超时事件”,并注入pid和mid,主处理线程会转入错误处理模块进行处理。
[0181]
特殊的,当心跳定时器到时时,会产生一个“心跳请求事件”注入mqtt主线程输入消息队列,mqtt主线程会将其当作一个特殊的“发布事件”在保持发送函数中处理:调用编帧函数按协议格式生成一个pingreq报文,并发到输出消息队列。置位心跳指示状态位表明“心跳请求已发送”,如果在下一个心跳定时器到时前,服务器端返回了pingresp“心跳请求响应”报文,则清除“心跳请求已发送”位。否则调用超时回调函数向输入消息队列发送一个“心跳超时事件”,mqtt主线程则会转入错误处理模块进行处理。
[0182]
特殊的,当客户端需要重新订阅或退订主题时,mqtt主线程也会将其当作一个特殊的“发布事件”在保持发送函数中处理:可选的,支持由用户应用程序将订阅和退订行为输入消息队列,或者由shell命令输入。调用报文编帧函数生成subscribe或unsubscribe报
文,并发到输出消息队列;同时启动对应的发送定时器并记录报文标识符pid和自定义mid号。如果定时器到时前,服务器端返回了对应的suback或unsuback报文,则清除定时器和相关记录信息,否则调用超时回调函数向输入消息队列发送一个“订阅(/退订)错误事件”,并注入pid和mid,主处理线程转入错误处理模块进行处理。
[0183]
mqtt协议客户端保持接收函数:当mqtt接收线程接收到网络上到来的mqtt报文,生成“报文接收事件”消息头合成接收报文,并发送到输入消息队列后;消息头解析函数通过识别消息头类型发现是“接收事件”时,转入本函数进行处理。调用报文解码函数按mqtt协议报文格式要求将收到的报文解码为相关数据并存入客户端实例的接收缓存区。在此处,保持接收函数可能收到的报文类型有:主题发布publish、发布确认puback、发布收到pubrec、发布释放pubrel、发布完成pubcomp、心跳响应pingresp、消息订阅应答suback、取消订阅确认unsuback,对非以上类型报文视为非法报文进行丢弃,可选的:对publish类型报文:将其主题(topic)与初始化定义的主题过滤器(topic_filter)主题进行比较,如有相符的主题,则调用初始化定义的对应主题订阅回调函数进行处理。接着调用报文编帧函数生成一个puback类型(对于qos1),如果publish报文是qos2等级,则生成pubrec类型报文发到输出消息队列中,同时启动一个发送定时器,并记录报文标识符pid,以判断接收后续的pubrel报文。
[0184]
对puback类型报文:将其报文标识符pid对应的发送定时器关闭,并清除已记录的pid和mid号。可选的,对上层应用需要实现为同步通信的情况,可预先注册“应答成功”回调处理函数,在清除对应pid和mid前,将mid号返回上层应用。
[0185]
对pubrec类型报文:将其报文标识符pid对应的发送定时器重置,并调用报文编帧函数生成一个pubrel类型报文,发到输出消息队列中。
[0186]
对pubrel类型报文:将其报文标识符pid对应的发送定时器关闭(该定时器是在之前发送pubrec报文时启动的),并清除记录的pid号,调用报文编帧函数生成一个pubcomp类型报文,发到输出消息队列中。
[0187]
对pubcomp类型报文:将其报文标识符pid对应的发送定时器关闭,并清除记录的pid和mid号;可选的,对上层应用需要实现为同步通信的情况,可预先注册“应答成功”回调处理函数,在清除对应pid和mid前,将mid号返回上层应用。
[0188]
对pingresp类型报文:将客户端全局“心跳请求已发送”状态位清除。
[0189]
对suback类型报文:其报文包含返回码,可能指示“订阅成功”或指示“订阅失败”,将其报文标识符pid对应的发送定时器关闭,并清除记录的pid和mid号。可选的,预先注册“应答成功”回调处理函数,在清除对应pid和mid前,将返回码和mid号返回上层应用。
[0190]
对unsuback类型报文:其报文包含返回码,可能指示“退订成功”或指示“退订失败”,将其报文标识符pid对应的发送定时器关闭,并清除记录的pid和mid号。可选的,预先注册“应答成功”回调处理函数,在清除对应pid和mid前,将返回码和mid号返回上层应用。
[0191]
以上各类型报文处理流程中,如果定时器到时无报文返回,则定时器线程会自动调用超时回调函数向输入消息队列发送一个相关类型“错误事件”和“错误码”。可选的,错误事件在消息队列中可按优先级排队,即消息队列优先输出“错误事件”,主处理线程收到后则会转入错误处理模块进行处理。
[0192]
错误处理函数:错误事件分为发送、接收线程调用返回错误和服务器端应答超时
两大类。可选的,为了简化设计,对这两大类错误都统一重置客户端,并通知上层用户应用,由用户应用层自行处理消息重发策略。执行流程如下,首先调用定时器关闭函数关闭当前所有计时的定时器,对于应答超时中报文为publish、subscribe或unsubscribe的情况,mqtt主线程保持发送模块会记录报文对应的mid号,此时,错误处理函数会查询该mid号。对于其他错误,错误处理函数会依次遍历已记录的发送定时器及对应mid,如果未找到任何mid号,则再遍历输入消息队列中所有消息头中的mid号,并获得第一个找到的mid号(或者未获得任何mid号)。之后调用消息队列关闭函数,清空和关闭当前主线程输入和输出消息队列,并清除已订阅的mqtt消息主题,清除客户端实体的连接和心跳指示状态位,调用网络实例的断开连接回调函数断开socket连接。最后调用上层用户应用注册的错误处理回调函数,通知其相关错误信息和错误发生时未完成事件的mid号,最后将主线程状态置为“mqtt_state_con”,并重新执行连接流程。
[0193]
接下来,参见图8。基于与上述信息处理方法相同的技术构思,本发明的另一实施例提供了一种信息处理装置,所述信息处理装置所达到的效果与上述方法达到的效果类似,此处不再赘述。
[0194]
本发明实施例提供的信息处理装置,包括:确定模块81,用于确定不存在对应于消息队列遥测传输mqtt协议客户端的第一线程的输入信息;
[0195]
控制模块82,用于控制所述第一线程进入阻塞状态,释放所述第一线程所占用的处理器时间片;
[0196]
控制模块82,还用于利用释放的所述处理器时间片,执行除所述第一线程外的其他线程。
[0197]
本发明实施例提供的信息处理装置,在所述第一线程为主线程时,所述输入信息为输入消息队列中的信息;在所述第一线程为发送线程时,所述输入消息为输出消息队列中的信息;在所述第一线程为接收线程时,所述输入消息为服务器发出的消息;其中,所述输入消息队列中包括输入至所述主线程的信息,所述输出消息队列包括经过所述主线程处理,并输入至所述发送线程的信息。
[0198]
本发明实施例提供的信息处理装置,控制模块82,在控制所述第一线程进入阻塞状态之后,还用于:在监听到对应于所述消息队列遥测传输mqtt协议客户端的第一线程的输入信息时,控制所述第一线程由所述阻塞状态更新为唤醒状态。
[0199]
本发明实施例提供的信息处理装置,控制模块82还用于:采用异步通信方式与服务器进行通信。
[0200]
本发明实施例提供的信息处理装置,控制模块82,在所述采用异步通信方式与服务器进行通信时,具体用于:通过发送线程向所述服务器发送第一数据信息,以及,通过接收线程接收所述服务器反馈的第二数据信息,其中所述发送线程和所述接收线程采用异步工作模式。
[0201]
本发明实施例提供的信息处理装置,确定模块81还用于:根据目标参数,确定目标通信方式;其中,所述目标通信方式用于与服务器进行通信,所述目标通信方式为同步通信方式或者异步通信方式。
[0202]
本发明的又一实施例提供了一种电子设备,包括:处理器、存储器及存储在所述存储器上并可在所述处理器上运行的程序,所述程序被所述处理器执行时实现如上所述的信
息处理方法,且能达到相同的技术效果,为避免重复,此处不再赘述。
[0203]
本发明的另一优选实施例还提供了一种计算机可读存储介质,计算机可读存储介质上存储计算机程序,计算机程序被处理器执行时,实现如上所述的信息处理方法的步骤,且能达到相同的技术效果,为避免重复,此处不再赘述。
[0204]
此外,本发明可以在不同例子中重复参考数字和/或字母。这种重复是为了简化和清楚的目的,其本身不指示所讨论各种实施例和/或设置之间的关系。
[0205]
还需要说明的是,在本文中,诸如第一和第二等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含。
[0206]
以上所述是本发明的优选实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明所述原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也应视为本发明的保护范围。
再多了解一些

本文用于创业者技术爱好者查询,仅供学习研究,如用于商业用途,请联系技术所有人。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献