Communication with server

Get

Get is getting data from web server. and new WWW("https://urlexample.com"); with a url but without a second parameter is doing a Get.

i.e.

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour 
{
    public string url = "http://google.com";
    
    IEnumerator Start() 
    {
        WWW www = new WWW(url); // One get.
        yield return www;
        Debug.Log(www.text); // The data of the url.
    }
}

Post (Upload A File)

Upload a file to server is also a post. You can easily upload a file through WWW, like the below:

Upload A Zip File To Server

string mainUrl = "http://server/upload/";
string saveLocation;

void Start() 
{
    saveLocation = "ftp:///home/xxx/x.zip"; // The file path.
    StartCoroutine(PrepareFile());
}

// Prepare The File.
IEnumerator PrepareFile() 
{
    Debug.Log("saveLoacation = " + saveLocation);
     
    // Read the zip file.
    WWW loadTheZip = new WWW(saveLocation);

    yield return loadTheZip;

    PrepareStepTwo(loadTheZip);
}

void PrepareStepTwo(WWW post) 
{
    StartCoroutine(UploadTheZip(post));
}

// Upload.
IEnumerator UploadTheZip(WWW post) 
{
    // Create a form.
    WWWForm form = new WWWForm();
 
    // Add the file.
    form.AddBinaryData("myTestFile.zip",post.bytes,"myFile.zip","application/zip");
 
    // Send POST request.
    string url = mainUrl;
    WWW POSTZIP = new WWW(url,form);
 
    Debug.Log("Sending zip...");
    yield return POSTZIP;
    Debug.Log("Zip sent!");
}

In this example, it use the coroutine to prepare and upload the file, if you want to know more about Unity coroutines, please visit Coroutines.

Sending a request to the server

There are many ways to communicate with servers using Unity as the client (some methodologies are better than others depending on your purpose). First, one must determine the need of the server to be able to effectively send operations to and from the server. For this example, we will send a few pieces of data to our server to be validated.

Most likely, the programmer will have setup some sort of handler on their server to receive events and respond back to the client accordingly - however that is out of the scope of this example.

C#:

using System.Net;
using System.Text;

public class TestCommunicationWithServer
{
    public string SendDataToServer(string url, string username, string password)
    {
        WebClient client = new WebClient();

        // This specialized key-value pair will store the form data we're sending to the server
        var loginData = new System.Collections.Specialized.NameValueCollection();
        loginData.Add("Username", username);
        loginData.Add("Password", password);

        // Upload client data and receive a response
        byte[] opBytes = client.UploadValues(ServerIpAddress, "POST", loginData);
    
        // Encode the response bytes into a proper string
        string opResponse = Encoding.UTF8.GetString(opBytes);

        return opResponse;
    }

First thing one must do is toss in their using statements which allow us to use the WebClient and NameValueCollection classes.

For this example the SendDataToServer function takes in 3 (optional) string parameters:

  1. Url of the server we're communicating with
  2. First piece of data
  3. Second piece of data we're sending to the server

The username and password is the optional data I am sending to the server. For this example we're using it to be then further validated from a database or any other external storage.

Now that we've setup our structure, we will instantiate a new WebClient to be used to actually send our data. Now we need to load our data into our NameValueCollection and upload the data to the server.

The UploadValues function takes in 3 necessary parameters as well:

  1. IP address of server
  2. HTTP method
  3. Data you're sending (the username and password in our case)

This function returns a byte array of the response from the server. We need to encode the returned byte array it into a proper string to actual be able to manipulate and dissect the response.

One could do something like this:

if(opResponse.Equals(ReturnMessage.Success))
{
    Debug.Log("Unity client has successfully sent and validated data on server.");
}

Now you might still be confused so I guess I will give a brief explanation of how to handle a response server sided.

For this example I will be using PHP to handle the response from the client. I'd recommend using PHP as your back-end scripting language because it's super versatile, easy to use and most of all fast. There definitely are other ways to handle a response on a server but in my opinion PHP is by far the simplest and easiest implementation into Unity.

PHP:

// Check to see if the unity client send the form data
if(!isset($_REQUEST['Username']) || !isset($_REQUEST['Password']))
{
    echo "Empty";
}
else
{ 
    // Unity sent us the data - its here so do whatever you want 
  
    echo "Success";
   
}

So this is the most important part - the 'echo'. When our client uploads the data to server, the client saves the response (or resource) into that byte array. Once the client has the response, you know the data has been validated and you can move on in the client once that event has happened. You also need to think about what type of data you're sending (to an extent), and how to minimize the amount you're actually sending.

So this is only one way of sending/receiving data from Unity - there are some other ways that may be more effective for you depending on your project.

Simple Post (Post Fields)

Every instance of WWW with a second parameter is a post.

Here is an example to post user id and password to server.

void Login(string id, string pwd)
{
    WWWForm dataParameters = new WWWForm();    // Create a new form.
    dataParameters.AddField("username", id); 
    dataParameters.AddField("password", pwd);   // Add fields.
    WWW www = new WWW(url+"/account/login",dataParameters);
    StartCoroutine("PostdataEnumerator", www);
}

IEnumerator PostdataEnumerator(WWW www)
{
    yield return www;
    if (!string.IsNullOrEmpty(www.error))
    {
        Debug.Log(www.error);
    }
    else
    {
        Debug.Log("Data Submitted");
    }
}