From Ruby Silverlight to Ruby Web Service (with a touch of spice)
After validating I could create a C# Silverlight client calling both document-style SOAP .net web service and an RPC-style SOAP Rails web service, it was time to move to the all-in-Ruby scenario.
The advantages such a scenario would bring include:
– increased developer productivity due to single end-to-end language experience
– greater leverage through the expressiveness and power of the Ruby language
– shorter cycle time due lack of compilation step (especially when running on the Silverlight-specific Chiron development web server)
– wider options in terms of class libraries, SDKs, and tools
So let’s look at what is needed to make the Ruby “all-the-way” option work:
1. The ability to leverage traditional .NET assemblies from Ruby.
2. The Silverlight ServiceModel stack (a subset of WCF, right-sized for the client).
IronRuby allows integration with the .NET platform – even using strongly-typed collections! Not bad for a dynamically typed language :-) !!!
The challenge is that the WCF approach requires the use of .NET attributes to “decorate” the contract definition.
[System.ServiceModel.OperationContractAttribute (AsyncPattern=true, Action="/ws_tst/api/GetTime", ReplyAction="*")]
Unfortunately IronRuby does not support that for the time being (still alpha).
So the solution for now is to:
1. Generate and tweak the web service proxy in C#,
2. Package it up in a small assembly
3. Copy the assembly in the Silverlight .xap package to the Silverlight app folder.
4. Add the assembly declaration to the AppManifest.xaml
[xaml]
[/xaml
Then, we can move on to the Silverlight client implementation:
1. Declare our web service proxy assembly and its namespaces
require "RorMonnetUsaComSoap" include RorMonnetUsaComSoap include RorMonnetUsaComSoap::RoRServiceReference
2. Instantiate the WCF client generated for our web service port
@svcproxy = WsTstWsTstPortClient.new()
3. Wire up an event handler for the asynchronous web service call (since Silverlight requires asynchronous calls)
@svcproxy.GetTimeCompleted { |sender, args| txtResults.text = args.result }
4. Wire up a button event handler to request the asynchronous web service call
btnTest.click { |sender, args| @svcproxy.GetTimeAsync() }
Summary:
require "Silverlight"
require "System"
require "System.ServiceModel"
require "RorMonnetUsaComSoap"
include System
include System::Net
include System::ServiceModel
include RorMonnetUsaComSoap
class App < SilverlightApplication
use_xaml
def initialize
@svcproxy = initializeServiceProxy()
# wire up web service callback
@svcproxy.GetTimeCompleted { |sender, args| handle_get_time_completed(sender, args) }
# wire up the button handler
btnTest.click { |sender, args| handle_btn_clicked(sender, args) }
end #initialize method
def initializeServiceProxy
txtResults.text = "Initializing the svc proxy ..."
proxy = RorMonnetUsaComSoap::RoRServiceReference::WsTstWsTstPortClient.new()
txtResults.text = "proxy initialized! ready!"
return proxy
end
def handle_btn_clicked(sender, args)
txtResults.text = "Ready to invoke the service ..."
@svcproxy.GetTimeAsync();
txtResults.text = "Going ..."
end
def handle_get_time_completed(sender, args)
txtResults.text = "Done! [" + args.result.to_s + "]"
end
end # App class
App.new
Et VoilĂ !




