Unable to receive data from PHP in unity - c#

I have this script to interact with my database which is on mySql
string dataSubmitURL = "http://localhost/HighScore/AddScore.php?";
string dataGetURL = "http://localhost/HighScore/GetScore.php?";
// Use this for initialization
void Start () {
StartCoroutine(GetScores());
}
// Update is called once per frame
void Update () {
}
IEnumerator PostScores(string playerName, int score) {
string submitURL = dataSubmitURL + "name="+ playerName + "&score=" + score;
print(submitURL);
WWW submitData = new WWW(submitURL);
yield return submitData;
if (submitData.error != null)
{
Debug.LogError("Error occur when Submitting data : " + submitData.error);
Debug.LogError("Error occur when Submitting data : " + submitData.text);
Debug.LogError("Error occur when Submitting data : " + submitData.responseHeaders);
//submitData.text
}
else {
print(" Submitted");
}
IEnumerator GetScores() {
WWW getData = new WWW(dataGetURL);
yield return getData;
if (getData.error != null)
{
Debug.LogError("There was an error getting the high score: " + getData.error);
}
else {
print(getData.text);
}
}
}
But the problem is i am getting
There was an error getting the high score: Empty reply from server
Although these both urls
string dataSubmitURL = "http://localhost/HighScore/AddScore.php?";
string dataGetURL = "http://localhost/HighScore/GetScore.php?";
working fine in browser when i directly put it. I also added this crossDomain.xml in my root folder so that it can accessible to all. What I am doing wrong.
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*"/>
</cross-domain-policy>

I don't know what was the problem all the code is correct and it works by changing the IP Address only.
string dataSubmitURL = "http://YouripAddress/HighScore/AddScore.php?";
string dataGetURL = "http://YouripAddress/HighScore/GetScore.php?";

Related

Issues with Cefsharp and foreach loop

I'm new to working with async and I'm trying to build a Cefsharp application that collects data from an external API, stores it in local variables and then exports these through JavaScript to HTML. It's not a beautiful implementation and I'm sure my code is pretty awful but here goes:
My application performs a tick every 5 seconds, where it executes a HTTP Post request and stores the result in a QuickType (app.quicktype.io) list. This is the tick:
private async void timer1_Tick(object sender, EventArgs e)
{
await chromeBrowser.WaitForInitialLoadAsync();
if (httpPost.ConnectionSuccesful())
{
var devtoolsContext = await chromeBrowser.CreateDevToolsContextAsync();
var postResult = await httpPost.SendPost("robot_info");
try {
var result = Welcome.FromJson(postResult);
foreach (var robot in result.Result.Robots.Select((value, i) => (value, i)))
{
Console.WriteLine(robot.value.Id);
if (robot.value.ChargingStateCode == 9 || robot.value.ChargingStateCode == 12)
await devtoolsContext.EvaluateFunctionAsync("function setBatteryCharge() { var batteryLevel = jQuery('#robot" + robot.i + "Charge'); batteryLevel.css('width', "+ robot.value.StateOfCharge + " + '%'); batteryLevel.text('Charging'); batteryLevel.addClass('high'); batteryLevel.removeClass('medium'); batteryLevel.removeClass('low'); }");
else if (robot.value.StateOfCharge > 75)
await devtoolsContext.EvaluateFunctionAsync("function setBatteryHigh() { var batteryLevel = jQuery('#robot" + robot.i + "Charge'); batteryLevel.css('width', " + robot.value.StateOfCharge + " + '%'); batteryLevel.text(" + robot.value.StateOfCharge + " + '%'); batteryLevel.addClass('high'); batteryLevel.removeClass('medium'); batteryLevel.removeClass('low'); }");
else if (robot.value.StateOfCharge >= 50)
await devtoolsContext.EvaluateFunctionAsync("function setBatteryMedium() { var batteryLevel = jQuery('#robot" + robot.i + "Charge'); batteryLevel.css('width', " + robot.value.StateOfCharge + " + '%'); batteryLevel.text(" + robot.value.StateOfCharge + " + '%'); batteryLevel.addClass('medium'); batteryLevel.removeClass('high'); batteryLevel.removeClass('low'); }");
else
await devtoolsContext.EvaluateFunctionAsync("function setBatteryLow() { var batteryLevel = jQuery('#robot" + robot.i + "Charge'); batteryLevel.css('width', " + robot.value.StateOfCharge + " + '%'); batteryLevel.text(" + robot.value.StateOfCharge + " + '%'); batteryLevel.addClass('low'); batteryLevel.removeClass('high'); batteryLevel.removeClass('medium'); }");
}
}
catch (ArgumentNullException Nex) {
Console.Write("[Error] - " + Nex.Message);
}
catch (Exception ex)
{
Console.WriteLine("[Error] - " + ex.Message);
}
}
else
Console.WriteLine("[Error] - Check connection or access to API server.");
}
I'm currently trying to update the battery level and it successfully does this for the first tick (the JavaScript works as intended and both the css, classes and text is changed). Then it stops working. I've checked that the correct results are coming in from the HTTP Post and that the data is stored properly in the local variables. The problem seems to occur in the foreach. I've tried to read up about async a bit but I can't seem to find the culprit. After the first execution of the code, something seems to be blocking the iteration of the for each. I'm using Cefsharp.Winforms and Cefsharp.Puppeteer.
Any idea on why this is happening? Also thankful for any pointers or tips on how to improve the code.
EDIT: This is the Console Output
[Query] Sending post request to xxx with method 'robot_info'
[Success] - API Post Request was succesful.
PR1#11
PR1#15
[Query] Sending post request to xxx with method 'robot_info'
[Success] - API Post Request was succesful.
PR1#11
[Query] Sending post request to xxx with method 'robot_info'
[Success] - API Post Request was succesful.
PR1#11
The first iteration goes through fine.
EDIT2: This is the timer
public void InitTimer()
{
timer1 = new Timer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 5000;
timer1.Start();
}
EDIT3: Method SendPost
public async Task<string> SendPost(string method)
{
HttpClient httpClient = new HttpClient();
string data = new JavaScriptSerializer().Serialize(new
{
jsonrpc = "2.0",
method = method,
id = Guid.NewGuid().ToString()
});
StringContent content = new StringContent(data, System.Text.Encoding.UTF8, "application/json");
try
{
Console.WriteLine("[Query] Sending post request to " + url.ToString() + " with method '" + method + "'");
HttpResponseMessage response = await httpClient.PostAsync(url, content).ConfigureAwait(false);
string result = await response.Content.ReadAsStringAsync();
if (IsValidJson(result))
{
Console.WriteLine("[Success] - API Post Request was succesful.");
return result;
}
else
return null;
} catch (HttpRequestException hre)
{
Console.WriteLine("[Error]: " + hre);
return null;
}
}
EDIT4: Structure of Welcome
public partial class Welcome
{
[JsonProperty("jsonrpc")]
public string Jsonrpc { get; set; }
[JsonProperty("result")]
public Result Result { get; set; }
[JsonProperty("id")]
public string Id { get; set; }
}
public partial class Result
{
[JsonProperty("timestamp")]
public long Timestamp { get; set; }
[JsonProperty("robots")]
public List<Robot> Robots { get; set; }
}
Robots is a list with a bunch of longs and ints.

Retrieve data in nested for Firebase Realtime Database (Unity C#)

I wanted to retrieve data and link that I put in a nested inside Firebase but I receive an error:
System.Collections.Generic.Dictionary`2[System.String,System.Object][]
I hope there's anyone who can help me solve this issue.
Here is the firebase nested looks like
Here is the code
private IEnumerator LoadCourse_1()
{
//Get the currently logged in user data
var DBTask = DBreference.Child("Course").Child("MDR3005").GetValueAsync();
yield return new WaitUntil(predicate: () => DBTask.IsCompleted);
if (DBTask.Exception != null)
{
Debug.LogWarning(message: $"Failed to register task with {DBTask.Exception}");
}
else if (DBTask.Result.Value == null)
{
//No data exists yet
Course1.text = "-";
Course1CodeName.text = "-";
}
else
{
//Data has been retrieved at dashboard
DataSnapshot snapshot = DBTask.Result;
Course1.text = snapshot.Child("CourseCode").Value.ToString() + ": " + snapshot.Child("CourseName").Value.ToString() ;
//Data retrieve for course data
Course1CodeName.text = snapshot.Child("CourseCode").Value.ToString() + "\n" + snapshot.Child("CourseName").Value.ToString();
TM1.text = snapshot.Child("Notes").Value.ToString();
}
}

lidgren client cannot connect after disconnecting

I'm using Lidgren to connect a unity game to a gameserver. everything works fine. the only problem is when the client disconnects from the server (by loss of internet connection or even manually) it cannot connect again. I have to close and reopen the game to be able to connect again. I have tried this outside the unity too and got the same results:
connection method is like this:
public IEnumerator Connect()
{
m_Client.Start();
var hail = m_Client.CreateMessage();
AuthRequest id = new AuthRequest()
{
Name = PlayerSettings.Name,
};
hail.Write(new Packet(PacketType.AuthRequest, id).SerializePacket());
m_Client.Connect(k_ServerAddress, k_Port, hail);
Debug.Log("Connecting " + id.Name + " to " + k_ServerAddress + ":" + k_Port);
NetConnectionStatus status = m_Client.ConnectionStatus;
while (m_Client.ConnectionStatus != NetConnectionStatus.Disconnected)
{
if (m_Client.ConnectionStatus != status)
{
status = m_Client.ConnectionStatus;
Debug.Log("Status: " + status);
}
yield return null;
}
}
If I use this code:
LidgrenClient m_Client = new LidgrenClient();
m_Client.Connect();
the client gets connected, but when the client gets disconnected from the server the update method below just logs Trying to Reconnect every 5 minutes but actually does nothing:
void Update()
{
if (!waiting && !m_Client.Connected)
{
Debug.Log("Trying to Reconnect");
StartCoroutine(TryReconnect());
}
m_Client.ReadMessages();
}
IEnumerator TryReconnect()
{
waiting = true;
m_Client.Connect();
yield return new WaitForSeconds(5f);
waiting = false;
}

Delay in accessing recently added data via Web Server [duplicate]

I am creating a HoloLens app using Unity which has to take data from a REST API and display it.
I am currently using WWW datatype to get the data and yield return statement in a coroutine that will be called from the Update() function. When I try to run the code, I get the latest data from the API but when someone pushes any new data onto the API, it does not automatically get the latest data in real time and I have to restart the app to see the latest data.
My Code:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
public class TextChange : MonoBehaviour {
// Use this for initialization
WWW get;
public static string getreq;
Text text;
bool continueRequest = false;
void Start()
{
StartCoroutine(WaitForRequest());
text = GetComponent<Text>();
}
// Update is called once per frame
void Update()
{
}
private IEnumerator WaitForRequest()
{
if (continueRequest)
yield break;
continueRequest = true;
float requestFrequencyInSec = 5f; //Update after every 5 seconds
WaitForSeconds waitTime = new WaitForSeconds(requestFrequencyInSec);
while (continueRequest)
{
string url = "API Link goes Here";
WWW get = new WWW(url);
yield return get;
getreq = get.text;
//check for errors
if (get.error == null)
{
string json = #getreq;
List<MyJSC> data = JsonConvert.DeserializeObject<List<MyJSC>>(json);
int l = data.Count;
text.text = "Data: " + data[l - 1].content;
}
else
{
Debug.Log("Error!-> " + get.error);
}
yield return waitTime; //Wait for requestFrequencyInSec time
}
}
void stopRequest()
{
continueRequest = false;
}
}
public class MyJSC
{
public string _id;
public string author;
public string content;
public string _v;
public string date;
}
This is happening because resources caching is enabled on the Server.
Three possible solutions I know about:
1.Disable resources caching on the server. Instructions are different for every web server. Usually done in .htaccess.
2.Make each request with unique timestamp. The time should in Unix format.
This method will not work on iOS. You are fine since this is for HoloLens.
For example, if your url is http://url.com/file.rar, append ?t=currentTime at the end. currentTime is the actual time in Unix Format.
Full example url: http://url.com/file.rar?t=1468475141
Code:
string getUTCTime()
{
System.Int32 unixTimestamp = (System.Int32)(System.DateTime.UtcNow.Subtract(new System.DateTime(1970, 1, 1))).TotalSeconds;
return unixTimestamp.ToString();
}
private IEnumerator WaitForRequest()
{
string url = "API Link goes Here" + "?t=" + getUTCTime();
WWW get = new WWW(url);
yield return get;
getreq = get.text;
//check for errors
if (get.error == null)
{
string json = #getreq;
List<MyJSC> data = JsonConvert.DeserializeObject<List<MyJSC>>(json);
int l = data.Count;
text.text = "Data: " + data[l - 1].content;
}
else
{
Debug.Log("Error!-> " + get.error);
}
}
3.Disable Cache on the client side by supplying and modifying the Cache-Control and Pragma headers in the request.
Set Cache-Control header to max-age=0, no-cache, no-store then set Pragma header to no-cache.
I suggest you do this with UnityWebRequest instead of the WWW class. First, Include using UnityEngine.Networking;.
Code:
IEnumerator WaitForRequest(string url)
{
UnityWebRequest www = UnityWebRequest.Get(url);
www.SetRequestHeader("Cache-Control", "max-age=0, no-cache, no-store");
www.SetRequestHeader("Pragma", "no-cache");
yield return www.Send();
if (www.isError)
{
Debug.Log(www.error);
}
else
{
Debug.Log("Received " + www.downloadHandler.text);
}
}

Script push from C# to Php not working on application

Okay I am using Unity To create my application and MSSQL for the database in between them both i have a PHP Exchange server.
So basically I am having a problem with this piece of code
using UnityEngine;
using System.Collections;
public class NewSession : MonoBehaviour {
string userLoginFile = "http://"ServerIP"/UnitySQL/NewSession.php?";
public UnityEngine.UI.Text NewSess;
string userid = "";
string session = "";
void OnGUI()
{
session = NewSess.text;
userid = PlayerPrefs.GetString ("UserId");
}
public void Insert()
{
if (session == "") {
StartCoroutine (LoginUser (userid));
} else {
print("DAMNSON");
}
}
IEnumerator LoginUser(string user)
{
WWW login = new WWW (userLoginFile + "UserId=" + user);
print (userLoginFile + "UserId=" + user);
yield return login;
if (login.error == null)
{
string[] credentials = login.text.Split('/');
foreach(string str in credentials)
{
string[] creds = str.Split ('=');
for(int i=0; i < creds.Length; i++)
{
print ("winner");
}
}
}
}
}
Now I don't know why its having this problem because it works fine when i use localhost and have the php exchange on my server i can clearly see the scripts print is correct because if i copy and paste that into the address header it does what its supposed to no problem.
Here is the PHP Script
<?php
$userid = $_REQUEST['UserId'];
$user = 'user';
$pass = 'Pass';
$server = 'IP';
$database = 'MyTable';
// No changes needed from now on
$connection_string = "DRIVER={SQL Server};SERVER=$server;DATABASE=$database";
$conn = odbc_connect($connection_string,$user,$pass);
/*$q = "DECLARE #return_value int
EXEC #return_value = [dbo].[InsertAnswersCheck]
#varQuestionOptionId = '$QOI',
#varUser = '$userid'
SELECT 'Return Value' = #return_value";*/
$q = "INSERT INTO usersession (UserId) VALUES ($userid)";
$result = odbc_exec($conn,$q);
$num_rows = odbc_num_rows($result);
if($num_rows > 0)
{
} else {
}
?>
It's been a problem for sometime but i cant figure out what is wrong. If anyone can help that would be fantastic.
Please Note It works with the same script on my localhost if set it will require the user to login twice. But when i do it on the server script it will just stick you in a loop until you copy and paste the print code.
I don't know, but you could try:
Open in browser whatever your print (userLoginFile + "UserId=" + user); prints out.
Put print(login.text); after yield return login; (inside the next if).
Put else you your if (login.error == null) with print("Err: " + "login.error.ToString());
I don't see any echo in your PHP script.
Output form 1 and 2 should be identical.

Categories