Red5的共享对象有一条很关键:当没有客户端连这个共享对象时,该共享对象自动清空。客户端再次连接该共享对象时将创建新的同名共享对象,这时属性值为空。
创建:
当调用ApplicationAdapter的public boolean createSharedObject(IScope scope, String name, boolean persistent)方法时,就在scope下创建了一个名为name的共享对象。它又调用ISharedObjectService的createSharedObject方法。ISharedObjectService是在red5-common.xml中注入的,默认是org.red5.server.so.SharedObjectService。它的创建方法是:
1: /** {@inheritDoc} */
2: public boolean createSharedObject(IScope scope, String name, boolean persistent) {
3: if (hasSharedObject(scope, name)) {
4: // The shared object already exists.
5: return true;
6: }
7: synchronized (scope) {
8: final IBasicScope soScope = new SharedObjectScope(scope, name, persistent, getStore(scope, persistent));
9: return scope.addChildScope(soScope);
10: }
11: }
可以看到创建共享对象其实就是new了一个SharedObjectScope,它继承了BaseScope,实现了ISharedObject接口。
1: public class SharedObjectScope extends BasicScope implements ISharedObject, StatusCodes
通过ApplicationAdapter的getSharedObject方法获取共享对象其实就是SharedObjectScope这个Scope!它有一个SharedObject成员,它负责存取具体的共享对象属性值。SharedObject并没有实现ISharedObject,我们平常操作的共享对象是ISharedObject(其实就是SharedObjectScope这个Scope),并非SharedObject对象。
当有客户端连接名为name的共享对象时,如果没有则调用ISharedObjectService的createSharedObject方法创建一个名为name的共享对象(scope)。
销毁:
客户端断开共享对象的连接,其实就是断开共享对象这个scope的连接!客户端发起断开共享对象的连接的事件时,RTMPHandler监听到SharedObject事件,进入onSharedObject处理函数。将共享对象消息分派给SharedObjectScope(实现ISharedObject接口)的dispatchEvent处理,根据消息的类型(SERVER_DISCONNECT)要么从rtmp连接中注销这个Scope(unregisterBasicScope),要么removeEventListener。
1: public void unregisterBasicScope(IBasicScope basicScope) {
2: basicScopes.remove(basicScope);
3: basicScope.removeEventListener(this);
4: }
它依然走了SharedObjectScope的removeEventListener方法。
1: @Override
2: public void removeEventListener(IEventListener listener) {
3: so.unregister(listener);
4: //part 1 of the fix for TRAC #360 - if we have not been released by all that acquired then
5: //keep on disconnection of the last listener
6: if (so.isAcquired()) {
7: keepOnDisconnect = true;
8: }
9: //remove the listener
10: super.removeEventListener(listener);
11: //part 2 of the fix for TRAC #360 - check acquire
12: if (!so.isPersistentObject() && (so.getListeners() == null || so.getListeners().isEmpty()) && !so.isAcquired()) {
13: getParent().removeChildScope(this);
14: }
15:
16: for (ISharedObjectListener soListener : serverListeners) {
17: soListener.onSharedObjectDisconnect(this);
18: }
19: }
so.unregister中
1: protected void unregister(IEventListener listener) {
2: listeners.remove(listener);
3: listenerStats.decrement();
4: checkRelease();
5: }
调用了checkRelease()方法:
1: /**
2: * Check if shared object must be released.
3: */
4: protected void checkRelease() {
5: //part 3 of fix for TRAC #360
6: if (!isPersistentObject() && listeners.isEmpty() && !isAcquired()) {
7: log.info("Deleting shared object {} because all clients disconnected and it is no longer acquired.", name);
8: if (storage != null) {
9: if (!storage.remove(this)) {
10: log.error("Could not remove shared object.");
11: }
12: }
13: close();
14: }
15: }
看到了吗“Deleting shared object {} because all clients disconnected and it is no longer acquired.”,。在close中删除了共享对象的所有属性。再回到removeEventListener中:
1: if (!so.isPersistentObject() && (so.getListeners() == null || so.getListeners().isEmpty()) && !so.isAcquired()) {
2: getParent().removeChildScope(this);
3: }
这里将SharedObjectScope这个Scope删掉了。
客户端再次连到这个共享对象时,如果没有则再次创建:
1: if (!sharedObjectService.createSharedObject(scope, name, persistent)) {
2: sendSOCreationFailed(conn, name, persistent);
3: return;
4: }
如果你的应用希望没有客户端连接时仍然保持着共享对象,可以通过checkRelease函数找解决办法——checkRelease有如下判断:
隐藏行号 复制代码 ? 这是一段程序代码。
if (!isPersistentObject() && listeners.isEmpty() && !isAcquired())
只有当该共享对象不是持久化的且没有客户端监听且没有获取(acquireCount=0)时,才走close清空共享对象。所以要想满足不清空的需求,要么让其持久化,要么监听不为空,要么acquireCount>0。对于非持久化的共享对象。系统调用
一下,就能保证所有客户端断开共享对象时acquireCount仍然大于0。以后需要释放的时候调用:
即可。
release函数源代码:
隐藏行号 复制代码 ? 这是一段程序代码。
-
public void release() {
-
if (acquireCount.get() == 0) {
-
throw new RuntimeException("The shared object was not acquired before.");
-
}
-
if (acquireCount.decrementAndGet() == 0) {
-
checkRelease();
-
}
}
当前acquireCount==0时调用release将会抛异常,提示“The shared object was not acquired before.”。
分享到:
相关推荐
包括音频、视频的发布、播放,以及数据对象的共享。 3. **录制与回放功能**:Red5支持对流媒体内容进行录制和回放,这对于在线教育、会议记录等场景十分有用。录制功能可以将实时流保存为FLV或F4V文件,而回放则能...
Red5是基于Java开发的,能够实现与Adobe的FMS(Flash Media Server)相似的功能,包括实时流媒体传输、录制播放视频、共享对象以及远程调用等。通过Red5,开发者可以构建诸如视频播放网站、远程教育平台、视频会议...
Red5是一个开源的流媒体服务器平台,它提供了与Macromedia公司的Flash Media Server(FMS)相似的功能,主要支持基于Adobe Flash平台的实时通信应用,如音频、视频流,以及共享对象通信等。Red5利用Java语言开发,...
3. **互动性**:Red5支持Flash Player的交互功能,如共享对象、远程调用和屏幕共享,这使得开发具有高度交互性的在线应用成为可能。 4. **可扩展性**:通过Java平台,Red5提供了丰富的API和插件机制,用户可以根据...
此外,Red5的安全特性也是不可忽视的一部分,它提供了对流媒体播放和发布的安全控制,以及对共享对象的保护机制,确保数据传输的安全性。 #### JRuby与RTMPT协议 除了Java,Red5还支持JRuby,即运行于Java虚拟机上...
Red5是一款用Java编写的服务器,支持RTMP、RTMPT、RTMPS、RTMPE等多种协议,这些协议广泛应用于音频、视频流和数据共享。在聊天应用中,Red5可以创建一个或多个聊天室,允许用户加入并发送消息。 然后,深入Flex。...
- **概念解析**:SharedObject是Red5中用于存储跨连接会话数据的机制,能够在不同用户间共享信息,适用于游戏中的移动同步等场景。 - **移动同步原理**:通过SharedObject,游戏中的玩家移动和其他动态信息能够实时...
5. **远程方法调用**: 提供了一种机制,允许在不同客户端之间调用远程对象的方法。 #### 三、环境搭建 1. **安装J2EE 5**: - J2EE 5是一个企业级应用平台的标准版本,它包含了Java EE 5规范,支持包括EJB 3.0在内...
Red5还支持共享对象(SharedObject),这是一种在客户端和服务器之间共享数据的机制,类似于Web浏览器中的cookie,但具有更大的存储容量和更低的延迟。 在“基于red5的多人聊天”项目中,SharedObject起到了关键...
RED5 API文档可能包含了如何在应用中使用共享对象进行数据交互的说明。 "RED5-0_6_2-API"文件名表明这是RED5 0.6.2版本的API文档。不同版本的RED5可能会有不同的特性和改进,因此,查阅特定版本的API可以帮助开发者...
Java RED5是一款开源的Flash流媒体服务器,它允许开发者创建实时的、交互式的网络应用程序,如视频会议系统。...通过深入理解和掌握RED5的内部机制,开发者可以构建出稳定、高效的网络会议平台,满足各种业务需求。
迁移指南部分涵盖了从旧版本Red5迁移到新版本时需要注意的应用程序回调接口、处理类、客户端方法调用、共享对象的服务器端监听器以及服务器持久化等方面。此外,还提供了关于如何处理周期性事件、远程调用的服务器和...
ApplicationAdapter提供了共享对象、流管理和连接列表的控制,实现了IstreamAwareScopeHandler接口,使得在应用程序中控制流成为可能。开发者可以通过继承ApplicationAdapter并重写其方法来实现自定义的功能,比如...
**Red5服务器详解** Red5是一款强大的开源流媒体服务器,主要功能与Macromedia公司的FMS(Flash Media Server)相似,特别适用于基于Flash的流媒体服务。它的出现为开发者提供了更多的选择,因为它是用Java语言编写...
`IBasicScope`是所有范围对象的基类接口,包括共享对象(SharedObjects)。`IScope`接口则表示一个范围,它可能是应用、频道或其他自定义的逻辑分组,用于组织和隔离服务器资源。 8. **IBWControllable**: 这个...