Webservices In Unity

From Unify Community Wiki
Jump to: navigation, search

This will show you how to set up webservices and how to consume these services, and services from 3rd partys, from within Unity. It will also expand into using the Windows Communication Framework (WCF) which adds a lot of communication options, like JSON, built-in security and communicating directly over TCP/IP.

All code is written in C# on both the server and the client side.

Contents

Introduction

Using webservices you can talk to your webserver from within Unity using SOAP.

By using System.Web.Services, or System.Servicemodel for WCF, as well as some Mono utilities - wsdl and svcutil for generating service descriptions and xsp as a development webserver, we can call the webserver functions directly from within our clients and even receive complex .Net objects as a response.

Unfortunately, as an oversight (I hope), this is currently not possible from within the webplayer - only in standalone builds.

Requirements

All of the below is written with the assumption that you have Unity 3 installed, aswell as a separate installation of Mono 2.7.6. To host the webservices in a production environment you should use Apache and mod_mono or Microsoft IIS - whichever you prefer.

I have only tested this on Windows, but there should be nothing very system specific here.

Using ASP.NET services (.asmx)

We will start by using the webservices from System.Web.Services, as these are the simplest. It only gives us basic SOAP but for many cases this might be sufficient.

On the server side we will use what ASP.NET calls .asmx files, which contain the definition of the service. We will then use the Mono utility wsdl to automatically generate a source code file for the client.

Setting up the project

Create a new project and name it asmxtest. In your Assets folder, create a new folder and rename it to Plugins. To access the webservices we need some assemblies from Mono. In your Unity installation folder, go to the directory Editor/Data/Mono/lib/mono/2.0 and copy these two files to your new Plugins folder:

  • System.Web.dll
  • System.Web.Services.dll

In Unity, create a new scene. Inside your Assets folder, create a new folder and name it WebClient. Inside this folder, create a new C# script named ClientObject.cs. Add an Empty Gameobject and rename it to WebClient. Add the ClientObject.cs to the WebClient object, and save the scene.

We will also need to change the Mono compatibility setting in Unity. Go to your Player Settings (Edit->Project Settings->Player) and set the "API compatibility layer" to ".NET 2.0" (not Subset).

Also, in your project folder (not your Assets folder) create a new folder and name it WebServer. This will be where you place your webserver files - you can of course place it anywhere, but I prefer to keep it within the project while developing.

The webserver

Inside the WebServer directory, create the file MyService.asmx. Also create a directory named App_Code and inside it a file named MyService.asmx.cs.

The App_Code directory is where you place all the code for the webservices, while the root only holds the .asmx description files. Later, when you are ready for production, the .cs files can be compiled and placed inside a /bin directory instead.

MyService.asmx is the service description file. Here we define the service language (C#), and the class to use - in our case this is the class WebService.

In our code file, MyService.asmx.cs, we define the class WebService, and add the method Add which will simply add two integers and return the result. Note the decorators: [WebService] defines this class as a web-service, and [WebMethod] makes the method availiable to call from the client. Methods can be defined in this class without the [WebMethod] decorator - they will then not be callable by SOAP.

MyService.asmx

<%@ WebService Language="C#" Class="MyService"%>


MyService.asmx.cs

using System;
using System.Web.Services;
 
[WebService (Namespace = "http://tempuri.org/MyService")] // tempuri.org is the default, you should change this
public class MyService
{
	[WebMethod]
	public int Add(int a, int b)
	{
		return a+b;
	}
}


Testing the server

Now, lets test the server. Start a command shell (cmd) and change to the webserver directory. We will now use xsp to serve the pages, xsp can be found in your Mono installation directory (ex. C:\Program Files\Mono-2.6.7\bin). I reccomend you put this directory in your path.

Start the webserver from the command prompt:

> xsp

By default it will host the current directory on port 8080, so to see your web-server in action, start up a browser and point it to http://localhost:8080/MyService.asmx - Wohoo! It works!

You can now see all methods provided by this service, and even test them using the builtin web interface.

Consuming the service

Keep the webserver running for now, we will now automatically create a class for the client to use with the wsdl utility, which is also included in the Mono installation.

First, lets take a look at the system description that the server generates for this utility, point your browser to http://localhost:8080/MyService.asmx?wsdl - this will give you an xml file with the web-service description. It is this information that the wsdl utility uses to generate a C# file.

So lets get started, open up a new command prompt and change to your Unity project folder (asmxtest/Assets/WebClient). Run wsdl as follows:

> wsdl -out:MyService.cs http://localhost:8080/MyService.asmx?wsdl

This will create a file called MyService.cs which includes everything you need to call the webservice from within your Unity project (to see the parameters you can pass to the wsdl utility, run it without any arguments).

Open the file MyService.cs and take a look, but don't change anything.

Now, lets try consuming this service from within Unity. Remember the ClientObject.cs file you created earlier? Open it up and enter the following code.

ClientObject.cs

using UnityEngine;
using System;
using System.Collections;
 
public class ClientObject : MonoBehaviour
{
	void Start()
	{
        MyService service = new MyService();
        int n = service.Add(2,3);
        Debug.Log(n);
	}
}


You can now try to play the scene from Unity - keep an eye on the console.

What we do here is create a service object which is defined in the MyService.cs file, and we simply call the Add method on this object. This will connect to our webserver, call the function there, and return us the result. Magic!

I'm not going to go any further in how to write the webservices, but you should be able to expand on this easily, by for example adding database access and whatever you'd like.

There are also publically availiable webservices on the web that you can use, for example check out http://www.service-repository.com/

Using WCF

Lets move on to try using web services with the Windows Communication Framework. We can do the same things here as with the previous, but we get a lot more options - we can even write our service servers using sockets.

Setting up the project

Lets start again by creating an empty project, this time naming it wcftest. We will need some Mono assemblies for this as well, so create a Plugins folder inside your assets directory. Copy the following files from the Unity installation directory Editor/Data/Mono/lib/mono/2.0:

* System.Runtime.Serialization.dll 
* System.ServiceModel.dll

In Unity, create a new scene. Inside your Assets folder, create a new folder and name it WebClient. Inside this folder, create a new C# script named ClientObject.cs. Add an Empty Gameobject and rename it to WebClient. Add the ClientObject.cs to the WebClient object, and save the scene.

Again create a directory for the webserver in the project folder (not the Assets folder) naming it WebServer.

We will also for this need to change the Mono compatibility setting in Unity to “.NET 2.0″ in the Player Settings.

The webserver

The first thing we will need here is a config file, so create an empty file and name it web.config. Copy the below into the config file

web.config

<configuration>
  <system.serviceModel>
    <services>
      <service name="WebService" behaviorConfiguration="b">
        <endpoint binding="basicHttpBinding" contract="IWebService" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="b">
          <serviceMetadata httpGetEnabled="true" httpGetUrl="wsdl" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>


We will also need a service description file. This is similar to the .asmx file from above, but this time we'll name it MyService.svc. Notice that we define a Service and not a Class.

MyService.svc

<%@ServiceHost language="C#" Service="WebService"%>


Again for Mono to find the actual code, we need a directory named App_Code. We'll do it the "right way" and define a service interface, and then an implementation.

For the service interface, create a file named IMyService.cs in the App_Code directory with the following contents:

IMyService.cs

using System;
using System.Collections;
using System.ServiceModel;
 
[ServiceContract]
public interface IMyService
{
	[OperationContract]
	int Add(int n1, int n2);
}


You will notice we use decorators like we did with the .asmx implementation, however the names are a bit different. [ServiceContract] defines this interface as a service contract and [OperationContract] defines operations that should be part of this service contract.

Lets go on and create an implementation from this class, we will do this in the file MyService.cs:

MyService.cs

using System;
using System.Collections;
using System.ServiceModel;
 
public class MyService : IMyService
{
	public int Add(int n1, int n2)
	{
		return n1+n1;
	}
}


We will leave it at this for now, as you see we have only implemented the same service we did in .asmx. You can now start the webserver, open a command prompt, change to the webserver directory and run xsp

> xsp

Consuming the service

Unfortunately we don't get a nice webinterface for testing our service when using WCF as we do with asmx. Lets instead test it by writing a client in Unity.

We'll start by autogenerating some code with svcutil. Open a command prompt and run the command:

> svcutil -out:MyServiceClient.cs http://localhost:8080/MyService.svc/wsdl?wsdl

You should get a file MyServiceClient.cs - copy this to your Assets/WebClient directory. You can open this up and take a look if you'd like but you shouldn't need to change it.

Now let's edit the WebObject.cs file:

WebObject.cs

using UnityEngine;
using System;
using System.Collections;
using System.ServiceModel;
 
public class TestObject : MonoBehaviour
{
	void Start()
	{
		MyServiceClient client = new MyService(new BasicHttpBinding(),
			new EndpointAddress("http://localhost:8080/MyService.svc"));
		int n = client.Add(1,2);
		Debug.Log(n);
	}
}


Play your scene, you should now get the result of the add in the console.


I also posted this to my blog at http://randomrnd.com/2011/08/21/webservices-in-unity/ - if you have any questions or comments you can find me there. Steego 16:46, 21 August 2011 (PDT)

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox