Interesting. I will try and get together a simple test case which shows
my problem in more detail. The particular occasion my problem is now
and replugging my network cable (as opposed to restarting the server). I
This is interesting. I am not replacing the NetConnection instance
currently (I am just calling connect() on the existing instance). I will
helps... I am refreshing the shared object by calling
That isn't the case for me. The SharedObjects are only updated by the
>
> Nik
>
>
> Kelvin Luck wrote:
>> Hi Tonic,
>>
>> Thanks for this thorough and timely write up!
>>
>> I'm not sure if you've been following my "Reconnected client
>> SharedObject sync events not firing" thread but it seems like this
>> information could be very helpful in solving my issues...
>>
>> Do you think that server initiated shared objects might solve my
>> problems with sync events not firing after re-connection?
>>
>> Thanks,
>>
>> Kelvin :)
>>
>> tonic wrote:
>>> Hello Red5 Community,
>>>
>>> i am kind of new to red5 and spend the last days tyring to figure out
>>> how to use shared objects with red5.
>>> In the following lines i like to summarise my experiences. This should
>>> serve as a hint for others who come accross the same questions and
>>> problems that i did.
>>> Please feel free to correct or supplement the following lines where
>>> neccessary.
>>>
>>> When discussing SharedObjects in the following, i refer to Remote Shared
>>> Objects and not Local Shared Objects of course.
>>> I also focus on non-persistent ones.
>>>
>>> *What are SharedObjects good for?*
>>>
>>> SharedObjects (SOs) are helpful to synchronize data between multiple
>>> clients in real-time and to invoke methods on multiple clients at once.
>>>
>>> A Remote SharedObject is an Object which is shared between multiple
>>> clients, namely all clients of the same scope.
>>>
>>> /So what is a Scope? /
>>> You can think of a scope as a chat room which is defined by the *uri*
>>> that is used to connect the server:
>>> e.g. rtmp://localhost/red5test/lobby
>>> red5test is the application scope
>>> lobby is a room scope, a child scope of red5test
>>> for more information on scopes see:
>>>
http://jira.red5.org/confluence/display/docs/Scopes+and+Contexts>>> <
http://faindu.wordpress.com/2007/07/09/what-are-remote-shared-object-rso-for/>
>>>
>>> *How to connect to SOs (clientside)?*
>>>
>>> A Client can connect to a SO using the following Actionscript lines:
>>>
>>> // at first you need to establish a connection to the server of course
>>> nc = new NetConnection();
>>> nc.connect( "rtmp://localhost/red5test/", true );
>>>
>>> // when the NetConnection is successfully established (you have to listen
>>> to NetStatusEvent.NET_STATUS event)
>>> // you can connect to a remote SharedObject e.g. named "chat"
>>> so = SharedObject.getRemote("chat", nc.uri, false);
>>>
>>> // when the connection to the SO is successfully established, you can
>>> begin to specify its contents
>>> so.setProperty("message","hello to all");
>>>
>>> *How does red5 handle SOs?*
>>>
>>> If a client connects to a SO, red5 looks into the specified scope if a
>>> SO named e.g. "chat" already exists.
>>> If it does, red5 uses it, if not, red5 creates a new SO for the Scope
>>> and uses that.
>>> When the last client connected to a SO disconnects from it, the SO will
>>> be destroyed (at least for non-persistent ones).
>>>
>>> *SOs on the serverside*
>>>
>>> */a) Access SOs on the serverside/*
>>> SOs can also be accessed from the serverside, i.e. the server also can
>>> make changes to the SO and broadcast them to all connected clients.
>>>
>>> To check wether a certain SO exists you can use the following lines in
>>> your Java Application:
>>>
>>> //get scope of the current connection first
>>> IScope scope = Red5.getConnectionLocal().getScope();
>>> // get SO
>>> ISharedObject so = getSharedObject(scope, "chat");
>>>
>>> */b) Create SOs on the serverside/*
>>>
>>> You can also create SOs on the serverside with the following lines:
>>>
>>> extracted from Joachim Bauchs tutorial
>>> (
http://www.joachim-bauch.de/tutorials/red5/MigrationGuide.txt#sharedobjects):>>>
>>> To create a new shared object when a room is created, you can override
>>> the method roomStart in your application:
>>>
>>> public class SampleApplication extends ApplicationAdapter {
>>>
>>> public boolean roomStart(IScope room) {
>>> if (!super.roomStart(room))
>>> return false;
>>>
>>> createSharedObject(room, "sampleSO", true);
>>> ISharedObject so = getSharedObject(room, "sampleSO");
>>>
>>> // Now you could do something with the shared object...
>>>
>>> return true;
>>> }
>>>
>>> }
>>>
>>> If a shared object should be created for connections to the main
>>> application, e.g. rtmp://server/application, the same must be done in
>>> the method appStart.
>>>
>>> ---
>>> <
http://www.joachim-bauch.de/tutorials/red5/MigrationGuide.txt#sharedobjects>--
>>>
>>> /*So what is it good for to create SOs by yourself when red5 does it for
>>> you automatically?*/
>>>
>>> One advantage is, that you can attach a Listener to the SO which is
>>> notified when a new client connects to the SO, updates data, disconnects
>>> etc. (See ISharedObjectListener
>>> <
http://dl.fancycode.com/red5/api/org/red5/server/api/so/ISharedObjectListener.html>)
>>>
>>> *Problem: clientside initiated vs. serverside initiated SOs*
>>>
>>> Creating SOs in your java application code can leed to some unexpected
>>> problems (It was at least for me).
>>> The problem is related to something i refer to as clientside vs.
>>> serverside initiated SOs.
>>> Of course all SOs wil be created on the red5 server. But there is a
>>> difference who initiated the creation.
>>> a) a serverside initiated SO is a SO that you have created with
>>> createSharedObject in your serverside code. It is then waiting for
>>> clients to connect.
>>> When a client connects to this SO, your custom implementation will be
>>> used.
>>> b) a clientside initiated SO is a "generic" SO that red5 automatically
>>> creates right in the moment when red5 recognizes that the SO a client
>>> connects does not exist.
>>>
>>> The problem arises when you want to create a custom serverside SO for
>>> the main application:
>>> e.g. I want to create an SO named "chat" in the main application scope
>>> and add a listener to it. So i put the following lines in my appStart
>>> method:
>>>
>>> createSharedObject(scope, "chat", false);
>>> ISharedObject so = getSharedObject(scope, "chat");
>>> ISharedObjectListener listener = new MyCustomListener();
>>> so.addSharedObjectListener(listener);
>>>
>>> Now when i start the server, *appStart* is called once the Application
>>> starts.
>>> My custom SO named "chat " will be created (a serverside-initiated SO).
>>> Now when a client connects to the SO named "chat" in the main
>>> application scope, my custom SO will be used by red5.
>>> Everything works fine untill now.
>>> But when all clients disconnect form this SO, my custom, serverside
>>> initiated SO will be destroyed by red5.
>>> After that, when a client connects to the SO named "chat", red5 won't
>>> find it anymore and will automatically create a new "genric" one.
>>> This new one now is clientside initiated, as i did not create it in the
>>> serverside code with createSharedObject.
>>> The difference now is, that no listener is attached to the new generic
>>> SO, and so no events will be fired anymore.
>>>
>>> This problem is not that severe for SOs in a room scope. In this case
>>> you put your creation code inside the *roomStart* method.
>>> As the room is also destroyed when the last connected client
>>> disconnects, the roomStart method will be called multiple times during
>>> the application lifecycle, i.e. everytime the first client connects to a
>>> room. In this case the problem only arises when the last client
>>> disconnects from the SO but not the room.
>>>
>>> /*So what solution is there to this problem?*/
>>>
>>> It would be good to have something like a SharedObjectCreationHandler or
>>> a SharedObjectFactory, but unfortunately there is nothing like that.
>>> But there is a Handler which handles sort of SO creation events: the
>>> ISharedObjectSecurity
>>> <
http://dl.fancycode.com/red5/api/org/red5/server/api/so/ISharedObjectSecurity.html>.
>>> This handler can be registered in the Application by
>>> registerSharedObjectSecurity
>>> <
http://dl.fancycode.com/red5/api/org/red5/server/adapter/MultiThreadedApplicationAdapter.html#registerSharedObjectSecurity%28org.red5.server.api.so.ISharedObjectSecurity%29>.
>>> Its use is to controll access to shared objects.
>>> It contains an event method named *isCreationAllowed*: Prior to
>>> automatically creating a SO red5 checks if creation is allowed by
>>> calling this method.
>>> Now if you want a custom serverside initiated SO to be created everytime
>>> red5 automatically tries to create a SO, you can put your SO creation
>>> code inside this method and return true.
>>> Red5 then knows creation is allowed and tries to create a SO. To do this
>>> red5f first checks if the SO already exists and !big surprise! it does,
>>> so red5 uses it and does not create one on its own.
>>>
>>> import static org.red5.server.api.ScopeUtils.getScopeService;
>>> ...
>>>
>>> public class MySecurityHandler implements ISharedObjectSecurity
>>> {
>>>
>>> ...
>>>
>>> public boolean isCreationAllowed(IScope scope, String name, boolean
>>> persistent)
>>> {
>>> if ( "chat".equals(name) )
>>> {
>>> // get the SO creation service. Basically the following lines are
>>> exactly what MultiThreadedApplicationAdapter does.
>>> // You can also pass a reference to your Application to this
>>> SecurityHandler and use it instead
>>> ISharedObjectService service = (ISharedObjectService)
>>> getScopeService(scope, ISharedObjectService.class,
>>> SharedObjectService.class, false);
>>>
>>> if( service.createSharedObject(scope, name, persistent) == true )
>>> {
>>> ISharedObject so = service.getSharedObject(scope, name);
>>> ISharedObjectListener listener = new MyCustomListener();
>>> so.addSharedObjectListener(listener);
>>> }
>>> }
>>> return true;
>>> }
>>>
>>> ...
>>>
>>> }
>>>
>>> The method described here, was also discussed in: [Red5] creation
>>> handler to ShareObject
>>> <
http://osflash.org/pipermail/red5_osflash.org/2008-February/018579.html>
>>>
>>> *Last but not the least: When is it better to use a SharedObject and
>>> when to use invokes?*
>>>
>>> Here is good mail discussing that topic:
>>> /
http://osflash.org/pipermail/red5_osflash.org/2007-August/014406.html/>>>
>>> That's all,
>>> hopefully it helps somebody.
>>>
>>> Cheers,
>>> Nik
>>>
>>> -----------------
>>>
>>> Further tutorials on SOs:
>>>
>>> What are Remote Shared Objects (RSO) for?
>>> <
http://faindu.wordpress.com/2007/07/09/what-are-remote-shared-object-rso-for/>
http://www.joachim-bauch.de/tutorials/red5/MigrationGuide.txt#sharedobjects>>>
http://www.joachim-bauch.de/tutorials/red5/HOWTO-Security.txt#shared-objects>>> Shared Whiteboard application in Red5
>>> <
http://sunil-gupta.blogspot.com/2007/04/shared-whiteboard-application-in-red5.html>
>>>
>>>
>>> ------------------------------------------------------------------------
>>> View this message in context: SharedObject experience & tips
>>> <
http://www.nabble.com/SharedObject-experience---tips-tp16010760p16010760.html>
>>> Sent from the Red5 - English mailing list archive
>>> <
http://www.nabble.com/Red5---English-f16329.html> at Nabble.com.
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>> _______________________________________________
>>> Red5 mailing list
>>>
Red5@...
>>>
http://osflash.org/mailman/listinfo/red5_osflash.org>> _______________________________________________
>> Red5 mailing list
>>
Red5@...
>>
http://osflash.org/mailman/listinfo/red5_osflash.org>>
>>
>