假设我有一个基于 tcp 的基本 golang jrpc 服务器:
package main
import (
"fmt"
"net"
"net/rpc"
"net/rpc/jsonrpc"
)
type Arith int
type Args struct {
A, B int
}
func (t *Arith) Add(args *Args, result *int) error {
*result = args.A + args.B
return nil
}
func RunServer() {
arith := new(Arith)
rpc.Register(arith)
listener, err := net.Listen("tcp", ":8080")
if err != nil {
fmt.Println("Error starting server:", err)
return
}
defer listener.Close()
for {
conn, err := listener.Accept()
if err != nil {
fmt.Println("Error …
Run Code Online (Sandbox Code Playgroud) 所以这是我的项目:
我正在构建一个中央界面/仪表板,以显示多个产品版本的多种测试类型的测试数据.我们在我们的大型产品上使用TestNG,虽然没有编写足够的测试,但这是另一个主题的讨论.这是目录结构的样子:
文件系统/的ProductVersion + testType/uniqueDateAndBuildID/TestNG的-results.xml
results.xml文件包含带有子测试标记的标记,这些标记对应于文件系统目录,然后是包含实际测试用例结果的xml文件(传递,失败等)XML解析和文件系统遍历都很好,很好/可靠.
控制流程:客户端访问主页面 - >服务器打开属性文件 - >服务器检查Web服务器属性(Websphere或Tomcat,如果我在本地工作) - >服务器根据它设置一堆常量.常量包括:根文件系统目录,文件系统分隔符(转换),"类似类型(基本上在不同平台上的相同测试)",以及要附加到的基本URL. - >然后服务器再读取属性文件并完成所有XML处理.使用ObjectOutputStream将结果缓存在内存中以及文件系统中. - >将大量结果发送回客户端进行UI处理/显示.
这是我遇到问题的地方:我无法访问客户端上的全局变量(在Globals类中包含/设置...我知道错误: - /),即使它们位于共享文件夹中.如果你想知道为什么我不能再次加载属性,那是因为客户端是GWT-ified Javascript,它不包含File().所以我的下一个想法是,做了一点上层Java阅读可能是使用一个Globals单例对象并将其传回去.但是看起来这也是坏的,如果不是不可能的话. 这里的建议会很棒.
这一切都非常紧密,我以前的Java教育还没有真正进入过.由于这只是开发人员检查的内部门户,因此实际测试我的代码似乎没有多大意义.只要它正确显示,正确记录,并优雅地处理错误,对吗?总而言之,这是<15级,所以我猜这不是什么大不了的事.我应该重构清理它并使其成为"更好的Java",评论所有内容以清楚地描述控制流程,或者不要过于担心它因为它很小?我知道将来在设计之前要多考虑一些事情,但我真的不知道自开始以来我接触过的大量Java原则.
在做了一些思考后编辑,想出了一个可能的解决方法.那么,我传回了一些包含全局"标题"对象的其他自定义列表实现,而不是只返回结果列表?我可以保留国家.
有没有什么理由不将XML-RPC用于对象代理服务器/客户端架构?也许类似"没有它已经过时,现在有X".
为了提供更多细节:我想构建一个框架,允许标准化交互和许多小工具(例如命令行工具)之间的结果交换.如果有人想要集成另一个工具,她会为此目的编写一个包装器.例如,包装器可以将工具的STDOUT转换为架构可用的对象.
目前我正在考虑用Python编写概念证明服务器.之后它可以用C/C++重写.为了确保客户端可以用尽可能多的语言编写,我想到了使用XML-RPC.CORBA似乎过于臃肿,因为服务器不应该太复杂.
感谢您的建议和意见,Rainer
RPC现在还在使用吗?或者rpc被其他技术取代了?如果我用C++开始新项目我应该考虑使用RPC吗?
更多信息,因为我知道RPC仍然在生产代码中使用:
我有两个相互通信的应用程序.这两个是在同一台机器上,但一个是服务,第二个是用户应用程序.用户应用每2,3秒发送一次服务应用.第二次使用rpc.我有1个客户端和许多具有本地数据库的计算机.并且该客户端需要从这些计算机获取一些数据.
我应该为这两个场景使用像Thrift这样的东西吗?或者它太大了?
现在我使用Hadoop处理最终将加载到同一个表中的数据.我需要一个共享的序列号生成器来为每一行生成id.现在我使用以下方法生成唯一编号:
1)在HDFS中创建一个文本文件,例如test.seq,用于保存当前的序列号.
2)我使用锁定文件".lock"来控制并发.假设我们有两个并行处理数据的任务.如果task1想要获取该号码,它将检查锁定文件是否存在.如果是,则表示task2正在从test.seq访问该号码,然后task1必须等待.当task2获取了该号码时,它会在返回时通过增加1来覆盖旧号码,并删除锁定文件".lock".当task1看到.lock消失时,task1将首先创建一个".lock"文件,然后以相同的方式获取序列号.
但是,我不确定这种方法是否切实可行.因为我将.lock和test.seq文件保存在HDFS中,即使任务1更改了test.seq的内容,它也可能无法立即被task2识别.当其他任务通过namenode获取有关HDFS中数据的信息时.因此,datanode将首先通知对namenode的更改,然后通知其他任务更改.这是对的吗?
另一个想法是创建在Master上运行的torjan程序.所以,任务获取顺序号是通过RPC Torjan程序.但是如何在主程序上运行Torjan程序?
有人可以给我一些建议吗?谢谢!
我无法理解为什么gwt rpc AsyncCallback之后的代码不会被执行?
例如,我有接口AppService扩展RemoteService,所以我将有AsyncAppService进行异步调用.
以下代码
AppServiceAsync service = GWT.create (AppService.class);
service.getCurrentUser(new AsyncCallback<Employee>(){
public void onFailure(Throwable caught) {
}
public void onSuccess(Employee result) {
currentUser = result;
}
});
// if i have the code after the above call, these code will not be execute, what is the problem
//code following will not be executed if they are in the same function.
boolean isAdmin = false;
if(currentUser!=null){
if(currentUser.getUserRole().equals("ROLE_ADMIN") ||
currentUser.getUserRole().equals("ROLE_MANAGER")){
isAdmin = true;
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢你的解释
是否可以执行String作为方法?
假设我有一台服务器和一台客户端.客户端发送一个"sayHello()"
字符串.客户端是否可以在客户端执行此字符串作为方法,如果他有private void sayHello()
方法?
我知道我可以通过将字符串与特定值进行比较来调用该方法,并基于此调用函数.但我正在调查上面描述的内容.
抱歉,如果我的英语不好.
我在调用我的GWT服务时遇到问题.在客户端,我有以下错误.
[ERROR] com.google.gwt.user.client.rpc.StatusCodeException: 500 The call failed on the server; see server log for details
[ERROR] at com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter.onResponseReceived(RequestCallbackAdapter.java:209)
[ERROR] at com.google.gwt.http.client.Request.fireOnResponseReceived(Request.java:287)
[ERROR] at com.google.gwt.http.client.RequestBuilder$1.onReadyStateChange(RequestBuilder.java:395)
...
Run Code Online (Sandbox Code Playgroud)
不幸的是,我在服务器日志中找不到与此错误相关的任何信息.我处于开发模式,我在码头唯一可以看到的是
[ERROR] 500 - POST /my/maping (127.0.0.1) 57 bytes
Run Code Online (Sandbox Code Playgroud)
但是,我知道我的服务实现被调用,它返回一个结果而不会抛出任何异常(因为我在返回之前使用了日志......).
我已经看到这个问题可能是一个序列化问题,但我真的没有看到我想念的东西让我的对象可序列化,(另外,gwt编译器通常会说我什么时候不能序列化).
我的/映射应该很好地定义,因为它以前工作,我很确定我没有修改任何与此相关的内容......
最后,我没有找到任何有趣的答案来解决我的问题.如果您有任何想法,请提前感谢您的帮助.
ps:我使用gwt 2.5.0-rc2.
我正在尝试使用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
如何从远程服务访问数据库和文档?
我正在一个基于PHP / JS的项目中,在这里我想在后端介绍域驱动设计。我发现命令和查询比CRUD是表达我的公共领域的更好方法,因此我喜欢遵循CQS原则构建基于HTTP的API。这不是安静的CQRS,因为我想在命令和查询端使用相同的模型,但是许多原理是相同的。对于API文档,我使用Swagger。
我找到了一篇文章,该文章通过REST资源(https://www.infoq.com/articles/rest-api-on-cqrs)公开了CQRS 。他们使用5LMT来区分不同的命令,而Swagger不支持。此外,通过将CQS放到面向资源的REST API中,我是否不会失去意图显示接口的好处?我没有找到任何文章或产品直接通过基于HTTP的后端公开命令和查询。
所以我的问题是:直接通过API公开命令和查询是否是一个好主意。它看起来像这样:
POST /api/module1/command1
GET /api/module1/query1
...
Run Code Online (Sandbox Code Playgroud)
它不是REST,但我看不到REST如何为表带来任何好处。维护REST资源将引入另一个模型。而且,在URL中具有命令和查询将允许使用诸如路由框架和访问日志之类的功能。