jjzjj

ios - 在不在线的情况下从 XMPP 获取离线消息

coder 2024-01-29 原文

我们正在为我们的移动聊天应用程序使用 ejabberd 服务器。 我们正在为我们的 IOS 应用程序使用 IOS XMPP-Framework (https://github.com/robbiehanson/XMPPFramework)

但是我们在实现上遇到了一个问题,我们找不到解决方案。 我们已经实现了 XMPP 消息传递的各个方面,除了一件事之外一切都很好:

当我们的应用程序在后台运行时,我们的 ejabberd 服务器会向我们发送推送通知以通知我们有关离线消息的信息。 (仅发送离线消息通知)

然后我们决定实现 IOS 后台推送通知功能,以便在应用程序处于后台时获取离线消息。

但问题是我们必须在线(发送状态)才能获得离线消息。 但是,当我们这样做时,它会产生 2 个不良后果:

  1. 发送消息的一方看到我们在线(即使我们在后台)
  2. 正因为我们在应用程序处于后台时上线,所以我们的服务器无法发送其他人消息的推送通知,因为我们在线并且服务器只能发送离线消息的通知。

为了解决这个问题,我唯一能想到的是,如果有一种方法可以在不在线的情况下从 xmpp 服务器检索离线消息。 有谁知道是否有任何方法可以使用适用于 ios 的 XMPP 框架

[编辑] 让我再澄清一下这个问题:

问题不止一个:

问题 1 - 推送通知问题:

1.1 - Server check if the message is sending to an online or offline user. If the user is offline server sends push notification to inform user but if the user is online server doesnt send anything. 
1.2 - When the application is in background and receive notification for offline messages, application become alive(still in background) and become online in order to get offline messages
1.3 - Because the client became online, server doesnt send the push notifications anymore but the application is still in background so the user cannot be informed about the message he/she received.

所以为了解决这些问题,我需要找到一种通过不向服务器发送在线状态来接收离线消息的方法

问题2——消息接收问题

2.1 - Server check if the message is sending to an online or offline user. If the user is offline server sends push notification to inform user but if the user is online server doesnt send anything. 
2.2 - When the application is in background and receive notification for offline messages, application become alive(still in background) and become online in order to get offline messages
2.3 - When the application became online server sends all offline messages to client but doesnt send the total count of offline messages(At least I cannot get it with IOS XMPPFramework)
2.4 - So I dont know how much longer the client should stay alive in the background because I dont know the total count of offline messages, so after getting 2-3 messages I have to suspend the application in the background. But in that case there might be buggy situations such as XMPP Framework receive the offline message but I suspend the client application before writing it to database etc...

为了找到解决这些问题的办法:

  1. 我需要找到一种方法,当我想从服务器获取一条离线消息时
  2. 如果可能的话,我还需要在不在线的情况下获取那些离线消息

最佳答案

查看ejabberd_mod_offline_post

  1. 首先配置房间必须是Member-Only房间,创建后立即将所有用户添加为成员,这样才能得到总数。
  2. 将以上模块添加到ejabberd模块中。
  3. 实现回调服务来处理回调帖子。

想法是当用户下线时:

  • 在一对一的情况下,会引发offline_message_hook
  • 在 MUC 情况下,将引发 muc_filter_message,并且任何不存在的人都处于离线状态。

[编辑]:

我在 16.06 上使用它。并且源代码中的行有错误:

...

Body = xml:get_path_s(Stanza, [{elem, list_to_binary("body")}, cdata]),

...

 Type = xml:get_tag_attr_s(list_to_binary("type"), Packet),

 Body = xml:get_path_s(Packet, [{elem, list_to_binary("body")}, cdata]),

...

我通过将 f 添加到 xml: 来修复它们,例如 Body = fxml:get_path_s(节, [{elem, list_to_binary("body")}, cdata]),

对于 MUC,离线用户位于“离线”字段中,格式为“user1..user2..user3..”,您需要这样做才能将他们从字符串中分离出来。

关于ios - 在不在线的情况下从 XMPP 获取离线消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40441055/

有关ios - 在不在线的情况下从 XMPP 获取离线消息的更多相关文章

  1. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  2. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  3. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  4. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  5. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  6. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

  7. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  8. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  9. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  10. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

随机推荐