Introduccion
Desafortunadamente, incluso ahora, en el mundo moderno, no siempre es posible aprovechar los beneficios
de la tecnología push y, a veces, es necesario implementar soluciones alternativas, por ejemplo, en forma de Long Poll, que le permite emular el mecanismo de las notificaciones push. En particular, surgió tal necesidad al implementar
el cliente VKontakte para el sistema operativo Sailfish .
Este artículo no analizará los principios de interacción con el servidor Long Poll VKontakte: tiene
documentación muy detallada y ya se han publicado ejemplos básicos
anteriormente . En cambio, se considerará una implementación práctica para una plataforma específica.
Se entiende que el lector está familiarizado con el desarrollo del sistema operativo Sailfish no solo en
QML , sino también en
C ++ .
Encuesta larga al cliente
La clase de cliente principal es la clase
LongPoll
, que consulta el servidor Long Poll y analiza sus respuestas.
El método
getLongPollServer
, cuya tarea es obtener información para abrir una conexión con el servidor, se llama durante la inicialización de la aplicación, lo que le permite recibir actualizaciones de usuario de inmediato:
void LongPoll::getLongPollServer() { QUrl url("https://api.vk.com/method/messages.getLongPollServer");
Si la solicitud se completa con éxito, la información de conexión con el servidor Long Poll se guarda y la conexión se abre utilizando el método
doLongPollRequest
:
void LongPoll::finished(QNetworkReply* reply) { QJsonDocument jDoc = QJsonDocument::fromJson(reply->readAll());
En el método
doLongPollRequest
Long Poll, los parámetros de conexión necesarios se pasan al servidor:
void LongPoll::doLongPollRequest() { QUrl url("https://" + _server);
Vale la pena señalar que el valor del campo de
mode
, igual a 10, se obtuvo agregando la opción de recibir archivos adjuntos (2) y devolviendo un conjunto extendido de eventos (8).
Como respuesta a la apertura de una conexión, el servidor devuelve un JSON que contiene los últimos eventos. La respuesta se procesa en el método
finished
:
void LongPoll::finished(QNetworkReply* reply) { QJsonDocument jDoc = QJsonDocument::fromJson(reply->readAll());
El campo
failed
en la respuesta puede tomar cuatro valores, pero solo uno de ellos, igual a uno, no requiere una solicitud repetida de información para conectarse al servidor Long Poll. Por esta razón, la condición se agregó al código.
jObj.value("failed").toInt() == 1
El método
parseLongPollUpdates
es un ciclo simple para todos los eventos entrantes con una verificación de su tipo:
enum LONGPOLL_EVENTS { NEW_MESSAGE = 4,
El código muestra que para cada nuevo evento Long Poll, el cliente envía una
señal que debe ser procesada por otra parte de la aplicación. El argumento de la señal no es el objeto del evento completo, sino solo sus partes necesarias. Por ejemplo, la señal
gotNewMessage
transmite solo el identificador de un nuevo mensaje, por el cual se
solicita su contenido completo:
void VkSDK::_gotNewMessage(int id) { _messages->getById(id); }
Como resultado de esta función de línea única
, se realiza una solicitud al servidor VKontakte para obtener información completa sobre el mensaje mediante su identificador con la
creación posterior
del objeto de este mensaje. En conclusión, se envía una señal asociada con la interfaz de usuario, transmitiendo datos sobre un nuevo mensaje, que se
muestra en el panel de notificaciones:
import QtQuick 2.0
Interfaz de diálogo
Ahora, según los principios de interacción del cliente con el servidor Long Poll y los principios de transferir la información recibida a la interfaz de usuario, podemos considerar un ejemplo de actualización de un
diálogo abierto.
Lo primero que llama la atención es el componente
Connections
:
Connections {
La ranura
onUserTyping
procesa el evento de un conjunto por el interlocutor del mensaje al mostrar la notificación correspondiente al usuario. Aquí, en el primer paso, se obtiene el identificador de la sala (la sala significa el término generalizado para diálogos y chats), y en la segunda etapa, se muestra una notificación si el identificador recibido y el identificador de la sala actual coinciden.
Vale la pena señalar que una notificación sobre un conjunto de mensajes se muestra durante diez segundos, si durante este tiempo no ha llegado un nuevo evento que activará la notificación nuevamente. Esto se logra usando el componente
Timer
:
Label {
El espacio
onSavedPhoto
responsable de procesar el final de la carga de imágenes en los mensajes, lo que está más allá del alcance del artículo actual.
La segunda cosa que es de interés es la lista de mensajes:
SilicaListView {
Aquí, el componente
MessageItem
es responsable de mostrar un solo mensaje. Su consideración está más allá del alcance de este artículo.
Los mensajes en sí se toman del modelo
vksdk.messagesModel
. Este modelo es una lista de objetos
Message
que se pueden actualizar en tiempo real mediante los métodos
add
,
addProfile
,
readMessages
,
readMessages
y
clear
:
void MessagesModel::clear() { beginRemoveRows(QModelIndex(), 0, _messages.size());
Común a los cinco métodos es el uso de la señal
dataChanged
, que indica que los datos se han actualizado en el modelo. La emisión de esta señal actualiza los elementos de
SilicaListView
para mostrar el estado actual de los mensajes. La adición de mensajes a
SilicaListView
realiza llamando a los
endInsertRows
beginInsertRows
y
endInsertRows
que envían las
rowsInserted
rowsAboutToBeInserted
y
rowsInserted
respectivamente. Como resultado, el usuario verá nuevos mensajes y su estado en tiempo real en el cuadro de diálogo.
Conclusión
Este artículo examinó la interacción con el servidor Long Poll al desarrollar para el sistema operativo Sailfish utilizando la aplicación VK como ejemplo. Se consideraron algunas características de la implementación del cliente y una forma de actualizar la interfaz de usuario en tiempo real. El código para la aplicación descrita en este artículo está
disponible en GitHub.