在XPage中使用远程服务(RPC)

mik*_*_x_ 1 javascript rpc lotus-domino xpages

我正在尝试使用rpc服务更新文档.

我有一个带按钮的xpage.我想单击该按钮并使用CS javascript to setInterval并每5秒更新一次文档字段.

我使用了远程服务控件,代码如下:

<xe:jsonRpcService id="jsonRpcService1" serviceName="heartBeat">
        <xe:this.methods>
            <xe:remoteMethod name="send">





                <xe:this.script><![CDATA[var db = session.getCurrentDatabase();
var heartView = db.getView("Heartbeats");

var doc:NotesDocument = heartView.getFirstDocument();
var vl = doc.getItemValueString();
if(vl==""){
    doc.replaceItemValue("dummyH","z");
}else{
    doc.replaceItemValue("dummyH",vl+"z");
}
doc.computeWithForm(false, false);
doc.save();]]></xe:this.script>
            </xe:remoteMethod>
        </xe:this.methods></xe:jsonRpcService>
Run Code Online (Sandbox Code Playgroud)

按钮的代码是这样的:

<xp:button value="Label" id="button1">
        <xp:eventHandler event="onclick" submit="false">
            <xp:this.script><![CDATA[setInterval(function(){heartBeat.send()},3000);]]></xp:this.script>
        </xp:eventHandler></xp:button>
Run Code Online (Sandbox Code Playgroud)

它不起作用.我没有得到任何错误,但我也没有在文档中得到任何更新......代码中有什么问题?

UPDATE

如果我用一个简单的打印("aaaaa")替换rpc脚本它完美地工作(我也按照下面的答案中的Tim的建议,为我的客户端代码).

当我再次使用我以前的代码时,我得到以下javascript错误:无法加载/Databases/Test/Mike/my1.nsf/RPCpage.xsp/mm?$$viewid=!dqducrahog!状态:400

如何从远程服务访问数据库和文档?

Tim*_*ony 10

RPC调用的语法有点不寻常; heartbeat.send()例如,您的调用实际上并不调用远程send方法.相反,它返回一个远程方法描述符的句柄...实际调用远程方法,你需要添加一个回调:

var remoteMethod = heartbeat.send();
remoteMethod.addCallback(function(response){
  // handle whatever came back from the server
});
Run Code Online (Sandbox Code Playgroud)

例如,如果您设计了远程方法来返回心跳是否成功,则更完整的示例将如下所示:

var heartbeatInterval = 3000;
var periodicHeartbeat = function() {
  var remoteMethod = heartbeat.send();
  remoteMethod.addCallback(function(response){
    if (response.stillAlive) {
      setTimeout(periodicHeartbeat, heartbeatInterval);
    }
  });
}
setTimeout(periodicHeartbeat, heartbeatInterval);
Run Code Online (Sandbox Code Playgroud)

通常建议使用setTimeout最初调度延迟函数,然后setTimeout从该延迟函数中再次调用以安排自己的下一次执行,而不是使用setInterval.

但是,在这个用例中,这尤其正确,因为每个远程方法调用都是异步的,因此setInterval最终会导致请求重叠,因为每个调用至少需要几毫秒才能完成.

此外,从当前内部调度下一次执行的首选模式允许您检查服务器发回的内容,以确定是否甚至打扰继续发送后续请求.现在你没有从远程方法返回任何值; 如果你只改变最后一行:

return { stillAlive: doc.save() };
Run Code Online (Sandbox Code Playgroud)

...然后JSON对象将自动作为其第一个参数传递给您的回调函数.再看一下前面例子中的一行:

if (response.stillAlive) {
Run Code Online (Sandbox Code Playgroud)

...因此,如果先前的调用成功,则RPC调用仅重新调度自身.这可能不是您想要的精确行为,但考虑到您可以从远程方法返回数据,并且返回的数据传递给您的回调函数,您可以设计最适合您的业务规范的调用和响应方法这个功能.

说了这么多,你可能想看一下keepAliveXPages扩展库中的组件...它不会在Domino文档中存储心跳数据,但是如果你要做的就是阻止空闲会话到期,这是一个更简单的解决方案.