I have been instructed to write a distributed event management tool where every client, whether Ruby, C # or Java Client, synchronizes all changes with a list of registered clients. I have to use XML-RPCto achieve the goal. My team and I wrote a client and server XML-RPCin each language and provide the appropriate source code below. If you need more code, please let me know.
The problem is that I can get Java and C # to communicate with each other. Ruby can communicate with others, but C # (and possibly Java, have not tested it yet) have problems accessing the Ruby server. I think the problem is with the endpoint. First let me give you the code. When reading, please keep in mind that the code is actually written by the command, and the naming conventions are slightly different:
C # Client
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();
_proxywill not contain a client for this URI. They are stored in the dictionary and are used when there is a need to synchronize events. One such synchronization will occur in case of modification;
foreach(IEventManagerWCF_XML_RPC proxy in this.peers.Values)
proxy.modify(_id, _field, _newValue);
Here is an excerpt from the IEventManagerWCF_XML_RPC interface;
[OperationContract(Action = "EventManagerService.modify")]
bool modify(int id, string field, string newValue);
C # XML RPC Service
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();
}
Nothing special here, I think. Let's move on to the Java code!
Java client
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);
xmlRpcPeersnow contains different clients. They are called as follows:
for(XmlRpcClient peer : this.xmlRpcPeers.values())
{
try {
peer.execute("EventManagerService.modify", params);
} catch (Exception e) {
e.printStackTrace();
}
}
Java new;
public class Server extends Thread{
private static final int port = 8000;
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 , .
# Ruby - EndPointNotFoundException, :
There was no endpoint listening at http://ip:8000/xmlrpc/EventManagerService that could accept the message.[...]
, . Ruby . !