Serving a Flash Socket Policy File From Processing

Last night I spent way too long trying to get AS3 to communicate with a simple socket server I wrote in Processing. I've done this kind of thing before and seemed to recall that it was pretty simple. But in the meantime, Adobe, in an effort to be more secure, has changed the Flash player to require a "socket policy file". The socket policy file is very similar to the familiar crossdomain.xml file that defines security permissions for HTTP access. Unfortunately, the socket policy file must either be sent on demand from the sockets that the player is attempting to access, or from port 843 on the host that the player is attempting to connect to. If all you want to do is run a quick and dirty socket server and have Flash clients connect to it, this is all a huge PITA.

Since ports below 1024 require root permissions in order for processes to use them on OS X, and I didn't want to run some other server process just to serve policy files, I needed to kludge a way to send the policy file from my nice, elegant socket server every time a client connected and requested a policy file. The example below is a simplified version, as it only listens on one port - the project I was working on was basically a proxy from one SWF to another, so I had two socket servers that needed to listen for the requests for a policy file and respond. In this example, the server listens for connections on port 5208, and simply echoes incoming data from the client to System.out, and has some visual feedback in the window. When the incoming message contains the string "policy-file-request" (the entire message from Flash will be terminated with a null char), we simply spit back the XML for a wide-open socket policy, followed by a null char (This is required, or the Flash player will not accept the policy file. This is what tied me in knots last night. RTFM!)

import processing.net.*;

int bgLevel = 0;
int port = 5208;
Server server;

String flashDomainPolicy = "<?xml version=\"1.0\"?>"
                              +"<cross-domain-policy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd\">"
                              +"<allow-access-from domain=\"*\" to-ports=\"*\" secure=\"false\" />"
                              +"<site-control permitted-cross-domain-policies=\"all\" />"
                              +"</cross-domain-policy>";

void setup ()
{
  size(200, 200);
  server = new Server(this, port);
  background(bgLevel);
}

void draw ()
{
  Client client = server.available();

  if (client !=null)
  {
    String message = trim(client.readString());

    if (message != null)
    {
      if (match(message,"policy-file-request") != null)
      {
        sendFlashPolicy(server);
      }
      else
      {
        server.write(message);
        System.out.println(message);

        // Change the background color to indicate message activity
        bgLevel = 255;
      }
    }
  }

  // Fade to black
  if (bgLevel>1)
  {
    bgLevel-=2;
    background(bgLevel);
  }
}

void sendFlashPolicy(Server socketServer)
{
    socketServer.write(flashDomainPolicy+char(0));
    System.out.println("Sending Flash policy file");
}

You can test this without a Flash client by firing up the sketch and telnetting to the port. Any strings you send will be echoed to System.out, unless you send the string "policy-file-request" in your message, which will result in the server sending the policy XML to you. You should be able to connect a Flash client to this server and start communicating right away.

, , , ,

In Defense of Dependency Injection

I've been rolling the RobotLegs framework into a new project, but not all the team members are sold on the idea, mostly because it represents third-party code that's complex and difficult (impossible?) to understand just by reading over the source.

I realized I was having a difficult time articulating the advantages to the approach, and specifically, the fact that the closest alternatives are every bit as complex and headache-inducing once you get down into the details.

So, what follows is a bit of a thought experiment using a very simple case. Hopefully, by the end, you'll see that what's true for a single, simple case is also true for multiple, complex cases, and in the end, it actually makes good sense to have a framework handle these things.

Imagine first, a Main class. There's only one Main across the entire codebase. Now imagine classes A, B, C, etc (there are a lot of them) that all use a ColorManager class. A, B, C are separate SWFs, so it makes sense for ColorManager to be compiled into Main, and somehow linked into the A, B, and C modules, but not compiled into them. This in itself can be a bit tricky, and there are a few different approaches, with assorted pros and cons.

Our first thought is to compile against a linked SWC containing the concrete ColorManager class. That will keep the actual implementation out of our modules, but any change to ColorManager will require re-compiling every SWF that uses it. Less than ideal.

We could say:

public class A
{
  private var colorManagerClass:Class = getDefinitionByName("ColorManager");
  private var colorManager:IColorManager = new colorManagerClass();
}

It gets the job done, and it's easy to understand. As long as the interface stays in synch, it's not too hard to make changes to the concrete ColorManager class without recompiling the module (and all the others). That synched interface is a pretty big caveat, but we'll find that most (all?) approaches share it. We could forego the interface completely, but at the expense of loosing very valuable strong-typing and code completion.

The downside would be that the concrete class absolutely must be "ColorManager" -- even though we've gone to the trouble of creating an interface (which would/should/could allow other implementations) were stuck with the one-and-only ColorManager returned by getDefinitionByName. The simplest way to make this dynamic? Pass in the String representing the class name. You know what that's called? Dependency Injection. If you're willing to pass in a String, you might as well pass in the class itself.

Another quibble with this technique is that it relies on something known as a "magic string." The compiler doesn't have a way of warning you that this class does or doesn't exist, or that it correctly implements the IColorManager interface. You'll need to rely on runtime warnings for that. It's very easy to misspell or miscapitalize the package/classname breaking everything.

Ok, my (completely competent) team member suggests, we can provide a setter for the class. That might look like:

public class A
{
  private var colorManager:IColorManager

  public function setColorManagerClass (colorManagerClass:IColorManager)
  {
    this.colorManager = new colorManagerClass();
  }
}

Again, this is merely another way of doing Dependency Injection. The real question is whether you'll be using a framework to provide dependencies automatically. We'll come back to address this separately.

What about having our class request the class at runtime, rather than relying on the fact that it will be injected. Something like this:

public class A
{
  private var classLocatorServiceInstance:ClassLocatorService;
  private var colorManager:IColorManager;

  public function initColorManager()
  {
    var colorManagerClass:Class = classLocatorServiceInstance.getConcreteClass(IColorManager);
    this.colorManager = new colorManagerClass();
  }
}

This implementation, while quite valid, raises more questions than it answers. Who calls initColorManager? How can it be sure the ClassLocatorService is ready to provide ColorManager? And just where does this ClassLocatorService come from any way? It's a singleton? How is that enforced? Did you notice how we're requesting the concrete class? Via its interface. We've got the same problem with allowing only one implementation of IColorManager. In order to allow multiple implementations, we're back to using a magic String.

Flash and Kerning

You're probably a special breed if you're reading this. The nuance of this feature along with Flash's implementation peculiarities mean that most people just don't fool with it for more than ten minutes.

This one bit me before, so I'm making a note to myself:

If you're using StyleSheets in Flash via ActionScript (I didn't try loading a textfile), the kerning property does not take a Boolean true/false as the documentation insists. I only works if you use a Number 1/0. The font tag will let you use a Boolean.

Also, since you're so special, I have a tool I've been working on to compile fonts into loadable libraries on the server. It will attempt to include kerning information if possible. The only other way to do that (to my knowledge) is via the Windows IDE.

Try the beta font to swf compiler here.