title: Programming a distributed application written in C#, Ruby and Java using XML-RPC
body: <p>I am tasked with writing a distributed event managing tool where each client, either a Ruby, C# or Java Client, synchronises all changes with a list of registered clients. I have to use <code>XML-RPC</code> to achieve the goal. My team and I have written up an <code>XML-RPC</code> client and server in each language and will provide the relevant source code below. If you require more code, please let me know.</p>
  
  <p>The problem is that I can get Java and C# to communicate with each other. Ruby can communicate with the others but C# (and maybe Java, haven't tested yet) have problems addressing the Ruby server. I guess the problem is with the Endpoint. First let me give you some code. When reading please be aware that the code is actually written by a team and naming conventions differ a bit:</p>
  
  <p><strong>C# client</strong></p>
  
  <pre><code>Uri _address = new Uri("http://" + _s + ":8000/xmlrpc/EventManagerService");
  ChannelFactory&lt;IEventManagerWCF_XML_RPC&gt; _factory = new ChannelFactory&lt;IEventManagerWCF_XML_RPC&gt;(new WebHttpBinding(WebHttpSecurityMode.None), new EndpointAddress(_address));
  _factory.Endpoint.Behaviors.Add(new XmlRpcEndpointBehavior());
  IEventManagerWCF_XML_RPC _proxy = _factory.CreateChannel();
  </code></pre>
  
  <p><code>_proxy</code> will not hold the client for a given URI. Those are stored in a dictionary and used when the need arises to synchronise events. One such synchronisation would happen in the case of a modification;</p>
  
  <pre><code> foreach(IEventManagerWCF_XML_RPC proxy in this.peers.Values)
          proxy.modify(_id, _field, _newValue);
  </code></pre>
  
  <p>Here is an extract from the IEventManagerWCF_XML_RPC interface;</p>
  
  <pre><code> [OperationContract(Action = "EventManagerService.modify")]
   bool modify(int id, string field, string newValue);
  </code></pre>
  
  <p><strong>C# XML RPC service</strong></p>
  
  <pre><code> 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();
       }
  </code></pre>
  
  <p>Nothing special here I guess. Lets move on to the Java code!</p>
  
  <p><strong>Java Client</strong></p>
  
  <pre><code>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); 
  </code></pre>
  
  <p><code>xmlRpcPeers</code> now holds the different clients. They are called as follows;</p>
  
  <pre><code>for(XmlRpcClient peer : this.xmlRpcPeers.values())
    {
     try {
      peer.execute("EventManagerService.modify", params);
     } catch (Exception e) {
      e.printStackTrace();
     }
    }
  </code></pre>
  
  <p>The <strong>Java Server</strong> has it's own class and is instantiated with a simple <code>new</code> call;</p>
  
  <pre><code>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();
        }
     }
  }
  </code></pre>
  
  <p>Up till now everything seemed to work fine. Adding Ruby to the mix is what gives the most trouble. Here is the relevant code;</p>
  
  <p><strong>Ruby Client</strong>
  Ruby clients are also stored in a dictionary. It is populated as follows;</p>
  
  <pre><code>@devices_XMLRPC[key] = EventManagerClient_XMLRPC.new(tokens[0]).device
  </code></pre>
  
  <p>The code for the class is:</p>
  
  <pre><code>class EventManagerClient_XMLRPC
    @uri
    @device
    attr_accessor :uri, :device
  
    def initialize(uri)
      @uri = uri
      @device = XMLRPC::Client.new2(
              uri="http://" &lt;&lt; @uri.to_s &lt;&lt; ":8000/xmlrpc/EventManagerService", proxy=nil, timeout=30)
    end
  end
  </code></pre>
  
  <p>A call to synchronise on modifications looks like this:</p>
  
  <pre><code>@devices_XMLRPC.each_value { |client| client.call("EventManagerService.modify", tokens[0], field, value) }
  </code></pre>
  
  <p><strong>Ruby Server</strong></p>
  
  <pre><code>server = XMLRPC::Server.new(8000, "127.0.0.1")
  server.add_handler("xmlrpc/EventManagerService", EventManagerService.instance)
  puts "Server ready!"
  server.serve
  </code></pre>
  
  <p>The EventManagerService class:</p>
  
  <pre><code>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
  </code></pre>
  
  <p><code>EventManager</code> being the class where all the logic resides.</p>
  
  <p>The error when trying to communicate from C# to Ruby is an <code>EndPointNotFoundException</code> that reads:</p>
  
  <p><code>There was no endpoint listening at http://ip:8000/xmlrpc/EventManagerService that could accept the message.[...]</code></p>
  
  <p>I tried fiddling around with the endpoint declaration but cannot seem to get it to work. The Ruby documentation does not help either. I am in need of help!</p>