I am trying to develop an app which sends a HTTP POST request to a NodeJS server (on the localhost). I am using the networking library 'Alamofire' just to try and simplify things.
My issue arises when I try and send multiple requests, I set up a simple button which sends the post request. When I run the app i can click the button and see that it sends the post requests when I click it, but only for the first 4 button presses/post requests.
It may be possible that my server is not set up correctly and not sending a response back or something along those lines.
I get 4 post's each time i open the app - everytime i close and re open the app i get another 4.
The same goes for when I restart the server.
I have tested the server using a pre-existing app (HTTP utility) and it appears to work fine.
When I use Alamofire i use JSON encoding, could this cause the issue???
Here's my swift code:
import UIKit
import Alamofire
class ViewController: UIViewController {
#IBAction func postBTN(sender: AnyObject) {
post(["xx":[10]])
}
override func viewDidLoad() {
super.viewDidLoad()
}
func post(postParrams: [String : AnyObject]) {
Alamofire.request(.POST, "http://10.0.0.10:3000", parameters: postParrams, encoding: .JSON)
}
}
UPDATE *** I added the following code below the 'Alamofire.request' to print the response data:
.validate()
.responseJSON { response in
print(response.request)
print(response.response)
print(response.result)
switch response.result {
case .Success:
print("Validation Successful")
case .Failure(let error):
print("the error is", error)
}
}
The error code that prints is:
the error is Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSUnderlyingError=0x7fd5a3d0e170 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=http://localhost:3000/, NSErrorFailingURLKey=http://localhost:3000/, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=The request timed out.}
From this i gather that the response result is a 'failure' and there are 2 error codes: Code=-1001, CodeKey=-2102
Related
I am new to Nodejs so excuse me for any mistake .. :)
Let me explain what i am trying to do :
basically i am making a push notification service for my platform .. i will explain further..
I have two NodeJs servers (using express) :
SERVER 1 :
it gets everything needed from the database such as ( device registration , identifier ..) and should send to the second server.
SERVER 2 : This server Receives a JSON ( contains everything i need ) to create the FCM and APNS payload and then send to the convenient provider (FCM,APNS).
what i am using : i am using axios to send POST requests.
The issue : since the 1st server will be sending big amount of requests ( usually 5K or more -- it's dynamic) at the same time , axios cannot handle that , and I've tried many other alternatives to axios but faced the same thing.
My question : How can i send that amount of requests without any issues ?
PS: when i send few requests ( 100 or bit more) i face no errors ...
I hope everything is clear and i would really appreciate any help.
Code Example of the Request with Axios :
PS: it always falls in the "[Request Error] ..."
try
{
axios.post(endpoint,{sendPushRequest})
.then( response => {
console.log(response.data);
})
.catch( er => {
if (er.response) {
console.log("[Response Error] on sending to Dispatcher...");
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.log(er.response.data);
console.log(er.response.status);
console.log(er.response.headers);
} else if (er.request) {
console.log("[Request Error] on sending to Dispatcher...");
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
} else {
// Something happened in setting up the request that triggered an Error
console.log('[Error]', er.message);
}
console.log(er.config);
});
}
catch (e) {
console.log('[ Catch Error]', e);
}
Usually, for doing this kind of asynchronous stuff you should use any queuing service as if the second server gets busy which it might in case of handling such a huge number of rest APIs your user would miss the notification.
Your flow should be like:
SERVER 1: it gets everything needed from the database such as ( device registration, identifier ..) and should push/publish to any queuing service such as rabbitMQ/Google pubsub etc.
SERVER 2: Instead of having rest APIs, this server should pull messages from the queue recursively and then Receives a JSON ( contains everything I need ) to create the FCM and APNS payload and then send to the convenient provider (FCM, APNS).
This is beneficial because even if anything happens to your server like busy/crashes the message would persist in the queue and on restarting the server you would be able to do your work(sending a notification or whatever).
I'm having trouble with the server side not communicating with the client side. I receive data on the back end once it's sent from the client, however, it will not work vice versa (when the data is sent back to the client).
My project setup:
Created an empty ASP.NET application with framework 4.6.2
Installed nuget package 'Microsoft.AspNet.SignalR' v2.4.0
Using jQuery 3.3.1
Added a startup class and inserted 'app.MapSignalR();' into the
configuration method
Added a hub with one method for communicating back and forth with the
client
Added a js file for starting up the hub and communicating with the
server
I have tried the following with no success:
Using framework 4.5
Using an older version of jQuery
Logging data on
back end (which I do receive data from the client)
Tried sending back the message to ALL clients (Clients.All) opposed to just the caller
Re-creating a new
project for signalR
Made sure that there were NO JS errors
Ran locally in MULTIPLE browsers (Chrome & Edge)
index.aspx:
<script src="/js/third_party/jquery-3.3.1.min.js"></script>
<script src="/js/third_party/jquery-ui.min.js"></script>
<script src="/js/third_party/jquery.signalR-2.4.0.min.js"></script>
<script src='/signalr/js'></script>
<script src="/js/client.js"></script>
client.js:
var conn = null;
$(function () {
$.connection.hub.stateChanged(connectionStateChanged);
$.connection.hub.start({ waitForPageLoad: false });
conn = $.connection.login;
function connectionStateChanged(state) {
switch (state.newState) {
case 1: // Connected
conn.server.announce('This is an announcement.'); // Works fine and sends the message
break;
}
}
// I'm using '.client', so there is no reason why this should not be triggered
conn.client.onAnnounce = function (message) {
alert(message); // Does NOT receive the message back
debugger;
}
Login.cs:
public class Login : Hub
{
public void Announce(string message)
{
// I receive the data here from the client... but it does not get sent back to the client
Clients.Caller.onAnnounce(message);
}
}
Startup.cs:
[assembly: OwinStartup(typeof(AutoPlayer.Startup))]
namespace SignalRTest
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}
I expect the server to receive a message, the server to send that same message back to the client, and for the client to alert the message.
After hours of trying different things, it was due to this line of code:
$.connection.hub.start({ **waitForPageLoad: false** });
Removing the 'waitForPageLoad' setting, or by setting it to true fixed it.
"waitForPageLoad - Determines if SignalR should wait until the page is entirely loaded to start the connection (defaults to true)."
I assume this was due to the client JS file not being loaded fully, by the time the server was calling back to the client (where 'conn.client.onAnnounce' did not exist yet). Figured I'd see a JS error in the console if this really is the case... but I guess not.
In working with the Angular docs / tutorial on the in-memory web api, I want to return some JSON values that indicate the success or failure of a request. i.e.:
{success:true, error:""}
or
{success:false, error:"Database error"}
But, the code in the example for the in-memory-data.service.ts file only has the one method: createDb().
How do update that service code to respond to a PUT/POST/DELETE request differently than a GET?
Note: In real-life / production, the backend will be PHP, and we can return these values any way we want (with the correct status codes). This question is specifically directed at making the In Memory Web API mock those responses.
Example:
Executing:
return = this.http.post(url,someJsonData,httpHeaders);
I would want return to be:
{success:'true',id:1234} with an HTTP Status code of 200.
Later, to delete that record that was just created:
url = `/foo/` + id + '/'; // url = '/foo/1234/';
this.http.delete(url);
This wouldn't really need a JSON meta data response. An HTTP Status code of 200 is sufficient.
How do update that service code to respond to a PUT/POST/DELETE
request differently than a GET?
The server will always respond to the requests that you have made. So if you fire an Ajax request it may be one of the known HTTP Methods (like POST, GET, PUT...). Afterwards you'll wait for the answer.
/** POST: add a new hero to the database */
addHero (hero: Hero): Observable<Hero> {
return this.http.post<Hero>(this.heroesUrl, hero, httpOptions)
.pipe(
catchError(this.handleError('addHero', hero))
);
}
/** GET: get a new hero from the database */
getHero (heroId: number): Observable<Hero> {
return this.http.get(this.heroesUrl + '/' + heroId)
}
I found the answer I was looking for: It's HttpInterceptors.
This blog post and the corresponding github repo demonstrate exactly how to simulate CRUD operations in Angular 2/5 without having to setup a testing server.
I am trying to proxy an api call from client side through my server for some third party service, reasons for this being CORS issues and adding in a secret key on the server side. I usually get it done in the following way:
app.use('/someService', (req, res) => {
let url = `https://example.com/${config.SECRET_KEY}/endpoint${req.url}`
req.pipe(request(url).pipe(res))
})
this way I can use any ajax library on the client side and perform get request for example: get: '/someService/params' and it would normally go through and perform that request and then pipe it back. However now I started getting:
Error: write after end
in express and I am not entirely sure about what could be causing it.
Your piping is wrong. As it is now, you're piping to res twice (.pipe() returns the argument passed to it for chainability).
Instead try this:
req.pipe(request(url)).pipe(res)
I should point out however that properly proxying the HTTP response is not quite that simple since currently this line will always respond with HTTP status code 200, no matter what the remote server for the middle request responds with. Also, any headers from that response will not be sent to res. With that in mind, you could naively try something like:
var proxiedRes = req.pipe(request(url));
proxiedRes.on('response', function(pres) {
res.writeHead(pres.statusCode, pres.headers);
// You will want to add a `pres` 'error' event handler too in case
// something goes wrong while reading the proxied response ...
pres.pipe(res);
});
i am building a Sencha Touch 2 Application with userspecific datasets.
Architecture of the App:
Sencha Touch App <=====> Java Server backend with REST Services
( many AJAX requests =) )
What i actually have is:
Login the user with username/password
The app gets initialized and the loginform comes into play. After submitting the form as a AJAX request, the server backend checks the userdata and calls the client callback function.
And what i want to do is:
The callback function should
create a cookie with the sessiontoken or
store the sessiontoken within the localstorage (http://docs.sencha.com/touch/2-0/#!/api/Ext.data.proxy.LocalStorage) or
store the sessiontoken within js variable
Okay, shouldn't be the problem.
But how can i achieve the following:
Most of the data is specific for one user and should be returned by the REST service if needed (by clicking on the navigation,...). How can i send the sessiontoken (see above) within every AJAX request - so the server can provide the suitable datasets (assuming the token is valid)?
Send cookies within AJAX requests
I have already read that cookies gets automaticly added to the request if the url is on the same space, right? The Java Server is on the same domain (localhost:8080) but the cookies aren't available - instead of requests on urls like 'app.json'. I thought that cross-domain-requests are really domain specific?
Send paramaters within AJAX requests
Because the cookies aren't avi i thought about the possiblity of 'manually' adding parameters to the ajax requests. The App will contain many AJAX requests and thats why i dont want to add the token manually - i tried to override the requests function of Ext.Ajax but i failed ;-( :
(function() {
var originalRequest = Ext.data.Connection.prototype.request;
Ext.override(Ext.data.Connection, {
request : function(options) {
alert("Do sth... like add params");
return originalRequest.apply(this, options);
}
});
})();
ERROR:
Uncaught Error: [ERROR][Ext.data.Connection#request] No URL specified
I also tried to add a listener
Ext.Ajax.add({
listeners : {
beforerequest : function( conn, options, eOpts ){
alert("Do sth... like add params");
}
}
});
ERROR:
Uncaught TypeError: Object [object Object] has no method 'add'
Any idea about how i can add the token?
Or any better way of handling these case?
Thanks!
Finally i successfully used:
function addAjaxInterceptor(context)
{
Ext.Ajax.on('beforerequest', function(conn, options, eOptions)
{
// add the param to options...
}, context);
}
Executed from the app (=> addAjaxInterceptor(this)).
But the following solution is more suitable for my situation i think:
Ext.Ajax._defaultHeaders = {
// params as json
};
(Cause Ext.Ajax is a singleton object and i dont change the params for every request)