gpt4 book ai didi

c# - 使用 XML-RPC 编写以 C#、Ruby 和 Java 编写的分布式应用程序

转载 作者:数据小太阳 更新时间:2023-10-29 08:13:51 25 4
gpt4 key购买 nike

我的任务是编写一个分布式事件管理工具,其中每个客户端(Ruby、C# 或 Java 客户端)将所有更改与注册客户端列表同步。我必须使用 XML-RPC 来实现目标。我和我的团队已经用每种语言编写了一个 XML-RPC 客户端和服务器,并将在下面提供相关的源代码。如果您需要更多代码,请告诉我。

问题是我可以让 Java 和 C# 相互通信。 Ruby 可以与其他人通信,但 C#(也许还有 Java,尚未测试)在处理 Ruby 服务器时存在问题。我想问题出在端点上。首先让我给你一些代码。阅读时请注意,代码实际上是由团队编写的,命名约定略有不同:

C# 客户端

Uri _address = new Uri("http://" + _s + ":8000/xmlrpc/EventManagerService");
ChannelFactory<IEventManagerWCF_XML_RPC> _factory = new ChannelFactory<IEventManagerWCF_XML_RPC>(new WebHttpBinding(WebHttpSecurityMode.None), new EndpointAddress(_address));
_factory.Endpoint.Behaviors.Add(new XmlRpcEndpointBehavior());
IEventManagerWCF_XML_RPC _proxy = _factory.CreateChannel();

_proxy 不会保留给定 URI 的客户端。这些存储在字典中,并在需要同步事件时使用。在修改的情况下会发生这样的同步;

 foreach(IEventManagerWCF_XML_RPC proxy in this.peers.Values)
proxy.modify(_id, _field, _newValue);

这是 IEventManagerWCF_XML_RPC 接口(interface)的摘录;

 [OperationContract(Action = "EventManagerService.modify")]
bool modify(int id, string field, string newValue);

C# XML RPC 服务

 Uri _baseAddress = new Uri("http://localhost:8000/xmlrpc");
_eventManagerHost = new ServiceHost(typeof(EventManagerService), _baseAddress);
try
{
ServiceEndpoint epXmlRpc = _eventManagerHost.AddServiceEndpoint(typeof(IEventManagerWCF_XML_RPC), new WebHttpBinding(WebHttpSecurityMode.None), "EventManagerService");
epXmlRpc.Behaviors.Add(new XmlRpcEndpointBehavior());

ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
_eventManagerHost.Description.Behaviors.Add(smb);
_eventManagerHost.Open();
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
_eventManagerHost.Abort();
}

我想这里没什么特别的。让我们继续学习 Java 代码!

Java 客户端

XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
try {
config.setServerURL(new URL("http://"+ip+":8000/xmlrpc/EventManagerService"));

}
catch (MalformedURLException e) {
e.printStackTrace();
}

config.setEnabledForExtensions(true);
config.setConnectionTimeout(60 * 1000);
config.setReplyTimeout(60 * 1000);
XmlRpcClient client = new XmlRpcClient();
client.setTransportFactory(new XmlRpcCommonsTransportFactory(client));
client.setConfig(config);
xmlRpcPeers.put(ip, client);

xmlRpcPeers 现在拥有不同的客户端。它们的名称如下;

for(XmlRpcClient peer : this.xmlRpcPeers.values())
{
try {
peer.execute("EventManagerService.modify", params);
} catch (Exception e) {
e.printStackTrace();
}
}

Java Server 有自己的类,并通过简单的 new 调用实例化;

public class Server extends Thread{

/**
* Server port
*/
private static final int port = 8000;

/**
* Starts the XML-RPC server
*/
public void run(){
WebServer webServer = new WebServer(port);
XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();

PropertyHandlerMapping phm = new PropertyHandlerMapping();
try
{
phm.addHandler("EventManagerService", lu.uni.binfo.ds.EventManager_Java.EventManagerService.class);
}
catch (XmlRpcException e1)
{
e1.printStackTrace();
}
xmlRpcServer.setHandlerMapping(phm);
XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
serverConfig.setEnabledForExtensions(true);
serverConfig.setContentLengthOptional(false);
try
{
webServer.start();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}

到目前为止,一切似乎都运行良好。将 Ruby 添加到组合中是最麻烦的。这是相关代码;

ruby 客户端Ruby 客户端也存储在字典中。它的填充如下;

@devices_XMLRPC[key] = EventManagerClient_XMLRPC.new(tokens[0]).device

类的代码是:

class EventManagerClient_XMLRPC
@uri
@device
attr_accessor :uri, :device

def initialize(uri)
@uri = uri
@device = XMLRPC::Client.new2(
uri="http://" << @uri.to_s << ":8000/xmlrpc/EventManagerService", proxy=nil, timeout=30)
end
end

同步修改的调用如下所示:

@devices_XMLRPC.each_value { |client| client.call("EventManagerService.modify", tokens[0], field, value) }

ruby 服务器

server = XMLRPC::Server.new(8000, "127.0.0.1")
server.add_handler("xmlrpc/EventManagerService", EventManagerService.instance)
puts "Server ready!"
server.serve

EventManagerService 类:

class EventManagerService
include Singleton
@manager

def initialize()
@manager = EventManager.instance
end

def modify(id, field, newValue)
puts "modify called"
@manager.modify([id, field, newValue], 1)
end

end

EventManager 是所有逻辑所在的类。

尝试从 C# 到 Ruby 通信时出现的错误是 EndPointNotFoundException,内容如下:

在 http://ip:8000/xmlrpc/EventManagerService 上没有监听可以接受消息的端点。[...]

我试着摆弄端点声明,但似乎无法让它工作。 Ruby 文档也无济于事。我需要帮助!

最佳答案

您可以尝试检查通过 WireShark 线路的流量.使用此工具,您将能够看到在不同应用程序之间传输的实际 HTTP 数据。也许这会提示您为什么在 Ruby 和 C# 之间通信时遇到问题。

关于c# - 使用 XML-RPC 编写以 C#、Ruby 和 Java 编写的分布式应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4008042/

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