引言
不幸的是,即使在现在,在现代世界中,也并非总是能够利用
推送技术的优势
,有时有时有必要实施变通办法,例如以Long Poll的形式,它可以让您模仿推送通知的机制。 特别是在
为Sailfish OS实现
VKontakte客户端时出现了这种需求。
本文不会讨论与Long Poll VKontakte服务器进行交互的原理-它具有非常详细的
文档 ,并且基本示例已在
较早时发布。 相反,将考虑针对特定平台的实际实现。
据了解,读者不仅熟悉
QML中的Sailfish OS开发,还熟悉
C ++中的Sailfish OS
开发 。
长投票客户
主要客户端类是
LongPoll
类,该类查询Long Poll服务器并解析其响应。
在应用程序初始化期间调用
getLongPollServer
方法,其任务是获取信息以打开与服务器的连接,该方法使您可以立即接收用户更新:
void LongPoll::getLongPollServer() { QUrl url("https://api.vk.com/method/messages.getLongPollServer");
如果请求成功完成,则保存与Long Poll服务器的连接信息,并使用
doLongPollRequest
方法打开连接:
void LongPoll::finished(QNetworkReply* reply) { QJsonDocument jDoc = QJsonDocument::fromJson(reply->readAll());
在
doLongPollRequest
Long Poll方法中,必要的连接参数传递到服务器:
void LongPoll::doLongPollRequest() { QUrl url("https://" + _server);
值得注意的是,
mode
字段的值等于10,是通过添加接收附件的选项(2)并返回扩展的事件集(8)获得的。
作为对打开连接的响应,服务器返回包含最新事件的JSON。 响应以
finished
方法处理:
void LongPoll::finished(QNetworkReply* reply) { QJsonDocument jDoc = QJsonDocument::fromJson(reply->readAll());
响应中
failed
字段可以采用四个值,但是只有一个值等于1,不需要重复请求信息即可连接到Long Poll服务器。 因此,将条件添加到了代码中。
jObj.value("failed").toInt() == 1
parseLongPollUpdates
方法是对所有传入事件进行检查的简单周期:
enum LONGPOLL_EVENTS { NEW_MESSAGE = 4,
该代码显示,对于每个新的长轮询事件,客户端都会发送一个
信号 ,该
信号必须由应用程序的另一部分进行处理。 signal参数不是整个事件对象,而只是其必要部分。 例如,
gotNewMessage
信号仅发送
gotNewMessage
的标识符,通过该标识符
请求其完整内容:
void VkSDK::_gotNewMessage(int id) { _messages->getById(id); }
作为此单行功能的结果,将向VKontakte服务器发出请求,以通过进一步
创建此消息
的对象来通过其标识符获取有关消息的完整信息。 总之,将发送与用户界面关联的信号,传输有关新消息的数据,该消息
显示在通知面板中:
import QtQuick 2.0
对话介面
现在,基于客户端与Long Poll服务器交互的原理以及将接收到的信息传输到用户界面的原理,我们可以考虑一个更新开放
对话的示例。
引起您注意的第一件事是“
Connections
组件:
Connections {
onUserTyping
插槽通过向用户显示相应的通知来处理消息的对话者设置的事件。 在这里,第一步,获得房间标识符(房间是指对话和聊天的通用术语),第二步,如果接收到的标识符和当前房间的标识符匹配,则显示通知。
值得注意的是,如果在这段时间内没有新的事件再次激活该通知,则将在十秒钟内显示有关一组消息的通知。 这可以通过使用
Timer
组件来实现:
Label {
onSavedPhoto
插槽负责处理消息中图像的加载结束,这超出了本文的范围。
感兴趣的第二件事是消息列表:
SilicaListView {
在这里,
MessageItem
组件负责显示一条消息。 它的考虑超出了本文的范围。
消息本身取自
vksdk.messagesModel
模型。 此模型是
Message
对象的列表,可以使用
add
,
prepend
,
addProfile
,
readMessages
和
clear
方法实时更新:
void MessagesModel::clear() { beginRemoveRows(QModelIndex(), 0, _messages.size());
这五种方法的共同点是使用
dataChanged
信号,该信号指示数据已在模型中更新。 发出此信号将更新
SilicaListView
元素以显示消息的当前状态。 通过调用
beginInsertRows
和
endInsertRows
来向
rowsAboutToBeInserted
添加消息,该
endInsertRows
分别发送
rowsAboutToBeInserted
和
rowsInserted
。 结果,用户将在对话框中实时看到新消息及其状态。
结论
本文以VK应用程序为例,研究了为Sailfish OS开发时与Long Poll服务器的交互。 考虑了客户端实现的一些功能以及实时更新用户界面的方法。 GitHub上
提供了本文描述的应用程序代码。