fms里c/s的一个例子

idPool = ["guest_1", "guest_2", "guest_3", "guest_4"];//数组,当堆栈用.全局的

application.onAppStart = function(){
   users_so = SharedObject.get("users");//获取本地共享对象users.注意,这是在服务端.不需要远程,而是本地
}

application.onConnect = function(client, name){//client为带协议的地址串的连接表示,name为输入的参数
   if (idPool.length <= 0){//如果对象池满
      application.rejectConnection(client, {msg:"Too many users."});//拒绝连接请求,给出信息,指明原因
   }
   client.id = idPool.pop();//从堆栈顶部弹出一个.并且给client多安个id属性。现在client有id属性了,后面可以使用了
   application.acceptConnection(client);//接受连接请求
   client.call("setID", null, client.id);//调用client的setID,给client发消息,将id传过去,null说明没有指定返回信息处理器
   users_so.setProperty(client.id, name); //将id:name值对保存到共享对象里。注意,这是服务器端
}

application.onDisconnect = function(client){
   idPool.push(client.id);//将要回收的id压回堆栈
   users_so.setProperty(client.id, null); //在共享对象里,将与id对应的值对设置为空,即删除。
}

myID = ""; //每个客户端都有一个id,表示自己,独一无二
nc = new NetConnection(); //连接对象。全局使用

/**
 * setID is a remote method that will be called by the server
 * after the client connects. Once we get our unique ID from the
 * server we can use it to publish our stream.
 */
nc.setID = function(id){ //setID方法,绑到连接上.如此,服务端就可以用client调用,给客户端发送消息了.这里,发送了id信息
    myID = id; //事实上,"我"的id是服务器分配的.
    statusInput.text = "Online. Your client's ID is: " + myID;//在状态栏显示在线信息及id
    ns = new NetStream(nc);//建立流
    ns.attachAudio(Microphone.get());//将流管道接到麦克音频源上
    var cam = Camera.get();//打开摄像头
    ns.attachVideo(cam);//将同一管道流接到摄像头上.这样,音频视频都接到同一管道上了.也可以使用上面接麦克的写法,一个
        //语句即可.因为下面还要用到,所以把引用拿出来了.
    ns.publish(id);//发布id信息
    _root[id].video.attachVideo(cam);//将摄像头同时连到自己的视频播放窗口.就能自拍了.同时有4个剪辑对象(被拖到)在舞台
        //上,形成数组.每个剪辑里有嵌入式视频与文本输入框.现在要访问剪辑里的视频对象,使用这种方式.video是剪辑里视频对象
    init();//开始初始化工作
}//这个方法在客户端执行,因此可以使用客户端的资源,如麦克和摄像头等.它被服务端调用,因此又可得到(传递)消息.

/**
 * onStatus is called whenever the status of the network
 * connection changes. It is how we know if we are connected
 * or not.
 */
nc.onStatus = function(info){//状态事件处理器.一旦网络连接状态改变,就调用它.诸如连接成功,失败等.info是服务器返回的
   connectButton.label = "Connect";
   connectButton.enabled = true;
   switch(info.code){
       case "NetConnection.Connect.Success":// 成功状态
          connectButton.label = "Disconnect";//标签改为"断开"
          statusInput.text = "Online";//标识"在线"
         
       break;
       case "NetConnection.Connect.Failed": //失败状态
          statusInput.text = "Cannot reach server. Possible network error.";
       break;
       case "NetConnection.Connect.Rejected"://连接拒绝
           statusInput.text = info.application.msg;//显示原因
       break;
       case "NetConnection.Connect.Closed"://连接关闭
           statusInput.text += " Connection closed.";
       break;
   }
}

connectButton.addEventListener("click", this);//给按钮注册事件监听器.this代表谁?
/**
 * click() is called when the connectButton is pressed.
 * Depending on the label of the button either a
 * connection is attempted or the current connection is
 * closed.
 */
function click(ev){//点击事件处理器.传入事件对象
    var button = ev.target;//取事件源
    var command = button.label;//取按钮的文字标签
    switch(command){
        case "Connect"://连接命令
           nc.connect("rtmp:/helloVideo", userNameInput.text);//连接,到服务端应用,传递用户名
           button.label = "Wait...";
           button.enabled = false;//按钮不可用
        break;
        case "Disconnect"://断开
           nc.close();//关闭连接
           button.label = "Connect";
        break;
    }
}

/**
 * init() is called after the server calls the setID method
 * It initializes the shared users object and then connects it.
 */
function init(){//服务端调用setID后,执行本初始化函数
    users_so = SharedObject.getRemote("users", nc.uri);//获取远程共享对象,到uri,连接到users上
    users_so.onSync = function(infoList){//共享对象同步事件处理器.共享对象里发生任何状态变化,都执行.信息列表里有具体信息
        for (var i in infoList){//逐条检测信息列表
            var info = infoList[i];//一条信息
            switch(info.code){//检测信息码
                case "change": //数据改变
                   var id = info.name;//取出名字,为id.name是信息的一个属性吗?规范在哪里?
                   var mc = _root[id];//找对应的剪辑对象
                   mc.nameInput.text = users_so.data[id];//还记得存入共享对象里的值对吗?现在按名字把值取出来.剪辑将它显示出来
                   if (myID != id){//判断数据变化的id与播放窗口是不是同一个。
                       var ns = new NetStream(nc);//建立管道流
                       mc.video.attachVideo(ns);//连到剪辑的播放窗口里
                       ns.play(id);//播放流, guest_1,
                       mc.ns = ns;//mc有ns属性吗?这里是新加的,还是已有的?在什么时候用到?还是已经用到了?
                   }//事实上,有4个窗口对象,只有一个是自己的,其余3个id都不一样.这样,就给3个窗口分别连到自己的流了.关键是
                        //每个窗口播放自己的流. 当然了,前提是数据流要变化.数据不变化,就不需要播放,因为没数据嘛
                break;
                case "delete"://有人离开了,就删除之
                   var id = info.name; //这个人离开了
                   var mc = _root[id];//取它的剪辑
                   mc.ns.close();//将剪辑里的流关闭.上面新加的属性,这里用上了
                   mc.nameInput.text = "";
                   mc.video.clear();//视频窗口处理
                break;
            }
        }//上面,info只有两个属性出现过:info.code和info.name.进一步查资料
    }
    users_so.connect(nc);    //共享对象连接. 注意:1)连接放在同步处理后面;2)有连接,就有状态变化,这都是服务端调用的
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值