当前位置:   article > 正文

学习open62541 --- [72] client删除subscription时的warning_badnosubscription

badnosubscription

本文记录一个问题的理解过程,试验条件:

  • 使用open62541运行server
  • 使用asyncua运行client
  • client会向server添加subscription,然后在断开连接前删除subscription

代码和理解

server端基于open62541

// server.c
#include "open62541.h"

#include <signal.h>
#include <stdlib.h>

UA_Boolean running = true;

static void stopHandler(int sign) {
    UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "received ctrl-c");
    running = false;
}

int main(void) 
{
    signal(SIGINT, stopHandler);
    signal(SIGTERM, stopHandler);

    UA_Server *server = UA_Server_new();
    UA_ServerConfig_setDefault(UA_Server_getConfig(server));

    UA_StatusCode retval = UA_Server_run(server, &running);
    
    UA_Server_delete(server);
    
    return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

Client代码是基于asyncua,

当删除subscription时,在client端会收到一个warning,
在这里插入图片描述

在open62541里对这个错误进行搜索,即UA_STATUSCODE_BADNOSUBSCRIPTION,找到相关代码,如下,

void
UA_Session_detachSubscription(UA_Server *server, UA_Session *session,
                              UA_Subscription *sub, UA_Boolean releasePublishResponses) {
    /* Detach from the session */
    sub->session = NULL;
    TAILQ_REMOVE(&session->subscriptions, sub, sessionListEntry);

    /* Reduce the count */
    UA_assert(session->subscriptionsSize > 0);
    session->subscriptionsSize--;

    /* Reduce the number of outstanding retransmissions */
    session->totalRetransmissionQueueSize -= sub->retransmissionQueueSize;
    
    /* Send remaining publish responses if the last subscription was removed */
    if(!releasePublishResponses || !TAILQ_EMPTY(&session->subscriptions))
        return;
    UA_PublishResponseEntry *pre;
    while((pre = UA_Session_dequeuePublishReq(session))) {
        UA_PublishResponse *response = &pre->response;
        response->responseHeader.serviceResult = UA_STATUSCODE_BADNOSUBSCRIPTION;
        response->responseHeader.timestamp = UA_DateTime_now();
        sendResponse(server, session, session->header.channel, pre->requestId,
                     (UA_Response*)response, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]);
        UA_PublishResponse_clear(response);
        UA_free(pre);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

具体原理如下,当client删除subscription时,会发送删除请求,server收到请求后会调用UA_Session_detachSubscription(),代码里会判断这个subscription是否是最后一个subscription,如果是那么就会把剩余的response发送出去,并把这个response的状态置为UA_STATUSCODE_BADNOSUBSCRIPTION

可以看出这个是正常的操作,本文代码里只有一个subscription,所以删除时就会把剩余的response都发出去;但是如果有多个subscription,此时只删除一个subscription就不会收到这个warning。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/982191
推荐阅读
相关标签
  

闽ICP备14008679号