This articles describes approach and the sample code for invoking client side ActionScript functions from the server application code. The example requires WebORB Enterprise Edition and also works in the product's development mode. The functionality is based on the real-time messaging (RTMP) implementation, it uses a dedicated connection between the client and server.
Below is a live instance of the example. Start multiple clients using the link below. As you open/close browser windows with the client application, connections to the server are established and torn down. The server informs all connected clients via a server-to-client invocation:
Open additional client(s) in a new window
A messaging application on the server-side must be represented through a directory under the /Applications folder. The directory may contain application configuration. Additionally, WebORB stores application instances (rooms) , shared objects and streams.
Application custom logic must reside in the application handler class. The class must implement the Weborb.Messaging.Api.IScopeHandler interface or can extend the Weborb.Messaging.Server.Adapter.ApplicationAdapter class (recommended).
Application handler receives the following callbacks from the WebORB server:
public virtual
bool appStart( IScope
app );
public virtual bool
appStop( IScope app );
public virtual bool
roomStart( IScope room );
public virtual void
roomStop( IScope room );
public virtual bool
appConnect( IConnection conn, Object[] parms );
public virtual bool
roomConnect( IConnection conn, Object[] parms );
public virtual void appDisconnect(
IConnection conn );
public virtual void
roomDisconnect( IConnection conn );
public virtual bool
appJoin( IClient client, IScope app );
public virtual void
appLeave( IClient client, IScope app );
public virtual bool
roomJoin( IClient client, IScope room );
public virtual void
roomLeave( IClient client, IScope room );
using System;
using System.Collections.Generic;
using System.Text;
using Weborb.Messaging.Api;
using Weborb.Messaging.Api.Service;
using Weborb.Messaging.Server.Adapter;
namespace Weborb.Examples.ClientCallback
{
public class
AppHandler : ApplicationAdapter
{
public override bool appConnect(
IConnection conn, object[]
parms )
{
// get the connections for
the scope (scope comes from the base class)
IEnumerator<IConnection>
connections = scope.getConnections();
Object[] args =
new Object[] {
conn.getClient().getId() };
// iterate over the connections
while(
connections.MoveNext() )
{
IConnection
connection = connections.Current;
// invoke
client side function via the client connection
if(
connection is
IServiceCapableConnection )
((IServiceCapableConnection)connection).invoke(
"clientConnected",
args );
}
//notify client about his
ID
if( conn
is IServiceCapableConnection
)
((IServiceCapableConnection)conn).invoke(
"setClientID", args );
return true;
}
public override void
appDisconnect( IConnection conn )
{
IEnumerator<IConnection>
connections = scope.getConnections();
Object[] args =
new Object[] {
conn.getClient().getId() };
while(
connections.MoveNext() )
{
IConnection
connection = connections.Current;
if( connection
is IServiceCapableConnection
)
((IServiceCapableConnection)connection).invoke(
"clientDisonnected",
args );
}
}
}
}
Download full source code listing here.
Compile the application handler class and place it into the WebORB's /bin folder. If WebORB runs inside of IIS, the /bin folder is the same where all class libraries for the given ASP.NET application are deployed. If WebORB runs standalone, the /bin folder is where weborb.dll resides.
Create "CallbackDemo" folder under /Applications. The name of the folder will be used in the client code to connect to the application. Place app.config into /Applications/CallbackDemo. The file must contain the following contents:
<?xml
version="1.0" encoding="utf-8"?>
<configuration>
<application-handler>
Weborb.Examples.ClientCallback.AppHandler
</application-handler>
</configuration>
The client side for this example uses Flex, however the same approach is applicable to the Flash applications.
Create a Flex Builder project as described in this article. The approach is to use the NetConnection api to establish a connection to the WebORB server. When the client establishes a connection, WebORB invokes the appConnect method used in the C# example above. Similarly, when a client disconnects from the application, WebORB invokes the appDisconnect method on the associated handler class.
The code below shows how to establish a connection with WebORB:
private var m_connection:NetConnection;
public
function InitConnection() :
void
{
var uri:String = ServerConfig.getChannel( "my-rtmp"
).endpoint;
m_connection = new NetConnection();
m_connection.client = this;
m_connection.objectEncoding = ObjectEncoding.AMF0;
m_connection.addEventListener( NetStatusEvent.NET_STATUS, handleNetStatus
);
m_connection.connect( uri + "/CallbackDemo"
);
}
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
xmlns:local="*"
creationComplete="InitConnection()" >
....
....
</mx:Application>
public function setClientID(
myID:String ) : void
{
// log event somewhere
}
public function clientConnected( clientID:String ) : void
{
// log event somewhere
}
public function clientDisconnected( clientID:String ) : void
{
// log event somewhere
}
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" width="351" height="351"
creationComplete="InitConnection()" >
<mx:Script>
<![CDATA[
import
mx.messaging.config.ServerConfig;
private var
m_connection:NetConnection;
public function
InitConnection() : void
{
var uri:String =
ServerConfig.getChannel( "my-rtmp"
).endpoint;
m_connection =
new NetConnection();
m_connection.client = this;
m_connection.objectEncoding =
ObjectEncoding.AMF0;
m_connection.connect( uri +
"/CallbackDemo" );
}
public
function setClientID( myID:String ):void
{
clientID.text = myID;
}
public
function clientConnected( clientID:String ) :
void
{
output.text =
"Client connected - " + clientID +
"\n" + output.text;
}
public
function clientDisconnected( clientID:String ) :
void
{
output.text =
"Client disconnected - " + clientID +
"\n" + output.text;
}
]]>
</mx:Script>
<mx:Panel x="10" y="10"
width="331"
height="331" layout="absolute"
title="Server
to client callback demo">
<mx:Label x="10" y="19"
text="Client ID:"/>
<mx:Text x="77" y="19" id="clientID"/>
<mx:TextArea x="10" y="72"
width="291" height="209" id="output"/>
<mx:Label x="10" y="49"
text="Events:"/>
</mx:Panel>
</mx:Application>