Jul
17
2008

socketBridge: Flash - Javascript Socket Bridge

Update: 5 May 2009
This post has generated a (relatively) large amount of interest so I feel I should point out the ionel is also hosting his improved version of the socketBridge. It has a nicer OO interface and might solve some issues with the javascript callbacks and setTimeouts. Might be worth a peek for all those interested: http://ionelmc.wordpress.com/2008/11/29/flash-socket-bridge-with-haxe/

I’ve been looking at a few flash - javascript socket server bridges recently with the hope of using one to allow me to speak to my Arduino via javascript. I’ve ended up writing my own one here - it’s usually more fun that way, and I can get it to do exactly what I need. However, there’s a couple of good options out there that you might
also want to check out:

SocketJS - Seems to work well and has a nice low file size. The only problem I had with it is that is does not easily allow for object oriented javascript as all of the callbacks are done at the global scope.

jssockets - Nice object oriented interface available here although the function called when the SWF is loaded is still in the global scope. Also this project uses Flex which makes the files size around 120+ KB, a little too large when compared with SocketJS’s ~3KB.

My version is called socketBridge, I think it does most of the things I wanted, mainly allowing for use of object oriented javascript throughout. I also avoided using Flex which kept the filesize nice and low. I’m still not 100% sure about the code quality as this is my first Flash project, prior to this I’d not written any ActionScript at all. To be honest I didn’t even write any here, it was all done using haxe.

I ran into a few issues with Flash’s ExternalInterface, it seems lock up the SWF whilst waiting for the javascript callbacks to return. This posed a bit of a problem when I wanted to do something like have the SWF tell the javascript that it’s loaded and then have that same callback ask the SWF to open a socket connection. The SWF wouldn’t be able to hear my javascript as it had halted whilst waiting for the loaded callback to return!

I found a way around this by wrapping all the callbacks from Flash in a setTimeout method. This effectively opens a new javascript thread and as such straight away returns the original callback. I picked up this tip here.

Feel free to download the bridge swf or alternatively grab the haxe source. It should all be pretty straight forward from a client side point of view.

If this is your first attempt at communicating with a Flash socket server then you may run into a few pitfalls. Flash seems to have some varying security policies depending on the player version, I won’t pretend to understand them all here but Adobe does a pretty good job here.

SocketBridge - connect to your server



 

 

Download

Usage

Include the SWF in your page using something like swfobject.

	so = new SWFObject("/path/to/socket_bridge.swf", "socketBridge", "400", "300", "9", "#ffffff");
	so.addParam("allowscriptaccess", "always");
	so.write("flashcontent");

The flash movie outputs messages such as what’s being sent and received, you can pick these up with the javascript callbacks though. Best just to get rid of the swf from the HTML page.

	#socketBridge {position:absolute;top:-1000px;}

Methods

connect(host, port)

Opens a new socket connection.

	var socket = document.getElementById("socketBridge");
	socket.connect("localhost", "5000");

write(msg)

Sends a string to the current socket server connection.

	socket.write("Hello socket server");

close()

Closes the current socket server connection.

	socket.clsoe();

Callbacks

The socket bridge SWF communicates to a series of javascript callbacks.
By default all callbacks are made to the global scope, however the socket bridge SWF can be provided with an optional scope flash var when being included. If used this should be a javascript namespace or object that enapsulates the callback functions the socket bridge uses.

   so.addVariable("scope", "myObject");
   // Callbacks will now all be in the scope of myObject
   // myObject.callback()

loaded()

Called once the SWF has been loaded, after this call it is safe to open a socket connection.

connected()

Called once a connection with a socket server has been successfully estabished.

disconnected()

Called when the cuurent connection is closed.

ioError(error_message)

Called when an IO Error occurs with the current connection.

securityError(error_message)

Called when a security Error occurs with the current connection. Flash seems to have varying security policies depending on the player version.

receive(message)

Called when a new message is received from a socket server

Example

Below is an example of setting up a scoped object to communicate with the socket bridge

// Object to encapsulate callbacks and communicate with socket bridge

var myObject = {

    // Socket bridge callback functions

    loaded : function() {
        // SWF loaded OK, ready to connect
        this.flashMovie = document.getElementById("flashMovie");
        this.connect();
    },

    connected : function() {
        // Code that you want executing after a succesful connection
    },

    disconnected : function() {
        // Code that you want executing after a disconnection
    },				

   ioError: function(msg) {
        // Code that you want executing after an IO error
    },						

    securityError: function(msg) {
        // Code that you want executing after a security erro
    },								

    receive: function(msg) {
        // Code that you want executing after we've received some data
        alert("Received from the socket server: " + msg);
    },

    // Functions to communicate with socket bridge		

    connect : function(server, port) {
        // Connect to server
        // EG: this.flashMovie.connect("localhost", "5001");
        this.flashMovie.connect(server, port);
    },

    close : function() {
        this.flashMovie.close()
    },

    write : function(msg) {
        this.flashMovie.write(msg);
    }	

};			

// Include socket bridge SWF

so = new SWFObject("/path/to/socket_bridge.swf", "socketBridge", "400", "300", "9", "#ffffff");
so.addParam("allowscriptaccess", "always");
so.addVariable("scope", "myObject");
so.write("flashcontent");

23 Comments

  1. Bryan Buschmann

    I’m happy to see that people are still looking into this bridging solution as I’ve been searching for a sockets based solution for a project I’m involved with. However, it seems that no one has come to terms with the new security requirements of Flash and sockets.

    Are you currently working on what needs to be done in order to process the file-policy-request returns on the client side? I’ve been trying to decipher the actual process and unfortunately can’t come to any specific answers. I’m using my custom socket server, the test scripts that were in the initial announcement, and various client scripts.

    I don’t know what I’m missing here. I have a policy server running and visible, its processing requests and sending out policy but for some reason, nothing is working except the older “non-secure” clients.

    I would love to get some additional brainpower on this issue.

  2. bit

    I’m having the same problem as the comment above me, and your example isn’t working. for your domains’ IP address (208.43.45.224) on port 80, I get ” Security Error: Error #2048: Security sandbox violation: http://matthaynes.net/flash/socket_bridge.swf cannot load data from 208.43.45.224:80.” Did you actually check this code before you published it?? why isn’t this working?

  3. matth

    I find the Flash security policies pretty confusing too. I’m not a Flash developer and haven’t got much experience with this stuff prior to developing the socketBridge app. As far as I know though, the Flash player itself deals with all the processing of policy-request files, i.e. you do not have to code any handling into your application.

    The way I got this working was to host a Flash master socket server on port 843, the newer Flash players will call on this first to get the policy-file. Basically my master server just serves up the following file:

    <?xml version="1.0" encoding="UTF-8"?'>
        <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="master-only" />
    </cross-domain-policy>
    

    I then host my actual socket server on whatever port I want and handle the socketBridge requests from there. Think the process goes something like this, Flash Player connects to master server on port 843 and retrieves the policy file, based on the permissions defines it then connects to the server you requested in the socketBridge app.

    As I say I’m no expert at this, but this is the idea I got from reading the adobe post on socket policy files.

    @bit - I’m not actually hosting a socket server on my domain here so you won’t be able to use the socketBridge to connect to it :) The socketBridge application is simply a client that allows you to talk to a socket server via javascript. You will still need to develop and host your own socket server.

  4. Tom

    I wrote a small python policy server for the people that just don’t want to write it :)

    from twisted.internet import reactor
    from twisted.internet.protocol import Protocol, Factory
    _policy = "<cross-domain-policy><allow-access-from domain='*' to-ports='*' secure='false' /></cross-domain-policy>\0"
    
    class PolicyHandler(Protocol):
     def __init__(self):
      pass
    
     def dataReceived(self, data):
      self.transport.write(_policy)
    
    def main():
     f = Factory()
     f.protocol = PolicyHandler
     reactor.listenTCP(843, f)
     print "Policy handler running on port 843."
     reactor.run()
    
    if __name__ == '__main__':
     main()
    
  5. Selçuk YAZAR

    Hi,

    thanks for the code and samples, but i tried all thing but it didn’t work.i wrote my socket server using c#. it’s listen 9000 port and i have corssdomain.xml file and i added the line “loadPolicyFile” into hx code. But it’s not working. any other suggestion.

    thanks in advance.

  6. ionel

    The way you call the callbacks using setTimeout is bound for failure: no quote escape for the string you pass to setTimeout. While it can be easily fixed i don’t think it would be very performant. A solution would be just calling the callbacks as usual and do setTimeout if necessary in the javascript code.

  7. Flash socket bridge with haxe « ionel’s coderlog

    [...] of solutions for making a bridge to use the flash sockets (flash.net.Socket) in javascript, notably socketBridge and jssockets. But I didn’t like the way they made you write your client code: because you [...]

  8. the blogoholic » Blog Archive » Sockets with JavaScript

    [...] Obviously JavaScript can’t do it directly, but with Adobe Flash and something like socketBridge (or this improved version) you could control a socket with mostly JavaScript.  The only problem [...]

  9. Kaiser Soze

    This is a great tool. I only have one issue: how would you hide it on the page if you don’t care to display the console output? I tried several ways to do this (putting the embedded object inside a hidden div, setting the object size to 0×0 or 1×1, etc) but none worked. The swf crashes if I set the size too small, and it doesn’t get loaded if I wrap it around an invisible div.

    Any feedback on this would be greatly appreciated!

  10. matth

    @Kaiser Soze

    A few options maybe, could try adding CSS display:none; div after the SWF has loaded with SWFObject ? Otherwise you could put it in a div which is absolutely positioned with top and left values of -100000px.

    Sure I have had this working but can’t find the exact code I used sorry.

  11. Kaiser Soze

    Thanks! Moving it off the screen with an absolute position did the trick.

    You know, I’ve been testing this a lot today and sometimes I get the following error for no apparent reason:

    Error: Error #1502: A script has executed for longer than the default timeout period of 15 seconds.
    at Boot_3D39A$/__trace()
    at MethodInfo-65()
    at SocketBridge$/connect()
    at Function/http://adobe.com/AS3/2006/builtin::apply()
    at flash.external::ExternalInterface$/_callIn()
    at ()

    If you just reload the page, no code changes, it works fine the second time around. Firebug reports the following in these cases:

    uncaught exception: Error calling method on NPObject! [plugin exception: Error in Actionscript. Use a try/catch block to find error.].

  12. matth

    Hmm, that’s a weird one I’ve not seen before. I’m really not that hot with Flash debugging I’m afraid!

    I know Ionel who commented above has his own version of the socketBridge app with some revamped code. Basically the same functionality but with a nicer JS interface, might be worth a try if you can’t track down the bug.

    http://ionelmc.wordpress.com/2008/11/29/flash-socket-bridge-with-haxe/

  13. Gilles

    Seems that Symantec is now picking up socket_bridge.swf and reporting it as Downloader.Swif.C Trojan. I’ve submitted a false positive report, so hopefully it’s fixed soon, but in the mean time just a heads up.

  14. Aexaey

    Doesn’t work with flash version 10.1.85.3. TCP connection is established to specified host/port, then “” string is sent, and after waits 2 seconds, tcp disconnects. No user data transmitter or received.

  15. racer

    Is there an example with a complete html Page to see how it’s working??

  16. muhoo

    The receive function is dying with an “unterminated string literal” on FF3 if there is any input to the socket which contains a ‘ charachter, which, in my case, everything does! So it is unusable because of that. Is there some way to make it work with strings that have javascript special characters?

  17. joycleapola

    The scope of pharmacy practice incorporates much more regular roles these kinds of as compounding and dispensing drugs, and it also involves even more present day providers relevant to health treatment, which include clinical companies, reviewing drugs for security and efficacy, online pharmacy Pharmacists, so, are the pros on drug treatment and are the principal health and wellbeing experts who optimize medicine use to deliver sufferers with favorable wellness results.

  18. How to connect from local web browser to remote telnet server and send predefined commands? | Easy jQuery | Free Popular Tips Tricks Plugins API Javascript and Themes

    [...] 1) http://matthaynes.net/blog/2008/07/17/socketbridge-flash-javascript-socket-bridge/ [...]

  19. how to get rid of bag under eyes

    Hi, I do think this is an excellent site. I stumbledupon it ;) I’m going to return yet again since i have book-marked it. Money and freedom is the greatest way to change, may you be rich and continue to guide others.

    Here is my website: how to get rid of bag under eyes

  20. How to Get Rid of Dark Bags Under Eyes

    Unquestionably believe that which you stated.
    Your favorite justification seemed to be on the web the easiest thing to be aware of.
    I say to you, I definitely get irked while people think about worries that they plainly do not know about.
    You managed to hit the nail upon the top and defined out the
    whole thing without having side-effects , people could take a signal.
    Will probably be back to get more. Thanks

    My web blog: How to Get Rid of Dark Bags Under Eyes

  21. Didi

    Hi Matt, good jobs.
    Do you continue to maintain this flash/haxe tool ?
    Indeed when i testing i have a security violation, could you add security.allowdomain security.allowinsecuredomain and security loadpolicyfile ?

    all this with some flashvars ?

    Else, how can i compil your source code ? with haxe ?

    Thanks for your response !

  22. los angeles movers

    Should you be considering a move into the La area, choosing the best kind of company can be a
    significant part of that. Within this brief article, we’ll take a look
    at some of the important facets that is going into your
    search for the right people to tote around your
    important stuff, along with some of the parts that might
    best suit how you wish to live.

    Look at my web blog … los angeles movers

  23. Sanny Jane Yacapin

    It didn’t work for me but anyway thanks for posting this. Keep it up! i have a blog that somehow related to your article. i hope it may found useful for the others. Thank you.

Leave a comment