While this article includes code snippets only, the full code sample is included with dot42. Install dot42 and then open the sample from [MyDocuments]\dot42\Samples\Network\WcfTodoService. The solution includes both a server (project TodoServer) and a client (project ClientApp).
Compile and run the server
The server is a Windows application. It can be found as project TodoServer in the WcfTodoService solution. Compile this app and run it with administrator rights. When you run it, it shows the following dialog:Start the service by hitting the 'Start Service' button. If you did not start the service with admin right, it will show you the following error:
To start with admin rights, compile the project and navigate to TodoServer.exe in folder \Network\WcfTodoService\Server\bin\Debug. Right-click the executable and select 'Run as administrator'. When you start the service, you should now see this:
The service uses port 9222, so make sure your firewall allows connections to it.
Shared files
The client and the server projects share the following files (these are in the WcfTodoService\Shared folder):
- TodoApi.xsd
- ITodoApi.cs
- TodoApi.cs (auto generated from TodoApi by xsd.exe)
TodoApi.xsd and ITodoApi.cs together make up the API specification of the REST service. ITodoApi.cs is the service contract file. It defines an interface and has WCF attributes applied. TodoApi.cs is generated using the following command:
xsd.exe /c /n:Dot42.TodoApi.Version_1_0 TodoApi.xsdThis generates classes from TodoApi.xsd that provide a rich object model for regular XML data.
Client
The client is a dot42 project and will run on your Android device. The UI code is really straightforward and in order to focus on WCF, we will skip it and discuss the code that invokes the service.The programming model is exactly the same as with traditional WCF, except that one option in the project properties has to be checked. With this option checked, dot42 will generate proxy classes for the service so there is no need to generate code at runtime.

All WCF client code in MainActivity.cs use WebChannelFactory to open a channel to the service and make requests to the underlying methods exposed by the contract:
private const string _hostAddress = "http://192.168.1.1:9222/RestService/TodoService"; private VersionType GetVersion() { using (var client = new WebChannelFactory<ITodoApi>( new WebHttpBinding(), new Uri(_hostAddress))) { client.Open(); var channel = client.CreateChannel(); using (new OperationContextScope((IContextChannel)channel)) { return channel.GetVersion(); } } }If you run the client on your Android device it will look like this:
How is the performance on this? I created a variant that lets me get an image over the service, but it seems it uses a long time to deserialize or something (5+ seconds for a 1920x1080 jpg). So I swapped it with code that read the picture stream directly from the wcf service as a picture stream.
ReplyDeleteAlso when I tried to send over any kind of byte arrays I got an error that seemed like it tried to convert the base64 encoded byte array as an int. "illegal int ('AAFSFSF==') or something. My first solution was to send over a prebase64 encoded string and decode it manually on the other side.