i have a problem with titanium to comunicate with a my server in the network,
the server's ip is 192.168.0.208 on the port 8000 (is a Node.js server).
If i call the server from the browser no problem but if i try to call the server from the application in Titanium i saw this error "The target server failed to respond" and in the server log no call is received
this is my network.js file in the application
function HttpRequest(url, type, args, functionOnSuccss,functionOnError,timeout) {
// args is json parameters OPTIONAL
Ti.API.log("[HTTP REQ] Call" + url);
// ---# ok string ------
var xhr = Titanium.Network.createHTTPClient();
xhr.open(type,url);
xhr.cache = false;
xhr.enableKeepAlive = false;
xhr.timeout = timeout ? timeout : 500000;
xhr.setRequestHeader("Content-type", "application/json");
// xhr.setRequestHeader("Cookie", 'JSESSIONID=' + cookie + '');
xhr.onload = function(e) {
Ti.API.info("[HTTP] Response" + this.responseText);
functionOnSuccss(this.responseText);
};
xhr.onerror = function(e) {
Ti.API.info("ERROR " + e.error);
// alert("Connection Error");
functionOnError(e.error);
};
if(args){
xhr.send(args);
}else{
xhr.send();
}
};
exports.request = HttpRequest;
and this is the coda that make the request
network = require('/library/network');
var sendCarrello = function() {
$.loader.visible = true;
$.carrelloCamminante.animate(a);
url = "192.168.0.208:8000/newMobileUser"; // or http://192.168.0.208:8000/newMobileUser it's the same
network.request(url, "get",undefined, function(resp) {
alert(resp);
$.loader.visible = false;
}, function(err) {
alert("error - "+""+err);
});
};
what could be the error?
You must use "GET" not "get" :
network.request(url, "GET",undefined, function(resp) { ....
Related
How can I send HTTP GET and POST requests in C# with Unity?
What I want is:
send json data in post request (I use Unity serializer, so no need in
new one, I just want to pass string in post data and have ability to
set ContentType to application/json);
get response code and body without any problems;
do it all asynchronous without blocking ui rendering.
What I've tried:
implementing with HttpWebRequest/HttpWebResponse, but it's too hard and low level (if I won't found anything better, I'll have to use it);
using unity WWW, but it doesn't match my requirements;
using some external packages from NuGet - Unity don't accept them :(
Most problems were with threading, I'm not experienced enough in it in C#.
IDE, I use, is Intellij Rider.
The WWW API should get this done but UnityWebRequest replaced it so I will answer the newer API. It's really simple. You have to use coroutine to do this with Unity's API otherwise you have have to use one of C# standard web request API and Thread. With coroutine you can yield the request until it is done. This will not block the main Thread or prevent other scripts from running.
Note:
For the examples below, if you are using anything below Unity 2017.2, replace SendWebRequest() with Send() and then replace isNetworkError with isError. This will then work for the lower version of Unity. Also, if you need to access the downloaded data in a binary form instead, replace uwr.downloadHandler.text with uwr.downloadHandler.data. Finally, the SetRequestHeader function is used to set the header of the request.
GET request:
void Start()
{
StartCoroutine(getRequest("http:///www.yoururl.com"));
}
IEnumerator getRequest(string uri)
{
UnityWebRequest uwr = UnityWebRequest.Get(uri);
yield return uwr.SendWebRequest();
if (uwr.isNetworkError)
{
Debug.Log("Error While Sending: " + uwr.error);
}
else
{
Debug.Log("Received: " + uwr.downloadHandler.text);
}
}
POST request with Form:
void Start()
{
StartCoroutine(postRequest("http:///www.yoururl.com"));
}
IEnumerator postRequest(string url)
{
WWWForm form = new WWWForm();
form.AddField("myField", "myData");
form.AddField("Game Name", "Mario Kart");
UnityWebRequest uwr = UnityWebRequest.Post(url, form);
yield return uwr.SendWebRequest();
if (uwr.isNetworkError)
{
Debug.Log("Error While Sending: " + uwr.error);
}
else
{
Debug.Log("Received: " + uwr.downloadHandler.text);
}
}
POST request with Json:
void Start()
{
StartCoroutine(postRequest("http:///www.yoururl.com", "your json"));
}
IEnumerator postRequest(string url, string json)
{
var uwr = new UnityWebRequest(url, "POST");
byte[] jsonToSend = new System.Text.UTF8Encoding().GetBytes(json);
uwr.uploadHandler = (UploadHandler)new UploadHandlerRaw(jsonToSend);
uwr.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
uwr.SetRequestHeader("Content-Type", "application/json");
//Send the request then wait here until it returns
yield return uwr.SendWebRequest();
if (uwr.isNetworkError)
{
Debug.Log("Error While Sending: " + uwr.error);
}
else
{
Debug.Log("Received: " + uwr.downloadHandler.text);
}
}
POST request with Multipart FormData/Multipart Form File:
void Start()
{
StartCoroutine(postRequest("http:///www.yoururl.com"));
}
IEnumerator postRequest(string url)
{
List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
formData.Add(new MultipartFormDataSection("field1=foo&field2=bar"));
formData.Add(new MultipartFormFileSection("my file data", "myfile.txt"));
UnityWebRequest uwr = UnityWebRequest.Post(url, formData);
yield return uwr.SendWebRequest();
if (uwr.isNetworkError)
{
Debug.Log("Error While Sending: " + uwr.error);
}
else
{
Debug.Log("Received: " + uwr.downloadHandler.text);
}
}
PUT request:
void Start()
{
StartCoroutine(putRequest("http:///www.yoururl.com"));
}
IEnumerator putRequest(string url)
{
byte[] dataToPut = System.Text.Encoding.UTF8.GetBytes("Hello, This is a test");
UnityWebRequest uwr = UnityWebRequest.Put(url, dataToPut);
yield return uwr.SendWebRequest();
if (uwr.isNetworkError)
{
Debug.Log("Error While Sending: " + uwr.error);
}
else
{
Debug.Log("Received: " + uwr.downloadHandler.text);
}
}
DELETE request:
void Start()
{
StartCoroutine(deleteRequest("http:///www.yoururl.com"));
}
IEnumerator deleteRequest(string url)
{
UnityWebRequest uwr = UnityWebRequest.Delete(url);
yield return uwr.SendWebRequest();
if (uwr.isNetworkError)
{
Debug.Log("Error While Sending: " + uwr.error);
}
else
{
Debug.Log("Deleted");
}
}
Use HttpClient and something like:
public static HttpContent DoPost(object payload, string subPath)
{
var httpClient = new HttpClient();
HttpClient.BaseAddress = new Uri(Global.BaseUrl);
HttpClient.DefaultRequestHeaders.Clear();
HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // if you're using json service
// make request
var response = Global.HttpClient.PostAsJsonAsync(subPath.TrimLeadingSlash(), payload).Result;
// check for error
response.EnsureSuccessStatusCode();
// return result
return response.Content;
}
Payload is an object to be serialized to json. If all requests are going to the same baseUrl, you can set up HttpClient globally, and reuse it here
https://www.patrykgalach.com/2019/04/18/how-to-call-rest-api-in-unity/
Please refer this link cleanest way to play with data
and do not use www instead of use UnityWebRequest
We can use WWW and UnityWebRequest classes to initiate API calls. WWW got obsolete now and Unity recommends using UnityWebRequest over WWW.
void Start() {
string url = "https://retrofit-backend-demo.herokuapp.com/book";
StartCoroutine(GetBooksUsingWWW(url));
StartCoroutine(GetBooksUsingUnityWebRequest(url));
}
IEnumerator GetBooksUsingWWW(string url) {
using (WWW www = new WWW(url)){
yield return www;
Debug.Log(www.text);
JSONNode jsonNode = JSON.Parse(www.text);
string title = jsonNode[0]["title"].ToString();
Debug.Log("Title: " + title);
}
}
IEnumerator GetBooksUsingUnityWebRequest(string url) {
UnityWebRequest www = UnityWebRequest.Get(url);
yield return www.SendWebRequest();
if(www.isNetworkError || www.isHttpError) {
Debug.Log(www.error);
}
else {
Debug.Log(www.downloadHandler.text);
JSONNode jsonNode = JSON.Parse(www.downloadHandler.text);
string title = jsonNode[0]["title"].ToString();
Debug.Log("Title: " + title);
}
}
For demo: https://github.com/codemaker2015/api-interaction-unity3d-demo
I have a problem with my app based on AWS. When I test the following function in Amazon lambda, everything works (I get the push notification on my phone):
console.log("Loading kupa function");
var AWS = require("aws-sdk");
exports.handler = function(event, context) {
var eventText = JSON.stringify(event, null, 2);
console.log("Received event:", eventText);
var sns = new AWS.SNS();
var params = {
Message: eventText,
Subject: "Test SNS From Lambda",
TopicArn: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
};
sns.publish(params, context.done);
context.succeed("kupa sukces");
};
However, once I use the following method on my phone I get the "kupa sukces" log into my Android Studio but I don't get the notification on the phone. Furthermore, the "Test" on Lambda does not work anymore as wel...
Here is the code:
String lambdaRequest = "{\n\"kupa\" : \"" + true + "\"\n}";
asyncTask.delegate = wysylaczKupy.this;
asyncTask.friendFunction("friendsRequest",lambdaRequest);
}
the friendFunction is here:
public static void friendFunction(String funName, String requestContent) {
final String functionName = funName;
final String requestPayload = requestContent;
new AsyncTask<Void, Void, InvokeResult>() {
#Override
protected InvokeResult doInBackground(Void... params) {
try {
final ByteBuffer payload =
ENCODER.encode(CharBuffer.wrap(requestPayload));
final InvokeRequest invokeRequest =
new InvokeRequest()
.withFunctionName(functionName)
.withInvocationType(InvocationType.RequestResponse)
.withPayload(payload);
final InvokeResult invokeResult =
AWSMobileClient
.defaultMobileClient()
.getCloudFunctionClient()
.invoke(invokeRequest);
return invokeResult;
} catch (final Exception e) {
Log.e("LAMBDA", "AWS Lambda invocation failed : " + e.getMessage(), e);
final InvokeResult result = new InvokeResult();
result.setStatusCode(500);
result.setFunctionError(e.getMessage());
return result;
}
}
}
How can I fix this?
Thank you in advance,
Jan
Jan,
The Lambda function for publishing to an SNS Topic wasn't quite right. I modified your function and provided a default json value for testing. Just put your TopicARN in and try it out. Once you have tested using the Lambda console, then try the Android code, which I did not try.
Note that when sending a JSON payload to an SNS Topic, a default value is required. The default value is used when you don't specify a protocol specific message. For example, you are publishing to an SNS Topic with Android GCM endpoints and since your JSON payload does not contain "GCM" then all endpoints will receive your default message that you provided.
I'm not sure what you were doing with "{\n\"kupa\" : \"" + true + "\"\n}" but I'm guessing the "kupa": "true" is intended to the the data key/value for the app to handle? If so, you'll need to lookup a proper GCM payload to send both a message and data.
//Pass in the following json for testing: { "default":"some message", "kupa": "true"}
console.log("Loading kupa function");
var AWS = require("aws-sdk");
exports.handler = function(event, context, callback) {
var eventText = JSON.stringify(event, null, 2);
console.log("Received event:", eventText);
var sns = new AWS.SNS();
var params = {
Message: eventText,
MessageStructure: "json",
Subject: "Test SNS From Lambda",
TopicArn: "arn:aws:sns:us-west-2:xxxxxxxxxx:test"
};
sns.publish(params, function (err, data) {
if(err){
callback(err, null); //failed
}
callback(null, "kupa sukces"); //success
});
};
We are working on hydrid apps. Recently we got the requirement to support voice sms. We did R&D on that but we didn't have any luck. So we are trying to record 1 minute voice then we send it to a server. We don't know is it correct way. Please guide to us.
We tried like this https://www.npmjs.com/package/cordova-plugin-audio-recorder-api
var recorder = new Object;
function stop(){
recorder.stop = function() {
window.plugins.audioRecorderAPI.stop(function(msg) {
// success
alert('ok: ' + msg);
}, function(msg) {
// failed
alert('ko: ' + msg);
});
}}
function record{
recorder.record = function() {
window.plugins.audioRecorderAPI.record(function(msg) {
// complete
alert('ok: ' + msg);
}, function(msg) {
// failed
alert('ko: ' + msg);
}, 30); // record 30 seconds
}}
function playback(){
recorder.playback = function() {
window.plugins.audioRecorderAPI.playback(function(msg) {
// complete
alert('ok: ' + msg);
}, function(msg) {
// failed
alert('ko: ' + msg);
});
}}
We please guide to proper way to achieve our task.
I am developing android app using cordova on Ubuntu 14. Its a hybrid app that consists of:-
Server- RESTful api using Php with slim framework &
Client - Backbone with requirejs,jquery,bootstrap etc.., HTML,CSS.
I have created the app as per the steps given in Apache Cordova Documentation guide (http://cordova.apache.org/docs/en/5.0.0/guide_platforms_android_index.md.html#Android%20Platform%20Guide) and imported the app in android studio. I am using android studio 1.3.
I have connected the app to my localhost using(10.0.2.2), the app runs on the emulator and shows the 'login' screen.
The challange is, after filling user name and password, when I click 'Sign In' it should trigger http 'POST' as in Browser app. But it does not triggers POST and in return I get 404 error in Backbone.sync-error, and when I saw the server HTTP_METHOD it shows 'GET' !!
I have overriden Backbone.sync method.
This is my 'login.js' file triggering the event
//sigin button click code ...
// ...
signinInfo.set({
email: email,
password: password
});
signinInfo.save(null,{
success: function (data) {
window.localStorage.setItem('uid',signinInfo.attributes.uid);
window.localStorage.setItem('email_id',signinInfo.attributes.email_id);
// redirect the user to the given route
if (data.attributes.status == "1") {
window.location.href = "";
} else {
alert("Incorrect password!");
}
} // success
});
The above 'save' on 'signinInfo' model triggers the Backbone.sync method. Here's the code snippet from models.js that overrides 'Backbone.sync' method:
originalSync = Backbone.sync;
Backbone.sync = function (method, model, options) {
var success = options.success;
var error = options.error;
console.log("Models.js- method: " + method + ", model: " + JSON.stringify(model) + ", options: " + JSON.stringify(options));
options.success = function (model, response, options) {
console.log("Models.js- success, response: " +response );
$('.srLoading').hide();
if (typeof model.redirect == 'undefined') {
success(model, response, options);
} else {
window.location.replace("/");
}
};
options.error = function (model, response, options) {
console.log("Models.js- error:" +JSON.stringify(model) + " response: " + response + "; options: " + JSON.stringify(options));
$('.srLoading').hide();
error(model, response, options);
};
// I have tried to put options for crossDomain here, but its not working
options = options || (options = {});
if (!options.crossDomain) {
options.crossDomain = true;
}
if (!options.xhrFields) {
options.xhrFields = {withCredentials:true};
}
if (method === "read") {
console.log("Models.js- read method!" );
$('.srLoading').show();
options.dataType = "jsonp";
return originalSync.apply(Backbone, arguments);
}
if (method === "create") {
console.log("Models.js- create method!" );
$('.srLoading').show();
options.dataType = "jsonp";
options.contentType = 'application/json';
options.type = 'POST';
//options.data = JSON.stringify(options.data);
return originalSync.apply(Backbone, arguments);
}
if (method === "update") {
$('.srLoading').show();
options.dataType = "jsonp";
return originalSync.apply(Backbone, arguments);
}
if (method === "delete") {
$('.srLoading').show();
options.dataType = "jsonp";
return originalSync.apply(Backbone, arguments);
}
}; //Backbone.sync
Above, method 'create' is called but at server it does not converts to 'POST' request. Instead $_SERVER['REQUEST_METHOD'] shows 'GET'! :(
In my Backbone.sync method I commented [options.dataType = "jsonp";] so that the code looks as follows:
...
if (method === "create") {
console.log("Models.js- create method!" );
$('.srLoading').show();
//options.dataType = "jsonp";
options.contentType = 'application/json';
return originalSync.apply(Backbone, arguments);
}
Now my login sends HTTP POST request to the server!
On cross domain (CORS), backbone with dataType 'jsonp' can only make 'GET' request. So to make other actions we need to send 'json' data.
I am at my whit's end.
I will try to keep it brief.
Using Cordova/Phonegap 3.0 (and get the same results on 2.8.0).
Android version 4.0.4.
Code works on BlackBerry10 (Q10 and Z10).
On Android it errors with a JSON Error (no, I'm not parsing JSON, this seems to come out of cordova's bowels). I will paste the JSON.stringified error object at the end of this.
So, on to code then:
First a filesystem success function:
function onFSSuccess(fileSystem) {
if (fileSystem == null) {
window.alert("fileSystem is null");
}
var root = fileSystem.root;
root.getDirectory("com.app.id",{create:true},gotDir,onError);};
Then a function to handle success with directory retrieval:
function gotDir(d){
DATADIR = d;
doTheDl (d.fullPath + "/update.sql",fileTransfer);
};
Then the actual call to get the filesystem:
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFSSuccess, null);
Then a function to download the file:
function doTheDl (localPath,fileTransfer) {
try {
window.alert ("Downloading to '" + localPath + "'");
fileTransfer.download (
uri,
localPath,
function (entry) {
try {
$("#dbDownloadProgressContainer").text("File saved to " + entry.name + ". Applying script to database...");
dbInitObj.applyUpdateScript(entry);
}
catch (e) {
window.alert ( e);
}
},
function (err) {
window.alert ("ERROROR!!! - " + err);
var errCodeName = err.code;
switch (err.code) {
case FileTransferError.FILE_NOT_FOUND_ERR:
errCodeName ='FILE_NOT_FOUND_ERR';
break;
case FileTransferError.INVALID_URL_ERR:
errCodeName="INVALID_URL_ERR";
break;
case FileTransferError.CONNECTION_ERR:
errCodeName="CONNECTION_ERR";
break;
case FileTransferError.ABORT_ERR:
errCodeName="ABORT_ERR";
break;
default:
errCodeName = "UNKNOWN";
break;
}
window.alert ("Download failed: " + err.source + ", " + err.target + ", " + errCodeName);
},
true
);
}
catch (e) {
window.alert ( e);
}
}
Man, gotta love all these async callbacks...
Next we get to the heart of the matter, trying to READ the downloaded file:
//Bulk of applyUpdateScript script ommited, but eventually it gets here:
function readComplete (evt) {
$("#dbDownloadProgressContainer").text("Parsing script file...");
//Got this gem from here: http://beckism.com/2010/09/splitting-lines-javascript/
var lines = evt.target.result.match(/^.*([\n\r]+|$)/gm);
//var lineIndx = lines.length;
window.setTimeout(function () {
$("#dbDownloadProgressContainer").text("Processing " + lines.length + " statements");
},50);
};
try {
var fileReader = new FileReader();
fileReader.onloadend=readComplete;
fileReader.onerror=function (err) {
//var errStr = translateFileError (err);
window.alert ("FileReader.onerror: " +JSON.stringify (err));
};
fileReader.onloadstart=function (evt) {
window.alert ("FileReader.onloadstart - " + JSON.stringify (evt));
};
fileReader.onload=function (evt)
{
window.alert ("FileReader.onload - Called when the read has successfully completed.- " + JSON.stringify (evt));
};
fileReader.onprogress = function (evt)
{
window.alert ("FileReader.onprogress - " + JSON.stringify (evt));
}
fileReader.onabort = function (evt)
{
window.alert ("FileReader.onabort - " + JSON.stringify (evt));
}
function gotFile (fileEntry) {
window.alert ("Activating reader for file '" + fileEntry.fullPath + "'");
fileReader.readAsText(fileEntry);
};
function noFileFound (fileError) {
alert ("Can not access database update script: code " + translateFileError (fileError));
};
// window.alert ("scriptPath.name = " + scriptPath.name);
DATADIR.getFile (scriptPath.name,null,gotFile,noFileFound);
}
catch (e) {
window.alert (e);
}
NOW, when I hit the reading bits, I eventually get this from the 'onerror' event (rember this is the JSON.stringfied error object:
{
"type":"error",
"bubbles":false,
"cancelBubble":false,
"cancelable":false,
"lengthComputable":false,
"loaded":0,
"total":0,
"target":{
"_readyState":2,
"_error":{
"code":"JSON error"
},
"_result":null,
"_fileName":"file:///mnt/sdcard/com.app.id/update.sql",
"_realReader":{
"error":null,
"result":"",
"readyState":0
}
}
}
Please also note that 'com.app.id' is a place holder for the actual app ID - can't paste that for fear of sensitive names. I did try other folder names as well.
Other notable(?) items:
The download progress event seems to indicate that we are downloading precisely double the actual file size (wtf?)
Results are the same on android device and emulator
BlackBerry10 seems to work fine
Thanks in advance to any clever people....
OK.
This was the solution:
function gotFile (fileEntry) {
fileEntry.file (function (file) {
fileReader.readAsText(file);
});
};
So thanks a BAJILLION to this dude:
http://www.html5rocks.com/en/tutorials/file/filesystem/?ModPagespeed=noscript
In case you missed it, the magic is the call to the "file(...)" function on the fileEntry object.
Why it works on the BB10 WITHOUT it....aarrgggghhh