Para el desarrollo y compilación de MEGAchat , utilizamos principalmente CMake como herramienta de configuración de proyectos multiplataforma. También utilizamos VCPKG para gestionar las dependencias necesarias para crear MEGAchat en la mayoría de las plataformas: Windows, MacOS y Linux.
Para obtener detalles sobre las herramientas de construcción necesarias para cada sistema operativo, revise el capítulo Herramientas de construcción en el repositorio de MEGA SDK.
Más información para la compilación WebRTC Android en WebRTC para Android
MEGAchat requiere algunas dependencias para funcionar. La mayoría de ellos se descargan y crean automáticamente utilizando VCPKG durante la fase de configuración.
Para Linux, se necesitan algunas bibliotecas adicionales en el sistema para que VCPKG pueda crear las dependencias. Para distribuciones basadas en Debian, puede instalar las bibliotecas necesarias usando el siguiente comando:
sudo apt install python3-pkg-resources libglib2.0-dev libgtk-3-dev libasound2-dev libpulse-dev
Los nombres de los paquetes pueden variar para diferentes distribuciones de Linux, pero debería compilarse correctamente con paquetes que proporcionen las mismas bibliotecas.
Puede consultar el conjunto completo de dependencias en el archivo vcpkg.json en la raíz del repositorio.
MEGAchat también necesita la biblioteca MEGA SDK. Más adelante en este documento encontrará instrucciones sobre cómo utilizarlo con MEGAchat . El proyecto MEGA SDK lo carga automáticamente MEGAchat CMake, por lo que solo tienes que clonarlo en la ruta esperada.
Sólo hay una dependencia opcional adicional que debe instalarse en el sistema: Qt Framework. Solo es necesario crear la aplicación Qt de ejemplo, pero no es necesario para las pruebas, el ejemplo CLI ni la biblioteca en sí.
Primero que nada, prepara un directorio de tu elección para trabajar con MEGAchat . El mega
se utilizará como directorio del espacio de trabajo en los ejemplos de este documento.
mkdir mega
cd mega
Después de preparar el directorio, clone el repositorio de MEGAchat para obtener el código fuente MEGAchat .
git clone https://github.com/meganz/MEGAchat
Como MEGAchat requiere el MEGA SDK para funcionar, clone el MEGA SDK en la ruta esperada.
git clone https://github.com/meganz/sdk MEGAchat/third-party/mega
Finalmente, clona el repositorio VCPKG al lado de la carpeta MEGAchat . Si ya está usando VCPKG y tiene un clon local del repositorio, puede omitir este paso y usar el VCPKG existente en su sistema.
git clone https://github.com/microsoft/vcpkg
Las siguientes instrucciones son para configurar el proyecto desde la interfaz de línea de comandos (CLI), pero cmake-gui o cualquier editor o IDE compatible con CMake deberían ser adecuados si se configuran los mismos parámetros de CMake.
MEGAchat está configurado como cualquier otro proyecto CMake normal. El único parámetro que siempre se necesita es el directorio VCPKG para administrar las dependencias de terceros. La dependencia de MEGA SDK se crea como parte de la compilación MEGAchat .
Para configurar MEGAchat , desde el espacio de trabajo ( mega
directorio), ejecute CMake:
cmake -DVCPKG_ROOT=vcpkg -DCMAKE_BUILD_TYPE=Debug -S MEGAchat -B build_dir
Nota 1 : Es posible que -DCMAKE_BUILD_TYPE=<Debug|Release>
no sea necesario para generadores multiconfiguración, como Visual Studio.
Nota 2 Si Qt Framework está instalado en su sistema pero CMake no lo detecta, puede agregar -DCMAKE_PREFIX_PATH=</path/to/qt/install/dir>
para que CMake pueda localizarlo. Si Qt no está instalado y prefiere no instalarlo, puede desactivar la aplicación de ejemplo Qt configurando -DENABLE_CHATLIB_QTAPP=OFF
. La biblioteca, el ejemplo de CLI y las pruebas aún se construirán.
En el comando cmake anterior, se han utilizado rutas relativas para simplificar. Si desea cambiar la ubicación de VCPKG, MEGAchat o el directorio de compilación, simplemente proporcione una ruta relativa o absoluta válida para cualquiera de ellos.
Durante la configuración del proyecto, VCPKG creará y configurará las bibliotecas necesarias para la plataforma. Puede que la primera ejecución tarde un poco, pero una vez creadas las bibliotecas, VCPKG las recuperará del caché binario.
MEGAchat se puede configurar con diferentes opciones, algunas de las cuales se pueden encontrar en el archivo chatlib_options.cmake. Las opciones para administrar los ejemplos y pruebas se encuentran en CMakeLists.txt.
Una vez que MEGAchat esté configurado, simplemente cree el proyecto completo:
cmake --build build_dir
Puede especificar --target=<target>
como CHATlib
o megaclc
, o simplemente dejar el comando como está para crear todas las etiquetas. Además, se puede agregar -j <N>
o --parallel <N>
para administrar la concurrencia y acelerar la compilación.
Una vez finalizada la compilación, los archivos binarios estarán disponibles en build_dir
, que se especificó en el comando de configuración de CMake.
Para abstraer la complejidad del código, MEGAchat proporciona una capa intermedia que permite crear rápidamente nuevas aplicaciones.
La documentación está disponible en src/ MEGAchat api.h
El modelo de subprocesos MEGAchat es similar al modelo de subprocesos de JavaScript: todo se ejecuta en el subproceso principal (GUI), nunca se permite el bloqueo y los eventos externos (red, temporizadores, etc., eventos webrtc, etc.) activan devoluciones de llamadas en el subproceso principal. Para que esto funcione, MEGAchat debe poder interactuar con el bucle de eventos de la aplicación; este suele ser el bucle de eventos/mensajes del marco GUI en el caso de una aplicación GUI, o un bucle de mensajes personalizado en el caso de una aplicación de consola. Como este bucle de mensajes es muy específico de la plataforma, es responsabilidad del desarrollador de la aplicación implementar la interfaz entre este y MEGAchat . Esto puede parecer más complicado de lo que es en realidad: la interfaz consta de dos partes. Una parte es la implementación de la función megaPostMessageToGui(void*)
, que publica un puntero void*
opaco en el bucle de mensajes de la aplicación. Esta función normalmente es llamada por subprocesos distintos del hilo principal, pero también puede ser llamada por el propio subproceso de la GUI. La otra parte es el código en el bucle de mensajes de la aplicación que reconoce este tipo de mensajes y los devuelve a MEGAchat , llamando a megaProcessMessage(void*)
con ese mismo puntero, esta vez en el contexto del hilo principal (GUI). Todo esto se implementa en /src/base/gcm.h
y /src/base/gcm.hpp
. Estos archivos contienen documentación detallada. Un ejemplo de implementación de esto en Windows es: megaPostMessageToGui(void*)
haría un PostMessage()
con un tipo de mensaje de usuario y void*
como lParam o wParam del mensaje, y en la declaración switch
de procesamiento de eventos, habrá una entrada para ese tipo de mensaje, obteniendo el puntero void*
emitiendo el lParam o wParam del mensaje y pasándolo a megaProcessMessage(void*)
.
MEGAchat se basa en libuv, que se ejecuta en su propio subproceso dedicado, para monitorear múltiples sockets en busca de eventos de E/S sin procesar e implementar temporizadores. También se basa en la funcionalidad de E/S de nivel superior de libuv, como la resolución DNS y los sockets SSL. Una capa delgada encima de libuv, llamada 'servicios' ( /src/base/?services*.*
) se implementa encima de libuv y GCM para tener API C++ 11 asíncronas simples, similares a javascript, para temporizadores. ( src/base/timer.h
), resolución DNS ( /src/base/services-dns.hpp
), cliente http ( /src/base/services-http.hpp
). Esta capa se diseñó originalmente para tener un componente de nivel inferior con una interfaz C simple (archivos cservices*.cpp/h
), de modo que los servicios puedan ser utilizados por varias DLL creadas con diferentes compiladores y un encabezado C de alto nivel. ++11 capa que es la interfaz y contiene la API pública: estos son los archivos .hpp.
Todas las bibliotecas de red en MEGAchat (libcurl) usan libuv para el funcionamiento de la red y los temporizadores (las bibliotecas C usan libuv directamente, el código C++ usa la capa C++ 11, es decir, timers.hpp
). Se recomienda encarecidamente que el usuario del SDK también haga lo mismo, aunque es posible, por ejemplo, tener un subproceso de trabajo dedicado que bloquee un socket y publique eventos en el subproceso de la GUI a través del GCM.
El patrón de uso es el siguiente: se registra una devolución de llamada para un determinado evento (evento de E/S de socket, temporizador, etc.), y el hilo libuv llama a esa devolución de llamada cuando ocurre el evento. Si el evento puede propagarse fuera de la biblioteca cuya devolución de llamada se llama, y especialmente a la GUI, entonces, en algún momento, el procesamiento de eventos debe dirigirse al subproceso de la GUI, utilizando el mecanismo GCM. Sin embargo, si el evento es interno y nunca se propaga fuera de la biblioteca, entonces se puede manejar directamente en el contexto del hilo libuv (siempre que nunca lo bloquee). Esto ahorra el costo de rendimiento de enviarlo al subproceso de la GUI y se recomienda si el evento ocurre con una frecuencia alta, por ejemplo, un evento de fragmento de datos entrante que solo necesita que los datos se agreguen a un búfer. Cuando se completa la transferencia, se puede organizar un evento de finalización en el subproceso de la GUI una vez por transferencia, combinando las ventajas de ambos enfoques.
MEGAchat tiene una función de registro avanzada que admite el registro de archivos y consola con color, rotación de archivos de registro y múltiples canales de registro, cada uno con un nivel de registro individual. Los niveles de registro se configuran en tiempo de ejecución (al inicio) y no en tiempo de compilación (es decir, no deshabilitando las macros de registro). Esto permite que una aplicación creada en el lanzamiento habilite el registro de depuración completo para cualquier canal. Los canales de registro se definen y configuran de forma predeterminada en src/base/loggerChannelConfig.h. El expediente contiene documentación detallada. Para mayor comodidad, las macros de registro dedicadas para cada canal generalmente se definen en el código que las utiliza; consulte las macros XXX_LOG_DEBUG/WARN/ERROR en karereCommon.h para ver ejemplos. El usuario del SDK es libre de crear canales de registro adicionales si es necesario. Ya está definido un canal de registro de GUI. La configuración del canal de registro se puede anular en tiempo de ejecución mediante la variable de entorno KRLOG. Su formato es el siguiente:
KRLOG=<chan name>=<log level>,<chan name2>=<log level2>...
Los niveles de registro son "desactivado", "error", "advertencia", "información", "detallado", "depuración", "debugv".
Hay un nombre de canal especial: "todos". Configurar el nivel de registro de este canal configura los niveles de registro de todos los canales. Esto permite, por ejemplo, silenciar fácilmente todos los canales excepto uno (o algunos), mediante:
KRLOG=all=warn,mychannel=debug,myotherchannel=info
El mismo canal se puede configurar varias veces y solo la última configuración será efectiva, lo que hace posible el truco anterior.
MEGAchat requiere que la aplicación defina la función karere::getAppDir()
en el momento de la compilación, para saber dónde crear el archivo de registro y comenzar a registrar lo antes posible, antes de ingresar main()
. Si MEGAchat está construido como una biblioteca estática, esto no es un problema. En el caso de la biblioteca dinámica, esta función tiene que ser un símbolo débil, para que MEGAchat pueda compilarse sin la implementación de la función, y la implementación se vincule cuando la biblioteca compartida MEGAchat se cargue al inicio de la aplicación. Los símbolos débiles no son realmente transferibles entre compiladores y esto puede ser un problema. Sin embargo, son compatibles tanto con gcc como con clang. Si no se admiten símbolos débiles, karer e debe construirse como una biblioteca estática.
base/promise.h
y su uso de ejemplo, por ejemplo, en /src/test-promise.cpp
setTimeout()
y setInterval()
en /src/base/timers.hpp
marshallCall()
ordena las llamadas lambda desde un subproceso de trabajo al subproceso de la GUI. Se pueden ver ejemplos de uso, por ejemplo, en /src/webrtcAdapter.h
y en muchos lugares diferentes. Este mecanismo no debería ser necesario directamente en el código de alto nivel que se ejecuta en el subproceso de la GUI./src/chatClient.h;.cpp
megaPostMessageToGui()
, cómo iniciar los 'servicios' y cómo crear una instancia del cliente MEGAchat . También muestra cómo implementar el método getAppDir()
, que es un símbolo débil que necesita la biblioteca MEGAchat para crear el archivo de registro y comenzar a registrar lo antes posible, antes de ingresar main()
.src/rtcModile/IRtcModule.h
y encabezados relacionadosmegaPostMessageToGui()
, pero puede tener cualquier nombre, siempre que la firma sea extern "C" void(void*)
. Esta función es el corazón del mecanismo de transmisión de mensajes (llamado Gui Call Marshaller o GCM) en el que se basa MEGAchat . Debe pasar un puntero a esta función a services_init()
.