当前位置: 代码迷 >> 综合 >> wayland client调用server的api方法后出错、掉线、程序退出UI消失的问题
  详细解决方案

wayland client调用server的api方法后出错、掉线、程序退出UI消失的问题

热度:78   发布时间:2023-12-11 22:53:33.0

本人博客已经迁移到nasdaqgodzilla.github.io

文章目录

  • 本人博客已经迁移到[nasdaqgodzilla.github.io](https://nasdaqgodzilla.github.io)
  • 概述
  • 原因
    • wayland server对socket中的client数据的处理、方法调用的响应
  • 解决方案
    • 临时解决-特别是快速调试和测试的时候
    • 解决

概述

  • wayland server提供了由wayland协议文件定义的接口,client通过绑定这些接口后即可调用server的方法。
  • 在使用google提供的wayland接口协议(/wayland-protocols/unstable/remote-shell)的时候,client完成对server资源的绑定后,调用remote_shellSetFrame方法,调用完成后发现没有效果,并且在client发现与server的连接已经断开,通过调试手段发现server已经不再处理该client的方法调用以及surface_commit()

原因

wayland server对socket中的client数据的处理、方法调用的响应

  • server在src/wayland-server.c中的方法 wl_client_connection_data()对socket中client发过来的数据进行解析(反序列化)和处理。
  • 在解析数据完成后,会调用客户端请求的方法。下面的closure就是即将调用的方法,通过invoke方法进行调用,原理是利用了ffi库进行调用。
        message = &object->interface->methods[opcode];since = wl_message_get_since(message);if (!(resource_flags & WL_MAP_ENTRY_LEGACY) &&resource->version > 0 && resource->version < since) {wl_resource_post_error(client->display_resource,WL_DISPLAY_ERROR_INVALID_METHOD,"invalid method %d (since %d < %d)"", object %s@%u",opcode, resource->version, since,object->interface->name,object->id);break;}closure = wl_connection_demarshal(client->connection, size,&client->objects, message);if (closure == NULL && errno == ENOMEM) {wl_resource_post_no_memory(resource);break;} else if (closure == NULL ||wl_closure_lookup_objects(closure, &client->objects) < 0) {wl_resource_post_error(client->display_resource,WL_DISPLAY_ERROR_INVALID_METHOD,"invalid arguments for %s@%u.%s",object->interface->name,object->id,message->name);wl_closure_destroy(closure);break;}log_closure(resource, closure, false);if ((resource_flags & WL_MAP_ENTRY_LEGACY) ||resource->dispatcher == NULL) {wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER,object, opcode, client);} else {wl_closure_dispatch(closure, resource->dispatcher,object, opcode);}wl_closure_destroy(closure);
  • 调用失败的重点:在解析socket数据之前,会对client发过来的消息进行版本判断,如果检测到client的版本低于server要求的最低版本(即代码中的since),那么server就会通过wl_resource_post_error来终止对该client的处理,并且会释放掉这个client相关的资源。故client会发现在调用一些方法后与server的连接会掉线,其原因就在于server认定版本不符合要求,主动断开了连接。

解决方案

临时解决-特别是快速调试和测试的时候

  • 如果能修改server的代码,直接在上面这个文件(wayland-server.c)将起始版本(since)修改为1,这样肯定不会被server认定版本不对而拒绝调用。强制调用会不会出问题就不知道了,反正在remote_shell``协议中强制调用它的SetFrame```并不会出什么问题。

解决

  • 将server和client的协议文件统一一下,并且重新生成接口和实现,统一版本。
  相关解决方案