I am using an http service object to make servlet requests inside a method in flex. The method is being invoked simultaneously in parallel by two events. I could see that both requests have reached the servlet, but only one returns to the result event. Also this behaviours is not consistent . is it possible that parallel invocation of the httpservice result in loss of some requests? I am sure that both requests have reached the servlet and data is returned from it. Its just that the result event is not triggered in certain cases.
Thanks in advance.
Including code to describe the issue better.
Please find the method below. The below method "callServlet" is being invoked by two separate events
private var httpObj:HTTPService=new HTTPService();
private function callServlet(text:String):void{
Alert.show(text);
httpObj = new HTTPService();
httpObj.url=<servlet URL>;
httpObj.method="POST";
httpObj.resultFormat="xml";
httpObj.contentType="application/xml";
var requestString:String=text;
httpObj.request=requestString;
httpObj.addEventListener(ResultEvent.RESULT,onResultMethods);
httpObj.addEventListener(FaultEvent.FAULT,onFaultMethod);
httpObj.send();
}
Each time i call the method, i pass a different "text" variable. I can see that the alert displays the two different texts send to it. And as explained earlier, both requests does reach the servlet and a response is sent from servlet.
But the result event "onResultMethod" is invoked just once.It doesnt invoke the "faultonFaultMethod" either.
Yes, I have seen this problem before, if you are making multiple requests from flex, some of them will be lost, that was back in 3.0 times. Browsers has a way of stopping the number of http calls, they can allow maximum of 2 calls at a time(depends on the browser), may be chain your requests one after the other or use a singleton which manages your calls.
Thanks all for help. I think i ve got the issue though i cannot guarantee the answer to be right.
The above method is called twice by two events. The httpOject variable is a private var global to the method callServlet. The listeners created in this method are being removed in the result and fault handler methods(this is not shown in the code above).
So i believe when multiple events call the method simultaneously there is a chance that the global variable httpObj is modified by both the events and hence both events result in servlet call using the same httpservice object. When the first call returns to the resulthandler i am removing the listener for resulthandler due to which the second result does not reach the resulthandler method.
This is my assumption and as of now i dont have any better solution. Do let me know if anyone comes up with a better explanation.
Related
In Signalr, is there any support for having events instead of callbacks.
Let me explain before you grab your pitchforks.
In following with the first example here
Clients.All.addContosoChatMessageToPage(name, message);
Wouldn't call a hub proxy's addContosoChatMessageToPage(name, message), but would dispatch a addContosoChatMessageToPage event with some extra information. (not asking that it be the same api call exactly)
The reason I'm asking all of this is because
This works much better alongside functional reactive programming frameworks like ELM and bacon.js
I don't want to do this myself and essentially create my own sub-framework. Of course I could always do Clients.All.CreateEvent(name,params...) where I'm continually calling back my method to do this event creation
I actually think events work better in some scenarios for separation of concerns.
Am I crazy? does something like this exist?
This is already supported. If you don't want to do the dispatching yourself and you know the name of the "event" or "method" at runtime you can do this:
IClientProxy proxy = Clients.All;
proxy.Invoke(name, args);
This lets you write code where you may not know the name of the event you're trying to callback on the client at compile time.
I am using RemoteObjects to call ZendAMF PHP from Flex/Flash Builder 4.6. I want to stop or abort a method call before it sends the request to the server based on an event or similar.
I have a class where I create and store all the RemoteObjects - for example:
activityLogService = new RemoteObject("zend");
activityLogService.endpoint=endpointServer;
activityLogService.addEventListener(FaultEvent.FAULT,faultHandler);
Then later I can simply call this object:
remotingService.activityLogService .getRecords();
I am trying to find a way in my remotingService object to stop the request - and not send anything to the server - for example if some variables are not set properly.
I noticed there is an invoke event:
activityLogService.addEventListener(InvokeEvent.INVOKE,invokeHandler);
However, I can not tell if that's going to stop things at the proper point, or if it's even possible to actually STOP the request - if so, how?
Thanks!
Check out this question
Flex : Is it possible to stop a remote call?
If you're using a RemoteObject you should be able to call
getOperation() method and then cancel() on the corresponding
operation.
while trying to solve my problems in serializing the execution of cairngorm commands, I tried to bypass completely the event dispatching and simply instantiated the command I wanted to execute, then called it's execute method. In this method there's a call to a delegate that calls ServiceUtils that performs the HTTPService.send thing...
Now, those commands should be run in the exact order I call them.
And, since the server (RAILS) is only one, all requests should return in the same order.
This isn't so.. the order varies upon different executions.. why?!?
Just because you send requests in a certain order doesn't mean the responses will return in that order. HTTPService calls are asynchronous. For example, assume the following three requests are sent at the same time:
Request 1 (takes 4 seconds on the server to process)
Request 2 (takes 0.5 seconds to process)
Request 3 (takes 2 seconds to process)
Assuming network speed is constant (and a lot of other environment issues being constant), you will get the response for Request 2 back first, then Request 3, then Request 1.
If you need to call them in serial, you should do something like this:
protected function doWork():void {
request1.send();
}
protected function onRequest1Complete(e:ResultEvent):void {
request2.send();
}
protected function onRequest2Complete(e:ResultEvent):void {
request3.send();
}
protected function onRequest3Complete(e:ResultEvent):void {
// you are done at this point
}
...
<mx:HTTPService id="request1" url="http://example.com/service1" result="onRequest1Complete(event)" />
<mx:HTTPService id="request2" url="http://example.com/service2" result="onRequest2Complete(event)" />
<mx:HTTPService id="request3" url="http://example.com/service3" result="onRequest3Complete(event)" />
Hope that helps.
RJ's answer covers it very well. Just to add to it:
Your commands will create asynchronous requests via the services you use. If you want to "simulate" synchronous execution of commands, the subsequent command will have to be executed in the resultHandler of the previous commands request.
Although this may not always be the cleanest way of doing things, it may be suitable for your scenario. I'll need more information about the nature of service calls and the app in general to make a call whether this is the best method for you or not.
HTH,
Sri
Is there any way to make multiple requests to the callback function in asp.net when using the ICallbackEventHandler? I need the results for each result, however, when I iterate through and call the function, I get the result only for the last call. Any way to make it return a result for each call?
This is what I am passing in via javascript:
function NoPostback() {
$(".spans").each(function(index, item) {
CallServer($(item).attr("myattr"));
});
}
In this, myattr is a custom attribute that holds a value (1..10). What I want returned is something like ('you said: ' + id) to be returned for each of the calls, so that I can go ahead and place them in the appropriate holders.
However, only one item is returned which is the final call made. For instance if there are 4 items, it returns only ('you said: 4').
Any idea on how to have all of them returned?
Thanks in advance.
Most Javascript AJAX frameworks either abort any subsequent requests if one is in progress, or they ignore previous requests and only handle the latest. The AJAX request itself will pass through the browser's XmlHttpRequest object, but the rest of the javascript code is running within the pages thread. Currently, there is no concurrent programming with javascript (however this is slated to change.)
Is there a way to make synchronous calls using RemoteObject in Flex?
All IO in Flex is asynchronous. The typical pattern to deal with this is to use an AsyncResponder. For instance:
var t:AsyncToken = remoteObject.methodCall();
t.addResponder(new AsyncResponder(resultEvent, faultEvent));
think twice when u want it to be synchronous.
Do u know what synchronous mean? it will FREEZE your application until it receive data. Unless u are pretty sure that your remote calling can receive return value immediately (super fast network connection).
if your function call depends on each other, i would suggest you implement a state machine. e.g.
after 1st async call, your state becomes STATE_1, and your next function call will check on this state variable, to decide next move (ignore the current call or carry on).
my 2 cents.
If you want synchronous behavior, just add a wait after you make the call.
EDIT: I've added code for the chaining behavior I was talking about. Just replace the result handler each subsequent time you call the remoteObject.
...
remoteObject.function1(...);
...
private var resultHandler1(event:ResultEvent):void
{
...
remoteObject.removeEventListener(resultHandler1);
remoteObject.addEventListener(ResultEvent.RESULT, resultHandler2);
remoteObject.function2(...);
}
private var resultHandler2(event:ResultEvent):void
{
...
}
I achieved the same in two ways: First, as said above the use of state machines. It may get tricky at times. Second, the use of command queues - I think this is the best way to do it... but the downside is that the UI may not be very reflective in this time.
you should perhaps try and make one request with with all the data u want to be recieved synchronous and then make the different classes that need data listen to the correct data for that class.
ex:
// request
remoteobject.GetData();
// on received request
private function receivedData(evt:ResultEvent):void
{
for each (var resultobject:ResultObjectVO in evt.result)
{
var eventModel:Object;
var event:DataEvents = new DataEvents(resultobject.ResultType);
event.data = eventModel;
eventdispatcher.dispatchEvent(event);
}
}
Something like this. Hopes this helps.
No, why would you wish to do that anyway.
Flex makes things asynchronous so that the user isn't forced to sit and wait while data is coming back.
It would be a very poor user expereince if each time an app requested data the user had to wait on it coming back before anything else could happen.
from comment
No you don't need synchronus behaivour. If you're making say 2 calls and call 2 comes in before call 1, but 2 relies on the data inside 1 then you're left with either don't fire off event 2 till 1 comes back (this will slow down your app - much like synchronus events) or implement a way to check that event 1 has come back in event 2's handler (there are many ways you could do this).
If you're firing off many events then why not have a wrapper class of some description that tracks your events and doesn't do anything on the responses until all events are back.
You can use the AsyncToken to keep track of individual requests, so if you are firing of loads at once then you can find out exaclty whats come back and whats not.
You all are somehow mistaken or not using flex from adobe, if you send 2 calls to the server, no matter if each has an individual resquestObject the second one will ONLY be returned after the first one finish, even if the second one takes 1 milisecond to process. Just try the fibonnaci 1/40 example.
Maybe if you call a synchronous XMLHttpRequest calling JavaScript on Flex, you can do this.