Why?
Lately I was discussing about programming a flash-based multiuser game using sharedObjects.
I’m not so fond of Flash so I thought: Flash can communicate with Javascript. So why not implement the game in Javascript and do only the multiplayer-communication in flash?
I created jsSO to allow the clients to push data to the server and notify other clients immediately about changes.
So this library allows programming of realtime games, chats etc.
How?
There is no easy way to get a notification in Javascript on the client about changes on the server.
So the solution is to use Flash and let it handle the update notifications.
You have to install the Flash server from Adobe or se the
free java alternative: Red5 as in the example below.
The data-transfer and the connection to the server are maintained by a simple embedded Flashmovie in your page.
The communication with other clients runs through the local Flashmovie and the Red5-Server.
The data-flow between two clients looks like this:

Image created by rhio.kim
Dependencies
- Javascript-Libraries: jquery + swfobject
- Flash-Remoting-Server: red5 or similar
Demos
I’m currently working on improving jsSO, so if the demos are not working please come back later, or try them on your own red5-server! :)
Update 2010: I have no Red5 Server running anymore, so the demos won’t work.
Open 2 Windows with the same demo and see how fast e.g. drawing in one window shows up on the other window!
Simple Button Example
Draw
Chat
Call Server Side Functions
Downoad / Repository
Releases
2009-04-15:
Version 0.2
* Allow calling functions on the server
* Event Handlers: e.g. detect connect/disconnect to rtmp-server
2009-02-24:
Version 0.1 (Inital release)
Source
SVN at code.google.com
including all JavaScript examples and a Java red5-demo
Usage
Include the Javascripts
<script type="text/javascript" src="js/swfobject.js"></script>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jsSO.js"></script>
Example Shared Object Usage
// Connect to to a shared object Handler (SOSample) on the Red5-Server and
// use the objectName "draw". The objectName is identical to a namespace
// for your data or a chat-room.
// SOSample is the simplest shared object example of the Red5-server
jsSO.connect('rtmp://localhost/SOSample', 'draw');
// On button click set someVar in the shared object
$(':button').live('click', function(){
jsSO.set('someVar', 'value');
});
// Listen to changes on the shared object
// event = A jquery event object
// updates = If a var is updated it is set in the updates-object.
// See code below for usage
// data = All data in the object
jsSO.onSync(function(event, updates, data) {
if (updates.someVar) {
// someVar was updated
console.log(data.someVar);
}
});
Other useful functions
// get the current data of the shared object
var data = jsSO.getData();
// get the last updates on the shared object
var updates = jsSO.getUpdates();
Event Handlers
// events from jsSO:
// connection: onConnect, onConnectError, onDisconnect
// shared object sync: onSync
// one of these fires for each server-call: onCallResponse, onCallError
jsSO.onConnectError(function(event, code){
// couldn't connect
});
jsSO.onDisconnect(function(event, code){
// server disconnected me
});
jsSO.onCallError(function(event, error){
// global error handler for all calls
});
Calling Server-Side Methods
jsSO allows now calling Server-Side Methods.
- connect() to the server, you only have to provide a rtmp-url if you do not neeed a shared-object
- jsSO calls the server-function getServiceList and creates a client-side jsSO.service object with all available methods.
- Calling a server-method is now as easy as: jsSO.service.helloWorld()
- To get results from the server i’ve borrowed the mochikit/dojo service syntax:
call addCallback() on the return value of the method to get the server-response or
call addErrback() to get server errors.
Live Demo
Example
jsSO.connect('rtmp://pro-web.at/firstapp', {debug: true});
jsSO.onConnect(function(){
// call function
jsSO.service.add(2, 4).addCallback(function(ret){
console.log(ret); // 6
});
// call alternative
jsSO.call('add', 2, 4).addCallback(function(ret){
console.log(ret); // 6
});
// call unknown function
jsSO.call('unknown').addCallback(function(ret){
// we don't get here
console.log('OK');
}).addErrback(function(error){
// error object is printed
console.log(error);
// error.application = "org.red5.server.service.MethodNotFoundException"
// error.code = "NetConnection.Call.Failed"
// error.description = "Method unknown without arguments not found"
// error.level = "error"
});
// call a function, which throws an exception
jsSO.service.throwException().addCallback(function(ret){
// we don't get here, because the server java code throws an exception
console.log('OK');
}).addErrback(function(error){
// error object is printed
console.log(error);
// error.application = "example.remoteapp.TestException" (the exception class)
// error.code = "NetConnection.Call.Failed"
// error.description = "some error occured" (the exception description)
// error.level = "error"
});
});
Server-Side: read all Services with the annotation @Service
package jsso;
public class Application extends org.red5.server.adapter.ApplicationAdapter
{
/**
* Allows the javascript-client to retrieve a list of available methods
*/
@Service
public ArrayList<String> getServiceList() {
ArrayList<String> serviceMethods = new ArrayList<String>();
Method[] methods = this.getClass().getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Service.class)) {
serviceMethods.add(method.getName());
}
}
return serviceMethods;
}
}
Server-Side: the implemented Methods
public class Application extends jsso.Application
{
@Service
public int add(int a, int b) {
return a+b;
}
@Service
public Object throwException() throws Exception {
throw new TestException("some error occured");
}
}
Future Improvements
- Allow multiple connections with different objectNames to the Server
- Automatic reconnect to sharedObject on connection loss
- Fallback in case flashplugin is not present
Leave a Reply
April 11th, 2009 at 20:53
Hi, in Red5 server version 0.8 RC2 the SOSample doesn’t came pre-installed, so you have to start the server, go to the default home page (http://localhost:5080/), then select install demos and select the SOSample demo to make jsSO work properly. It took me like two hours to figure out that.
Once I did that, everything work right. Thanks, great work.
April 12th, 2009 at 16:42
Hi again. I’m not in AS3, so I want to play around with connector.as, but can’t recompile it with Flex 3 SDK.
Could you explain how do you do it? Do you use the mxlmc.exe command?
April 13th, 2009 at 17:03
hi guu,
currently i’m switching from as2 to an mxml/as3 solution. i’m developing under flexDeveloper, but it should compile by hand under mxmlc also. i will create a repository on google-code with the newest version. unfortunately the name jsso is already taken so i have to come up with a new name :>
also thanks for your comments
daniel.
April 18th, 2009 at 13:58
What about the name jsRTMP as project name? is longer, but seems to be free too
April 24th, 2009 at 07:24
rad!
June 21st, 2009 at 10:34
[...] jsSO – это js-библиотека, которая позволяет клиентам при помощи JS взаимодействовать друг с другом через внедрённую флэшку, конектющуюся к rtmp-flash-серверу. Примерно так: Javascript/jsSO <-> Flashmovie <-> Red5-Server <-> Flashmovie <-> Javascript/jsSO. [...]
August 9th, 2009 at 08:18
Hello , I have a problem , becauce the SOSample is working (the ball demo is working whit RED5) but your examples aren`t working ? Please help!!!
August 29th, 2009 at 21:10
[...] example, plus source code, ofsetting Flash cookies via javascript. Also of interest: SWFObject and jsSO. Posted on Saturday, August 29th, 2009 at 1:10 pm under Asides. You can skip to the end and [...]
October 13th, 2009 at 00:06
[...] jsSO « pro-web.at (tags: flash jquery library as3) [...]
October 13th, 2009 at 11:36
[...] A useful example, plus source code, of setting Flash cookies via javascript. Also of interest: SWFObject and jsSO. [...]