June 15, 2008 at 9:28 pm · Filed under RubyAMF, Rails, AMF
Hello all,
There was at least one bug running RubyAMF with Rails 2.1, and I fixed
that today, and all my reference apps (which are what passes for
tests) work, so I’m tagging that sucka as 1.6.1.
You can get that like:
script/plugin install http://rubyamf.googlecode.com/svn/tags/1.6.1/rubyamf
Or from the current tag:
script/plugin install http://rubyamf.googlecode.com/svn/tags/current/rubyamf
Now, for anyone interested, what was breaking was Rails 2.1’s forgery
protection, which stops cross site scripting attacks by placing a
security code in HTML and Ajax forms and verifying that that’s the
right code on the Rails side.
My fix was just to add the AMF mime type to the list of mime types
that aren’t checked for forgery protection, alongside XML and JSON. I
think it belongs there, because there’s no way that I know of to hook
into the Rails forgery protection.
To do the same type of thing from a Flash app would be a bit of a
different process, and I’m not quite sure what the best way to think
about that is, nor if it’s actually a problem we need to worry about
anytime soon. Any thoughts?
Upshot: RubyAMF 1.6 for Rails 2, RubyAMF 1.6.1 for Rails 2.1.
Cross posted from (http://groups.google.com/group/rubyamf)
May 24, 2008 at 10:34 am · Filed under RubyAMF, Events
Hey all, this is Tony. I’m going to RailsConf next week. Daniel Wanja (of onrails.org) and I
will be giving a hands on tutorial on Thursday about Powering AIR
Applications with Rails. We have a ton of material, and if time
allows I’ll talk a bit about RubyAMF.
If you’re not coming to the tutorials let me know if you’re coming to
the conference anyway and we can meet up and talk about RubyAMF.
May 21, 2008 at 6:38 pm · Filed under Guttershark
Couple things. I thought I’d make sure I don’t pollute the RubyAMF blog with Guttershark stuff. So I’ve got a blog setup for Guttershark now.
I’m also migrating SSR into Guttershark, this is where SSR will be available from now on, and lives in net.guttershark.remoting. I’ve also just added a new RemotingManager class that simplifies working with RemotingConnections / RemotingService classes. As well as integration into Guttershark so that initializing a RemotingManager is as simple as providing a flashVar specifying what endpoints to initialize. There’s a good example in the examples/shells/remoting folder in the SVN repository.
May 19, 2008 at 12:15 pm · Filed under Uncategorized
I’ve been sitting on the code in branches/development for a while now
and I thought it was time to get it into trunk. I went a little crazy
though, and also tagged it as 1.6 and pointed the current tag to 1.6.
There are still some outstanding issues, but I’m running this code in
a stable environment and I wanted to get everyone on the same page.
Here’s the new order of things:
http://rubyamf.googlecode.com/svn/trunk
This is “edge”. There may be unstable code in here, but not by design.
It should be pretty solid for trying out new features or important bug
fixes.
http://rubyamf.googlecode.com/svn/branches/development
This is where experimental features or patches can go.
http://rubyamf.googlecode.com/svn/tags/current
This should be the stablest release available.
http://rubyamf.googlecode.com/svn/tags/1.6
This is the current stable release as of 19 May, 2008
History:
SVN r1275: branches/development goes into trunk
SVN 1276 - 1.6 tagged
SVN 1277 - “current” tag now points to 1.6
Current used to point to tags/release_1.3.3_rev865
Cross-posted from http://tinyurl.com/55b9ax
May 10, 2008 at 7:35 pm · Filed under AS3
I’ve been working quite a bit recently to get this Flash Actionscript 3 library ready. Check out the first beta.
March 4, 2008 at 3:58 pm · Filed under FlexibleRails
A friend sent me this link a couple weeks back to a short spotlight on Flexible Rails. Check it out
January 30, 2008 at 11:18 pm · Filed under Streaming
I’ve been working a lot lately with Akamai for streaming content. Minus many problems I’ve encountered, and having to write an AS3 AkamaiNCManager class. It’s pretty straight forward.
For a quick background on the what I’m going to show you - checkout the FLVPlayback documentation and look at the ncMgr property. Then read about the INCManager and NCManager. If you read the source code of the NCManager class, it’s pretty straightforward, and you can see that attempts to connect to your streaming application are made numerous times, first to port 1935, then to port 443, then to port 80 over RTMPT (http tunneling), then to port 443, over RTMPS.
That’s quite a few connection attempts to go through, which can cause delays in streams playing. Generally it’s not really a big deal. But in this case - a pretty serious application, I don’t want my apps attempting all of those, or just in that order.
Preferably I’d rather have it first check RTMPT over port 80, because port 80 is always open. Then check port 1935, then 443. It was pretty straight forward after diving into it a bit. I thought I’d share how to re-order the way that the NetConnection’s are attempted in the default NCManager class.
First thing, we need to update the AS3 source NCManager class. Find that source file, and open it up. There is a variable declared like so:
//ORIGINAL:
flvplayback_internal static const RTMP_CONN:Array = [
{ protocol: "rtmp:/", port:"1935" }
,{ protocol: "rtmp:/", port:"443" }
,{ protocol: "rtmpt:/", port:"80" }
,{ protocol: "rtmps:/", port:"443" }
];
//UPDATED:
flvplayback_internal static var RTMP_CONN:Array = [
{ protocol: "rtmp:/", port:"1935" }
,{ protocol: "rtmp:/", port:"443" }
,{ protocol: "rtmpt:/", port:"80" }
,{ protocol: "rtmps:/", port:"443" }
];
All I did here is update it so that it’s not constant, it’s now a var. Note that instead of changing the value of the variable in your class, just change it from const to var. So that in other flash applications, you don’t inherit something in the AS3 codebase you forgot about.
So now to update the variable:
package
{
use namespace flvplayback_internal;
public class MySomething
{
public function MySomething()
{
//change the values.
NCManager.flvplayback_internal::RTMP_CONN = [
{protocol: "rtmpt:/", port:"80" },
{protocol: "rtmp:/", port:"1935"},
{protocol: "rtmp:/", port:"443"}
]
}
}
}
Now you can successfully change the order of connection attempts.
January 28, 2008 at 10:10 pm · Filed under Everything Else
I had to share this with anyone who would listen because this is so friggin cool. I’ve been working on this project at work and we’re using Flash Remoting for services, and we are expecting millions of hits, the most being 7 million a day, but averaging in the hundreds of thousands of users per day.
So we had to devise a way to stress test the server software. That’s the screen capture I posted a couple days ago. But anyway, I setup 7 computers that all had JMeter running - hitting our internal dev server. Total there were 2000 threads, sending 28 requests per thread. In 9 hours, the server handled 37 million requests without anything being a problem. That’s crazy!
The other thing that was so crazy is that each request or “transaction” hits the MS SQL server 5 times per transaction. The server side software is awesome. Chris Crissmond and Darrell Thurmond had written it, its all free threaded - basically one transaction takes 0 seconds. It’s written in C# and SQL Server. These guys did an amazing job.
Another thing that happens per transaction is hitting the M$ Live Search API. M$ themselves told us we wouldn’t be able to get more than about 40 transactions per second on hardware we had (32 bit, 3 gigs ram, dual core something). But we peaked at processing about 300 requests per second. The server we had didn’t even care about what was happening, memory was at about 540MB, and the cpu was staying between 25-40% usage.
The next morning, we had the Live Search team from M$ asking us how the hell we did that. Pretty friggin cool. Also note that JMeter bursts requests, it’s not constantly sending requests. So we probably could have done 90 million in 9 hours no problem. Crazy.
Another successful AMF project. Go AMF!
January 28, 2008 at 9:36 pm · Filed under Remoting, SSR, AMF, AS3
John Farrar had asked about SSR 2 - more information on SSR and what benefits / things you get with it. I thought I’d be a little more specific and outline what it is and what you get. Bare with me if I start out by pointing out the obvious.
So, I guess here’s the obvious. SSR is a small AS3 remoting library. Stands for “Super Simple Remoting” because it’s simple. My goal when writing it was to make one library that works in Flash and Flex and handle logic that should be in every application. Personally I like using this in both Flash and Flex because I don’t forget how to use it. I always forget how to use RemoteObject so this makes a standard library for either.
So here’s an example of a bare minimum setup of SSR to make a remoting call.
import com.niarbtfel.remoting.RemotingConnection;
import com.niarbtfel.remoting.RemotingService;
import com.niarbtfel.remoting.events.FaultEvent;
import com.niarbtfel.remoting.events.ResultEvent;
var rc:RemotingConnection = new RemotingConnection("http://localhost/myGateway",3);
//gateway
//3 is the amf format
var rs:RemotingService = new RemotingService(rc,"MyService",4000,3,true);
//rc is the remoting connection to use for this service
//"MyService" is the service target on the server.
//4000 is the amount of time a call waits before retrying the call.
//3 is the amount of retries to attempt per call.
//true turns on call limiting, which means that the same exact call can't be made while one is waiting for a response or timeout.
//callbacks for calls, keep reading.
function onr(re:ResultEvent):void{}
function onf(fe:FaultEvent):void{}
//callbacks for calls, keep reading.
function onrArgs(re:ResultEvent,args:Array):void{}
function onfArgs(fe:FaultEvent,args:Array):void{}
rs.myMethod([],onr,onf,false); //make a call
//[] = call arguments
//onr is the result callback
//onf is the fault callback
//false - don't return the original arguments sent in the request to the callback functions
var mym:String = "myMethod";
rs.apply(mym,[],onrArgs,onfArgs,true); //make a call
//[] = call arguments
//onr is the result callback
//onf is fault callback
//true - return the original arguments sent in the request to the callback functions
This is the simplest form of setting up flash remoting with SSR without any event listeners on the RemotingConnection or RemotingService. Events for RemotingConnection and RemotingService are documented in the class files. You get events for things like disconnects, retries, timeouts, etc.
Each RemotingService can have a timeout specified for each call going to that service, as well as a maximum attempts allowed per call. If one call is made, but doesn’t receive a response within the timeout specified, it’s tried again. This happens over and over until the maximum attempts is reached, and a timeout event is dispatched.
RemotingService has an option to turn on call limiting. Which makes the remoting service smart about what to call and what not to call. If you made a call to “MyService.myMethod” with parameters [”something”,”something else”], it would not let you make that same call until the first one has completed, or has timed out. You’d still be able to make calls to any other service method.
Another new feature is caching. Say you make calls to some service numerous times, but the data is always the same. Instead of doing that you can enable the service to use caching. Here’s a snippet from above with caching in place:
var rs:RemotingService = new RemotingService(rc,"MyService",4000,1,true);
rs.remotingCache = new RemotingCache(-1);
//-1 specifies that the cache should never expire. (supply a time in milliseconds for an expiration if needed)
Now every call made through this remoting service will be cached. If the exact same call is made, the results are pulled from cache instead.
SSR also has paging built in with a RemotingPager. Here’s a snippet on how that works:
import com.niarbtfel.remoting.RemotingConnection;
import com.niarbtfel.remoting.RemotingService;
import com.niarbtfel.remoting.events.FaultEvent;
import com.niarbtfel.remoting.events.ResultEvent;
import com.niarbtfel.remoting.paging.RemotingPager;
import com.niarbtfel.remoting.paging.PageResponder;
var rc:RemotingConnection = new RemotingConnection("http://localhost/myGateway",3);
var rs:RemotingService = new RemotingService(rc,"MyService",4000,3,true);
var rp:RemotingPager;
var pr:PageResponder // just to include in compilation
var totalRecordsOnServer:int = 400; //should come from server instead.
//callbacks for calls, keep reading.
function onrArgs(re:ResultEvent,args:Array):void
{
rp = new RemotingPager(rs,"myMethod",PageResponder,["someParameter"],re.result as Array,totalRecordsOnServer,50,2,1);
myButton.addEventListener(MouseEvent.CLICK, onbc);
}
function onfArgs(fe:FaultEvent,args:Array):void{}
function onbc(me:MouseEvent):void
{
if(rp.hasNext())
{
trace(rp.next());
}
else
{
trace("no more pages");
}
}
rs.myMethod(["someParameter",0,50],onrArgs,onfArgs,true); //make a call to get the initial data.
//0 is the offset
//50 is the pagesize
In this example, a remoting pager is created in the result callback of the first call. A remoting pager needs at least the first page in order to be created. The RemotingPager takes care of “pre-fetching” pages with buffer options. In the above example, where the RemotingPager is created, 50 is the pagesize to grab, 2 is the amount of pages to buffer / pre-fetch. And 1 is the amount of pages that are left in the buffer before triggering another buffer fill / pre-fetch. This is the simplest form of paging, but the RemotingPager has methods for getting certain pages, getting them all, seeking, etc.
UPDATE: I forgot to mention RemotingService.MaxTimeoutsBeforeHault.
With RemotingService.MaxTimeoutsBeforeHault, you can control how many timeouts are allowed from any call, before all remoting calls are stopped. Here’s a snippet:
RemotingService.MaxTimeoutsBeforeHault = 3;
var rs:RemotingService = new RemotingService(rc,"MyService",4000,3,true);
rs.addEventListener(CallEvent.SERVICES_HALTED, onch);
function onch(ce:CallEvent):void{}
rs.myMethod([],onR,onF,true);
When you set this property, any call that causes a timeout, is kept track of, and if 3 timeouts happen from any call, no other remoting calls will be made. Each attempt after the services are halted, dispatches the CallEvent.SERVICES_HALTED event.
In conclusion - SSR gives you logic out of the box that should be available anytime we are using Flash Remoting. And gives you numerous other features. SSR 2 is documented very well in the source files.
January 27, 2008 at 12:56 am · Filed under SSR, AMF
I’ve beefed-up SSR with numerous new features and improvements. I’ve updated OSFlash with new examples, and included a couple examples in the download. I’ve also changed the package structure, as I’m untying myself from the rubyamf package. Download and enjoy.
UPDATE: Check out the SSR 2 Breakdown.
Next entries »