gpt4 book ai didi

javascript - Pubnub.history()分页

转载 作者:行者123 更新时间:2023-12-03 05:49:00 25 4
gpt4 key购买 nike

我正在尝试为pubnub.history()实现分页。这是我到目前为止的内容:

尝试1:这将从时间的开头获取头count消息:

function getHistory(chnl,count, token) {
var pagesize=10;
console.log('Starting at ' + token + ', getting ' + count);
pubnub.history({
channel : chnl,
callback : function(m){
var msgs = m[0];
var msgcount = msgs.length;
var startToken = m[1];
var endToken = m[2];
for (var i = 0; i < msgcount; i++) {
var msg = msgs[i];
processMessage(chnl,msg);
}
if (count >= pagesize) {
getHistory(chnl,count - pagesize,endToken);
}
},
count: pagesize,
start: token,
reverse: true
});
}


尝试2:一次又一次获取最新的 pagesize消息。 token每次都相同:

function getHistory(chnl,count, token) {
var pagesize=10;
console.log('Starting at ' + token + ', getting ' + count);
pubnub.history({
channel : chnl,
callback : function(m){
var msgs = m[0];
var msgcount = msgs.length;
var startToken = m[1];
var endToken = m[2];
for (var i = 0; i < msgcount; i++) {
var msg = msgs[i];
processMessage(chnl,msg);
}
if (count >= pagesize) {
getHistory(chnl,count - pagesize,startToken);
}
},
count: pagesize,
end: token,
reverse: false
});
}


我需要获取最新的 count消息,并以最新消息结尾。如何修改我的功能来做到这一点?



更新:我的新API v4代码:

function getHistory(chnl,count, token) {
var pagesize=10;
console.log('Starting at ' + token + ', getting ' + count);
pubnub.history({
channel : chnl,
callback : function(m){

},
count: pagesize,
start: token,
reverse: true
},function(status, response) {
var msgs = response.messages;
var msgcount = msgs.length;
var startToken = response.startTimeToken;
var endToken = response.endTimeToken;
for (var i = 0; i < msgcount; i++) {
var msg = msgs[i];
processMessage(msg);
}
if (count >= pagesize) {
getHistory(chnl,count - pagesize,endToken);
}
});
}


如果我要求1000,这是它现在正在做的事情:


2016-10-25 13:29:59.060 pubnub.js:23 Starting at 14772721032416580, getting 620
2016-10-25 13:29:59.385 pubnub.js:23 Starting at 14772748031396800, getting 610
2016-10-25 13:29:59.678 pubnub.js:23 Starting at 14772778027380036, getting 600
2016-10-25 13:30:00.024 pubnub.js:23 Starting at 14772808029462014, getting 590
2016-10-25 13:30:00.440 pubnub.js:23 Starting at 14772838027743668, getting 580
2016-10-25 13:30:00.772 pubnub.js:23 Starting at 14772868026780088, getting 570
2016-10-25 13:30:01.116 pubnub.js:23 Starting at 14772898023567196, getting 560
2016-10-25 13:30:01.426 pubnub.js:23 Starting at 14772928025649280, getting 550
2016-10-25 13:30:01.726 pubnub.js:23 Starting at 14772958026355252, getting 540
2016-10-25 13:30:02.113 pubnub.js:23 Starting at 14773220007794584, getting 530
2016-10-25 13:30:02.457 pubnub.js:23 Starting at 14774200653664656, getting 520
2016-10-25 13:30:02.606 pubnub.js:23 Starting at 14774200653664656, getting 510
2016-10-25 13:30:02.690 pubnub.js:23 Starting at 14774200653664656, getting 500
2016-10-25 13:30:02.790 pubnub.js:23 Starting at 14774200653664656, getting 490
2016-10-25 13:30:02.922 pubnub.js:23 Starting at 14774200653664656, getting 480
2016-10-25 13:30:03.015 pubnub.js:23 Starting at 14774200653664656, getting 470



如您所见,实际上并没有1000条消息,因此在 13:30:02.467处它一遍又一遍地收到相同的消息。然后,我请求300,但它成功了,但它得到了前300个,而不是最近的300个。

因此,仍然存在两个问题:


如果请求的号码超过了所有,则获取所有消息。
获取最新的x条消息。

最佳答案

PubNub存储-使用历史记录分页

一些设置


我整理了一个递归分页功能和一组测试它的步骤。请记住,此代码尽可能简单,但仍可对POC起作用,但这不是最佳实践。
这是PubNub JavaScript SDK v4,而不是最初提出该问题的v3。


首先,使用您自己的密钥初始化PubNub的实例

// init PubNub
var pubnub = new PubNub({
publishKey : 'pub-...',
subscribeKey : 'sub-...'
})


其次,创建一个函数来填充频道

我们希望创建一个包含消息的通道,以便我们可以轻松理解这些消息的顺序:消息#1,消息#2等。

我们使用setInterval在发布的消息之间添加一些延迟。首先,我们要确保消息按发布顺序存储(请记住,消息都是异步的,包括在服务器端),并且我们希望消息时间令牌之间有一定的时间间隔。

function pub(channel, total) {
var i = 1;

var looper = setInterval(
function() {
pubnub.publish({
channel: channel,
message: "message #" + i++
});

if (i > total) {
clearInterval(looper);
}
},
400);
}


您可以创建几个具有不同消息数量的不同测试通道,但是一个具有32条消息的通道应该可以完成简单的历史分页测试。您需要一个非四舍五入的数字,因此您可以按5或10进行分页,并查看结果不均的结果。另一个带有轮数的频道也很有用。

最后,创建历史记录分页功能

这有点粗糙,但是它可以完成工作而没有太多幻想,无法指出正在发生的事情。它使用递归而不是最优的。

function getMessages(args, callback) {
pubnub.history(
{
// search starting from this timetoken
start: args.startToken,
channel: args.channel,
// false - search forwards through the timeline
// true - search backwards through the timeline
reverse: args.reverse,
// limit number of messages per request to this value; default/max=100
count: args.pagesize,
// include each returned message's publish timetoken
includeTimetoken: true,
// prevents JS from truncating 17 digit timetokens
stringifiedTimeToken: true
},
function(status, response) {
// holds the accumulation of resulting messages across all iterations
var results = args.results;
// the retrieved messages from history for this iteration only
var msgs = response.messages;
// timetoken of the first message in response
var firstTT = response.startTimeToken;
// timetoken of the last message in response
var lastTT = response.endTimeToken;
// if no max results specified, default to 500
args.max = !args.max ? 500 : args.max;

if (msgs != undefined && msgs.length > 0) {
// display each of the returned messages in browser console
for (var i in msgs) {
msg = msgs[i];
console.log(msg.entry, msg.timetoken);
}

// first iteration, results is undefined, so initialize with first history results
if (!results) results = msgs;
// subsequent iterations, results has previous iterartions' results, so concat
// but concat to end of results if reverse true, otherwise prepend to begining of results
else args.reverse ? results = results.concat(msgs) : results = msgs.concat(results);
}

// show the total messages returned out of the max requested
console.log('total : ' + results.length + '/' + args.max);

// we keep asking for more messages if # messages returned by last request is the
// same at the pagesize AND we still have reached the total number of messages requested
// same as the opposit of !(msgs.length < pagesize || total == max)
if (msgs.length == args.pagesize && results.length < args.max) {
getMessages(
{
channel:args.channel, max:args.max, reverse:args.reverse,
pagesize:args.pagesize, startToken:args.reverse ? lastTT : firstTT, results:results
},
callback);
}
// we've reached the end of possible messages to retrieve or hit the 'max' we asked for
// so invoke the callback to the original caller of getMessages providing the total message results
else callback(results);
}
);
}


测试分页

我们假设我们有一个名为 test1的通道,其中在Storage中有32条消息,如下所示:


讯息1
讯息2


...


讯息#32


每个都有一个独特的时间令牌。

调用 getMessages函数可获得以下所需结果:

1.从最早的消息开始最多获取50条消息,一次最多5条消息

getMessages(
{
channel: 'test1', max: 50, pagesize: 5, reverse: true
},
function(results) {
console.log("results: \n" + JSON.stringify(results));
}
);


2.从最早的消息开始最多获取20条消息,一次最多5条消息

getMessages(
{
channel: 'test1', max: 20, pagesize: 5, reverse: true
},
function(results) {
console.log("results: \n" + JSON.stringify(results));
}
);


3.从最新消息开始,最多获取50条消息,一次获取5条消息

getMessages(
{
channel: 'test1', max: 50, pagesize: 5, reverse: false
},
function(results) {
console.log("results: \n" + JSON.stringify(results));
}
);


4.从最新消息开始最多获取20条消息,一次5条消息

getMessages(
{
channel: 'test1', max: 20, pagesize: 5, reverse: false
},
function(results) {
console.log("results: \n" + JSON.stringify(results));
}
);


因此,您应该看到每次调用 history时返回的消息的顺序始终是最早的到最新的(升序)。但是搜索消息的顺序取决于 reverse参数。


reverse:true将从最旧到最新检索消息块:1,2,3,4,5 | 6,7,8,9,10 | ...
reverse:false将检索最新到最旧的消息块:28,29,30,31,32 | 23,24,25,26,27 | ...


因此,重申一下,每个响应中消息的顺序是相同的,但是搜索/检索的方向是不同的。注意:这是新的存储/历史记录设计将使用更简单,更强大的API(例如: getMessagesSincegetMessagesBeforegetMessagesBetween)清除的内容。

现在让我们介绍 startToken参数,以便我们可以从通道历史记录时间轴中的给定点检索消息或将消息检索到该点。您指定的时间令牌将是您需要从通道历史记录中的现有消息中选择的时间令牌。因为我们在不同的时间发布了不同的密钥,所以您和我的情况将有所不同。我将在以下示例中使用 startToken:14774567814936359,并假设这是消息#17的时间标记。

5.从timetoken的消息开始最多获取20条消息,令牌为14774567814936359,一次最多5条消息(请记住, start参数是互斥的,因此您不会在结果中返回消息#17)

getMessages(
{
channel: 'test1', max: 20, pagesize: 5, reverse: true,
startToken:"14774567814936359"
},
function(results) {
console.log("results: \n" + JSON.stringify(results));
}
);


注意:您必须将timetoken值作为字符串传递(注意, startToken参数值在上面和下面引用),否则JavaScript会将它们四舍五入。例如,14774567814936359将变为14774567814936360,您将得到意外的结果。继续尝试不带引号的操作,您将看到将检索提供的时间令牌上的消息,但应将其排除在外。通过在浏览器的“网络”选项卡中进行检查,可以在提交的历史记录URL中看到四舍五入的时间令牌。

6.在时间令牌之前最多获得20条消息,令牌14774567814936359,一次获得5条消息

getMessages(
{
channel: 'test1', max: 50, pagesize: 5, reverse: false,
startToken:"14774567814936359"
},
function(results) {
console.log("results: \n" + JSON.stringify(results));
}
);


我们可以继续提供更多示例,但我会让你(斯科特)和其他人询问如何做示例,我可以根据需要提供。

订购历史记录结果

getMessages函数以预先排序的升序组合消息的结果数组,即使从最新到最早的消息中检索消息也是如此。它通过在新的历史记录结果之前加上先前迭代结果的当前累积值来实现。

如果希望按时间令牌降序对消息进行排序,则实现排序比较器功能相当简单。我在这里提供了一个简单的示例:

function sortHistory(messages, desc, callback) {
messages.sort(function(a, b) {
var e1 = desc ? b : a;
var e2 = desc ? a : b;
return parseInt(e1.timetoken) - parseInt(e2.timetoken);
});

callback(messages);
}


sortHistory函数接受messages数组(JSON元素数组: {message, timetokens}的数组),指示所需排序顺序的标志(默认为升序,对于降序设置为true),以及将使用结果排序数组消息。

现在,用 getMessages调用 revers:true。这意味着将按照从最早到最新的顺序检索消息,如果我们要升序排序,则已经按照该顺序进行了。

getMessages({channel: 'test1', max: 100, pagesize: 5, reverse: true}, 
function(results) {
console.log("presorted: \n" + JSON.stringify(results));
}
);


如果我们想按降序对消息进行排序,只需在 sortHistory函数中添加一个调用即可。

getMessages({channel: 'test1', max: 100, pagesize: 5, reverse: true}, 
function(results) {
console.log("before sort: \n" + JSON.stringify(results));

// sort messages in descending order
sortHistory(results, true, function(sorted) {
console.log("after sort: \n" + JSON.stringify(sorted));
});
}
);


而且,如果我们使用最新到最旧的 reverse:false检索消息,那么即使迭代大小为 pagesize(16,17,18,19,20 | 11,12 ,13,14,15 ...)。但是,如果我们想对降序进行排序,则只需调用 sortHistory函数。

getMessages({channel: 'test1', max: 100, pagesize: 5, reverse: false}, 
function(results) {
console.log("before sort: \n" + JSON.stringify(results));

// sort messages in descending order
sortHistory(results, true, function(sorted) {
console.log("after sort: \n" + JSON.stringify(sorted));
});
}
);



  我用新代码更新了jsfiddle,并对这个答案做了很多修改。


有关完整的详细信息,请参见PubNub JavaScript SDK Storage (history)文档/教程。

关于javascript - Pubnub.history()分页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40222176/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com