WWW data acquisition from remote server failing

I’ve started using LitJSON for my processing needs, and (quickly) built a Net Access layer to acquire data from a remote source. My Net Access Layer looks like this:

NET Access Layer

using UnityEngine;
using System;
using System.Collections;
using LitJson;

[Serializable]
public class ServerConnector : IDisposable
{
#region Variables / Properties

public string Address { get; private set; }
public bool AssetAcquired { get; private set; }
private WWW _payload;

#endregion Variables / Properties

#region Constructor

public ServerConnector(string address)
{
	if(string.IsNullOrEmpty(address))
		throw new ArgumentNullException("address");
	
	Address = address;
	DownloadPayload();
}

#endregion Constructor

#region Static Methods

public static T UnpackJSONFromSource< T >(string address)
{
	if(string.IsNullOrEmpty(address))
		throw new ArgumentNullException("address");
	
	T result = default(T);
	using(ServerConnector connector = new ServerConnector(address))
	{
		if(connector.AssetAcquired)
		{
			result = connector.UnpackJSON< T >();
		}
	}
	
	return result;
}

#endregion Static Methods

#region Methods

public void Dispose()
{
	if(_payload != null)
		_payload = null;
}
		
public string GetTextData()
{
	return _payload.text;
}

public T UnpackJSON< T >()
{
	Debug.Log("Payload: " + _payload);
	T result = JsonMapper.ToObject< T >(_payload.text);
	return result;
}

private IEnumerator DownloadPayload()
{	
	_payload = new WWW(Address);
	yield return _payload;
	
	if(_payload == null)
	{
		Debug.LogError("Failed to get the payload.");
		AssetAcquired = false;
		return true;
	}

	if(_payload.error != null)
	{
		Debug.LogError("Error occurred during download from " + Address + ": " + _payload.error);
		AssetAcquired = false;
	}
	else
	{
		AssetAcquired = true;
	}
}

#endregion Methods
}

Naturally, to test that this is working correctly, I created a single game object in a scene, with the following behavior:

Test Behavior

using UnityEngine;
using System.Collections;

public class NetLayerTest : MonoBehaviour 
{	
#region Variables / Properties

private ServerConnector _connector;
private string _secretMessage = "The secret message was not found or acquired.";

#endregion Variables / Properties

void Start () {
	_connector = new ServerConnector("http://andrewrgray.webs.com/dataz/test-data.json");
	
	Debug.Log("Address for download: " + _connector.Address);
	if(_connector.AssetAcquired)
		_secretMessage = _connector.UnpackJSON();
	
	Debug.Log(_secretMessage);
}
 }

However, I notice whenever I start up in my test scene that I always get the Debug messages, “Failed to get the payload.”, and “The secret message was not found or acquired.” Long story short, my usage of WWW isn’t getting any results!

I’ve made sure that the URL pointing to this JSON resource is correct (in fact, here it is), and that my usage of the WWW class in the Net Access layer is correct. I’m running my project in the editor, so I doubt that any interference from building as a webplayer is occurring (though, to rule that I out, I changed to a PC Any CPU build to be sure.)

Obviously, I am doing something totally wrong. The question is: what?

A note: This is my first time using WWW, so I made sure to consult the documentation first, and it did not yield enough information for me to discover the cause of the problem.

Try checking if (_payload.text == null) in your Coroutine.

“This is a test of the Net Layer Access system. If I can see this, I succeeded.”

Works for me. :wink:

iwaldrop set me on the correct path; my problem was that as the MonoBehaviour wasn’t working with the coroutines, nothing was working as intended. As such, I altered my setup as below:

ServerConnector Class

[Serializable]
public class ServerConnector : IDisposable
{
#region Variables / Properties
 
public string Address { get; private set; }
public bool AssetAcquired { get; private set; }
private WWW _payload;
 
#endregion Variables / Properties
 
#region Constructor
 
public ServerConnector(string address)
{
    if(string.IsNullOrEmpty(address))
       throw new ArgumentNullException("address");
 
    Address = address;
}
 
#endregion Constructor
 
#region Methods
 
public void Dispose()
{
    if(_payload != null)
       _payload = null;
}
 
public string GetTextData()
{
    return _payload.text;
}
 
public T UnpackJSON()
{
    Debug.Log("Payload: " + _payload);
    T result = JsonMapper.ToObject(_payload.text);
    return result;
}
 
public IEnumerator DownloadPayload()
{   
    _payload = new WWW(Address);
    yield return _payload;
 
    if(_payload == null)
    {
       Debug.LogError("Failed to get the payload.");
       AssetAcquired = false;
       return true;
    }
 
    if(_payload.error != null)
    {
       Debug.LogError("Error occurred during download from " + Address + ": " + _payload.error);
       AssetAcquired = false;
    }
    else
    {
       AssetAcquired = true;
    }
}
 
#endregion Methods
}

Test Behavior

public class NetLayerTest : MonoBehaviour 
{	
#region Variables / Properties

public string URL = "http://andrewrgray.webs.com/dataz/test-data.json";
private ServerConnector _connector;
private string _secretMessage = "The secret message was not found or acquired.";

#endregion Variables / Properties

#region Methods

IEnumerator Start () 
{
	_connector = new ServerConnector(URL);
	yield return StartCoroutine(_connector.DownloadPayload());
	
	if(_connector.AssetAcquired)
		_secretMessage = _connector.GetTextData();
	
	Debug.Log(_secretMessage);
}

#endregion Methods
}

While telling the utility class in the constructor who the calling MonoBehaviour is was a great idea, the problem is that the actual data access took 0.02s…longer than it took for the behavior to determine that the data had not been retrieved. It was impossible for me to get around moving the coroutine call to the actual behavior.

Once that happened, though, the rest fell into place!