从XMPP获取脱机消息而不联机

时间:2016-11-05 17:15:44

标签: ios objective-c xmpp ejabberd xmppframework

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

但我们在实施方面存在问题,我们无法找到解决方案。 我们已经实现了XMPP消息传递的各个方面,除了一件事之外,所有方面都很好:

虽然我们的应用程序是在后台,但我们的ejabberd服务器向我们发送推送通知,以通知我们有关离线消息的信息。 (仅发送离线消息的通知)

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

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

  1. 发送消息的一方看到我们的在线状态(即使我们在后台)
  2. 仅仅因为我们在应用程序处于后台时变为在线,我们的服务器无法向其他人发送推送通知,因为我们在线并且服务器只能发送离线消息的通知。
  3. 为了解决这个问题,我只能想到的是,如果有办法从xmpp服务器检索离线消息而不上线。 有没有人知道是否有任何方法可以使用XMPP-Framework for ios

    [编辑] 让我再详细说明一下这个问题:

    问题不只是一个:

    问题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. 时才能获得1条离线消息
    3. 如果可能,我还需要在不联机的情况下获取这些离线消息

2 个答案:

答案 0 :(得分:0)

我建议您将自定义扩展元素添加到“后台”在线状态,例如

function getData(){

    $.ajax({
        url: '/filter',
        dataType:'json',
        type: 'POST',
        data: {'mmsi':$('input[name=mmsi]').val(),'from': $("input[name='from']").val(), 'to': $("input[name='to']").val()}

    }).done(function(data) {
        initMap();
        console.log(data.length);
        console.log(data);
        $.each(data, function(index, obj){
            console.log( obj.latitude +  " - " +obj.longitude   );
            //console.log("helloooo");
            var pos = {lat: obj.latitude, lng: obj.longitude};
            path1.push({lat: parseFloat(obj.latitude), lng: parseFloat(obj.longitude)});

            contentString = "<p>" +obj.last_received_date+ "<br>"+obj.last_received_time+"</p>";
            var infowindow = new google.maps.InfoWindow({
                content: contentString
            });
            var circleIcon = {
                path: google.maps.SymbolPath.CIRCLE,
                fillColor: '#600d48',
                fillOpacity: 0.8,
                scale: 2,
                strokeColor: '#600d48'
            };
            var pathMarker = new google.maps.Marker({
                position: pos,
                icon: circleIcon,
                map: map
            });
            pathMarker.addListener('mouseover', function() {
                infowindow.open(map, pathMarker);
            });
            // assuming you also want to hide the infowindow when user mouses-out
            pathMarker.addListener('mouseout', function() {
                infowindow.close();
            });

        });
        var lineSymbol = {
            path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW
        };

        var polylineoptns = {
            strokeOpacity: 0.8,
            strokeWeight: 3,
            path: path1,
            strokeColor: '#FF0000',
            strokeOpacity: 1.0,
            map: map,
            icons: [{
                icon: lineSymbol,
                repeat: '70px',
                offset: '100%'
            }],
        };
        polyline = new google.maps.Polyline(polylineoptns);

        path1 = [];

    }).always(function() {

    }).fail(function(jqXHR, textStatus, errorThrown) {
        alert('Error: ' + errorThrown);
    })

}

然后,客户端,当您收到在线状态时,如果存在xmlns“<presence ...> <source xmlns:="com.foo#background"/> </presence> ”的扩展元素“source”,则不会通知。

答案 1 :(得分:0)

查看ejabberd_mod_offline_post

  1. 首先配置会议室必须是会员专用会议室,并在创建后立即将所有用户添加为会员,以便能够获得总数。
  2. 将上述模块添加到ejabberd模块中。
  3. 实施回调服务以处理回调帖子。
  4. 想法是当用户离线时:

    • 在一对一的情况下,将引发offline_message_hook
    • 在MUC案例中,将引发muc_filter_message,并且任何非Presence-Available的人都会离线。

    [被修改]:

    我在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 = f xml:get_path_s(Stanza,[{elem,list_to_binary(&#34; body&#34;)},cdata]),

    对于MUC,离线用户位于“脱机”状态。字段为此格式,&#39; user1..user2..user3 ..&#39;,您需要执行此操作以将其从字符串中拆分出来。