red5 remote ShareObject

原文链接

 

ShareObject 主要用途

 

SharedObjects (SOs)  主要用于多客户端的实时数据同步和方法统一调用。SharedObject 是一个远程的对象能够被多个客户端共享,也就说这些客户端在同一个域(scope)里面。

 

 什么是 scope?

你可以把scope 当作一个聊天室,这个聊天室是通过URI 链接到服务器

例如:rtmp://localhost/red5test/lobby

"red5test"  是application 域(scope) 

"lobby" 是聊天室作用域,也即 "red5test" 子域

 

 

客户端代码的编写

 

客户端可以用下面的代码获得 SharedObject  连接:

 

// 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");

 

red5 处理 ShareObject 过程

当客户端程序连接到SharedObject,red5就会查找指定作用域SharedObject是否存在(例如上面程序“chat”).如果存在,red5就会重用它;如果不存在,red5 就会在该作用域下创建新的SharedObject提供客户端使用。

当最后一个客户端从该作用域断开连接,SharedObject就会被销毁(at least for non-persistent ones)。

 

服务端 ShareObject  处理过程

a)服务端获取 SharedObject

也可以从服务获取 SharedObject ,例如,服务端可以对SharedObject 做改动,让后把这些改动以广播的方式传递给客户端

在你的 java程序中你可以用如下的代码检查SharedObject 的存在

//get scope of the current connection first
IScope scope = Red5.getConnectionLocal().getScope();
// get SO
ISharedObject so = getSharedObject(scope, "chat");

 b)服务端创建 SharedObject

当room 创建后,就可以创建新的 SharedObject 了,方法是覆写 ApplicationAdapter  roomStart 的 roomStart  方法,代码如下:

 

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;
  }

}

 如果需要创建 application 作用域 SharedObject ,那么你需要在appStart 方法中做如同上面代码所做工作

 

自己创建 ShareObject  问题

其中一个有利因素是你可在SharedObject 增加一个监听,当客户连接到SharedObject 时,你可以更新数据或者断开连接等等。

 客户端 还是 服务端  初始化 SharedObject 

在java 服务端创建 SharedObject  会有意料不到的问题(至少对我来说有),这些问题大部分与客户端,服务端初始化 SharedObject  有关。

当然所有的 SharedObject  都是在red5server 上创建的,但是不同之处是在哪儿初始化。

 

a)服务端初始化 SharedObject  ,SharedObject  是同过java 服务端  调用createSharedObject 创建的,创建后就等待客户端的连接

 

b)客户端是初始化SharedObject  是客户端连接到服务端时候,服务端发现不存在SharedObject 然后自动创建的。

问题会出现在你自定义服务端代码来创建SharedObject  

例如我想创建 application 作用域名叫 "chat " 的SharedObject  ,并且添加一个监听,所以我在appStart 加入如下的代码:

createSharedObject(scope, "chat", false);
ISharedObject so = getSharedObject(scope, "chat");
ISharedObjectListener listener = new MyCustomListener();
so.addSharedObjectListener(listener);

 appStart 方法在服务器启动时只被调用一次,启动后服务端创建名叫chat 的 SharedObject 对象 。客户端可以用application 作用域连接到 chat 对象,至此所有的工作都很正常。

但是当所有的客户端断开chat 的连接后,由服务端创建的chat 会被red5服务器销毁,之后当客户端再次连接chat 对象,red5 将找不到 chat 对象并自动创建一个 chat 。新的chat对象 是由客户端初始化创建的,这自动的创建方式,没有加入监听,所以自定义事件将不会得到响应。

这样的问题不会出现的room 作用域中,假设把上面的代码放到 roomStart 方法中。当最后一个客户端断开连接后 room 也会被销毁,roomStart 方法在 application 生命周期中将多次被调用,例如:当第一客户端连接一个room .这种情况下问题会出现在最后的客户端断开的不是它连接的room.

 

 

自己创建 ShareObject  问题解决办法

如果有些类似如SharedObjectCreationHandler 或者 SharedObjectFactory 方法就好了,不幸的是没有。

但是 ISharedObjectSecurity 提供了此类的解决方案

ISharedObjectSecurity 可以在 Application 中被  registerSharedObjectSecurity 注册,它被用来控制SharedObject的访问,它有一个名叫isCreationAllowed事件方法,该方法在自动创建ObjectSecurity 前判断能否被调用方法创建。

代码如下:

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;
  }

  ...

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
注意事项: 1、主进程传入的对象或变量不管是不是ref线程内操作传入的引用都会影响主进程的对象或变量,且对象只能是nonvisualobject类型的。 2、基础变量如long等等都不能传引用ref会运行会报错 3、SharedObjectUnregister只是把SharedObjectDirectory中的去掉,实际内存不会释放必须destroy 4、主进程不能直接访问线程中的变量和对象,可以通过处理类私有的办法处理。 5、千万注意释放线程的时候一定要把线程里面的资源释放完,不然百分百卡死。比如一个线程里面有一个timing的计时器,如果不先stop(),直接destroy,百分百卡死。如果连接数据库或者其他接口时千万注意了!!!千万要在uf_stop()(此例子中的释放预留方法)里面把所有的资源都释放干净,资源都释放干净,源都释放干净,都释放干净,释放干净,放干净,干净,净…… 大体设计思路: 1、在主进程中建立一个“任务信息类”数组,其中包含“任务线程类”,一个任务对应一个线程。 2、在主进程中建立一个“任务管理类”,负责处理任务信息类。 简单举例: 1、新建1个“任务管理类”,再新建N“任务信息类”,将“任务信息类”赋值完成加入“任务管理类”,并创建一个“任务线程类”,此时线程开始running。 2、“任务线程类”中有一个内部timing类,监控自己是否执行完成,会改标志。“任务管理类”也有一个timing监控“任务信息类”和“任务线程类”的情况,把完成的结束。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值