注意:在这个例子中,只是这个应用程序的作用域有sample处理程序,而不是子作用域,如果想这个处理程序同样在房间中起作用,必须在房间的作用域内的roomStart方法中注册它。
调用客户端的方法
从red5的应用程序中调用客户端方法函数,你首先需要一个当前连接对象作为参考
代码如下:
import org.red5.server.api.IConnection;
import org.red5.server.api.Red5;
import org.red5.server.api.service.IServiceCapableConnection;
...
IConnection conn = Red5.getConnectionLocal();
如果这个连接对象执行了IServiceCapableConnection,那么它就支持调用在另一个目标的方法
代码如下:
if (conn instanceof IServiceCapableConnection) {
IServiceCapableConnection sc = (IServiceCapableConnection) conn;
sc.invoke("the_method", new Object[]{"One", 1});
}
如果你需要方法调用的结果,你必须提供一个类作为第三个参数,这个类执行IPendingServiceCallback
代码如下:
import org.red5.server.api.service.IPendingService;
import org.red5.server.api.service.IPendingServiceCallback;
class MyCallback implements IPendingServiceCallback {
public void resultReceived(IPendingServiceCall call) {
// Do something with "call.getResult()"
}
}
The method call looks now like this:
这个方法的调用例子如下:
if (conn instanceof IServiceCapableConnection) {
IServiceCapableConnection sc = (IServiceCapableConnection) conn;
sc.invoke("the_method", new Object[]{"One", 1}, new MyCallback());
}
当然你能够在你的应用程序中执行这些,而且能传递该应用程序的实例
共享对象
访问和处理共享对象的接口函数已经被指定在ISharedObjectService类中
当我们在服务器端执行脚本处理共享对象的时候,需要特别指出的是这些被操作的共享对象一定要是在同一个作用域中被创建的。
当一个房间被被创建的同时创建一个新的共享对象,你可以在应用程序中重写你的roomStart函数:
import org.red5.server.adapter.ApplicationAdapter;
import org.red5.server.api.IScope;
import org.red5.server.api.so.ISharedObject;
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;
}
}
现在每次第一个用户连接到该应用程序的房间时,一个共享对象 sampleSO就会被服务器端创建.
一个共享对象应该被创建作为主程序的连接点,例如:rtmp://server/application 那么这个创建动作就应该在函数appStart中进行.
关于进一步的共享对象的函数信息,请大家参考ISharedObject的api参考文档
服务器端执行改变监听事件
要像在FCS/FMS一样,得到共享对象的改变信息,一个监听器,就必须实现ISharedObjectListener类,示例代码如下:
import org.red5.server.api.so.ISharedObject;
import org.red5.server.api.so.ISharedObjectListener;
public class SampleSharedObjectListener
implements ISharedObjectListener {
public void onSharedObjectUpdate(ISharedObject so,
String key, Object value) {
// The attribute <key> of the shared object <so>
// was changed to <value>.
}
public void onSharedObjectDelete(ISharedObject so, String key) {
// The attribute <key> of the shared object <so> was deleted.
}
public void onSharedObjectSend(ISharedObject so,
String method, List params) {
// The handler <method> of the shared object <so> was called
// with the parameters <params>.
}
// Other methods as described in the interface...
}
此外,这个监听器还必须被注册在共享对象上,代码如下:
ISharedObject so = getSharedObject(scope, "sampleSO");
so.addSharedObjectListener(new SampleSharedObjectListener())
从应用程序代码去改变共享对象的值
在服务器端改变共享对象示例代码如下:
ISharedObject so = getSharedObject(scope, "sampleSO");
so.setAttribute("fullname", "Sample user");
所有的作用域范围内注册了事件处理器的客户端也都会收到共享对象属性更改的通知
如果想要把多个操作共享对象的操作合并成一条更新事件发给作用域内的所有客户端,那么可以使用函数beginUpdate 和endUpdate,代码如下:
ISharedObject so = getSharedObject(scope, "sampleSO");
so.beginUpdate();
so.setAttribute("One", "1");
so.setAttribute("Two", "2");
so.removeAttribute("Three");
so.endUpdate();
服务器端执行的监听器将会通过各自的回调函数收到他们的更新通知
共享对象事件处理
从一个flash客户端或者相应的服务器端,通过remote_so.send(<handler>, <args>)调用共享对象,这个调用会被映射为red5的函数,因此一个事件处理程序必须通过ISharedObjectHandlerProvider的函数被注册。示例代码如下:
package com.fancycode.red5;
class MySharedObjectHandler {
public void myMethod(String arg1) {
// Now do something
}
}
...
ISharedObject so = getSharedObject(scope, "sampleSO");
so.registerServiceHandler(new MySharedObjectHandler());
可以给处理程序命名,代码如下:
ISharedObject so = getSharedObject(scope, "sampleSO");
so.registerServiceHandler("one.two", new MySharedObjectHandler());
这里处理程序被命名为one.two.myMethod
另一个为共享对象定义事件处理程序的方法是在red5-web.xml文件中增加他们
具体实例如下:
<bean id="sampleSO.one.two.soservice"
class="com.fancycode.red5.MySharedObjectHandler"
singleton="true" />
持续性(持久性)
持续性被用于如在服务器重启后,对象的属性仍然有效能被使用。在FCS/FMS中通常有些服务器端的局部共享对象被用于这方面
Red5能使任意的对象具有持续性(持久性),实现他们需要使用IPersistable 类,基本上这些对象都会有 类型,路径,字符串名称 并且他们知道怎样去序列化和反序列化他们本身
下面是个序列化和反序列化的例子:
import java.io.IOException;
import org.red5.io.object.Input;
import org.red5.io.object.Output;
import org.red5.server.api.persistence.IPersistable;
class MyPersistentObject implements IPersistable {
// Attribute that will be made persistent
private String data = "My persistent value";
void serialize(Output output) throws IOException {
// Save the objects's data.
output.writeString(data);
}
void deserialize(Input input) throws IOException {
// Load the object's data.
data = input.readString();
}
// Other methods as described in the interface...
}
保存或者载入这个对象可以使用如下示例代码:
import org.red5.server.adapter.ApplicationAdapter;
import org.red5.server.api.IScope;
import org.red5.server.api.Red5;
import org.red5.server.api.persistence.IPersistenceStore;
class MyApplication extends ApplicationAdapter {
private void saveObject(MyPersistentObject object) {
// Get current scope.
IScope scope = Red5.getConnectionLocal().getScope();
// Save object in current scope.
scope.getStore().save(object);
}
private void loadObject(MyPersistentObject object) {
// Get current scope.
IScope scope = Red5.getConnectionLocal().getScope();
// Load object from current scope.
scope.getStore().load(object);
}
}
对于一个应用程序如果被要求没有自定义的对象,而且是数据后来还要被重复使用,那么可以用类IAttributeStore ,将他们存储在作用域内,作用域内的所有属性都不是用IPersistable方式开启的,
后端存储这些对象的方式是可以配置的,默认的状态下存储在内存和文件系统中是有效滴
使用文件系统的存储方式时,会为每一个对象创建一个文件,这个文件会被创建在"webapps/<app>/persistence/<type>/<path>/<name>.red5",例如:对于一个共享对象“theSO”存在于"rtmp://server/myApp/room1"的连接中,同时一个文件会创建在"webapps/myApp/persistence/SharedObject/room1/theSO.red5"
循环事件
应用程序中都需要按规律执行某个任务,在FCS/FMS中使用setInterval函数去执行循环事件
Red5提供了一个时序安排服务在ISchedulingService类中,该类也和其他服务一样是继承自ApplicationAdapter类。这个服务能够注册一个对象(这个对象需要实现IScheduledJob类)执行以固定时间间隔去执行函数
去注册这个对象的类似示例代码如下:
import org.red5.server.api.IScope;
import org.red5.server.api.IScheduledJob;
import org.red5.server.api.ISchedulingService;
import org.red5.server.adapter.ApplicationAdapter;
class MyJob implements IScheduledJob {
public void execute(ISchedulingService service) {
// Do something
}
}
public class SampleApplication extends ApplicationAdapter {
public boolean roomStart(IScope room) {
if (!super.roomStart(room))
return false;
// Schedule invokation of job every 10 seconds.
String id = addScheduledJob(10000, new MyJob());
room.setAttribute("MyJobId", id);
return true;
}
}
addScheduledJob函数返回的id能够用于后来去停止执行已经被注册的事件
示例代码如下:
public void roomStop(IScope room) {
String id = (String) room.getAttribute("MyJobId");
removeScheduledJob(id);
super.roomStop(room);
}
分享到:
相关推荐
URLLoader(URLStream) FlashRemoting XMLSocket(Socket) FMS/FCS
系统的主要特点可以从下面三大方面来体现: 一、快速:快速的应用开发和优化的执行速度,更加有利于企业级应用和部署 二、兼容:兼容PHP4和PHP5版本,在PHP4下模拟了很多PHP5的优秀特性 三、简单:简洁的架构和模板...
资源来自github,用于Verilog进行网络通信时的FCS校验码的生成
FCS校验计算器
Flash大家庭里的一员,这个东东以前叫Flash Communication Server,传说中的FCS就是这个,现在改叫FMS了... 不见不知道哦,一见真可怕,adobe还有这么cool的东东,自从见了她,让我做些小东东的兴趣全没了,一心想...
字符串FCS校验码计算方法
欧姆龙plc的 hostlink 的fcs校验工具 http://blog.csdn.net/aliealie/article/details/53930703
两种方式进行异或运算 上面有详细的时间记录
欧姆龙FCS校验器 VB源代码,校验FCS值,可以算出FCS值,直接输入COM口通讯字串代码运算.
超聚变FCS-Pre-sales考试,真人验证,考试无忧。
流肛门 用于分析流式细胞术 .fcs 文件的程序 开发设置 开发/venv.sh 加载 HP 数据库元信息(示例) ... # 从存档卷制作 FCS db python flowanal.py make_FCSmeta_db '/mnt/hgfs/archive/' --ex 'archive2' 'Dupl
FCS Remover.dmg有用有帮助
从 FCS3.0 格式文件中提取数据记录并保存为 CSV 格式文件。 我已经通过使用以下内容确认了该程序的工作: 测试数据 从导出的数据 要求 Python 3.4.x 如何使用 python main.py /path/to/file_or_dir 适用于 ...
一个简单的网络帧FCS计算工具,可移植到自己的项目
输入十进制数字,能够自动转化为二进制数据并进行二进制除法运算,最后生成FCS码,输出到屏幕上。(完全原创----西安电子科技大学信息对抗)
西门子SITRANS FCS400质量流量传感器快速启动手册pdf,西门子SITRANS FCS400质量流量传感器快速启动手册
该软件是计算CRC校验和的软件,主要用vs2005进行开发,主要的应用技术是上位机界面读取输入的数字,通过计算后进行显示。
FCS系统总体介绍,幻灯片演示介绍
各FCS子系统相对独立,这并不符合矿山物联网从底层进行信息融合的理念。新桥煤矿对此进行了技术改造,按现场总线具有开放性和互操作性的性能,用FCS实现现场各个控制器和仪表设备互联,提高各子系统间的融合程度,实现了...
FCS-35000-AVATION-TIMER英文版说明书 里面详细的安装过程,完全图方便个人使用