上一篇《FluorineFx + Flex视频聊天室案例开发----服务器端》详细的介绍了如何利用FluorineFx开发一个及时通信的视频聊天室服务器处理程序,并通过Web网站来宿主这个服务处理程序的运行。本篇将着重介绍视频聊天室的客户端开发,包括连接RTMP服务器、发布视频、接收视频、在线用户列表、发送文本消息以及全服务器小喇叭功能点。

上述这些功能点在我以前写的文章里已经出现了N多次了,所以这里我不想过多的在次对他们进行解说,详细请查阅《Flex与.NET互操作系列文章 》,这里我将核心的几个方法代码贴出来简单说明。首先就是客户实现用户登录,通过FluorineFx提供的RemotingService的接口方法进行数据验证。

private function onLogin(event:MouseEvent):void
{
    remoteConn = new RemotingConnection("http://localhost:2020/ChatRoom.FluorineFxWeb/Gateway.aspx",ObjectEncoding.AMF3);
    myInfo = new UserInfo();
    myInfo.UserName=this.txtUserName.text;
    myInfo.Password=this.txtPassword.text;
    remoteConn.RemotingCall("ChatRoom.Services.DataService.Login",onLoginResult,onLoginFault,myInfo);
}

private function onLoginResult(result:UserInfo):void
{
    if(result != null)
    {
        this.myInfo = result;
        this.viewStack.selectedChild = chatView;
        rtmpnc = new RtmpConnection("rtmp://localhost:2777/VideoChat",ObjectEncoding.AMF3,onNetStatusHandler,myInfo);
    }
    else
    {
        this.lbState.text = "登陆失败,用户名或密码错误!";
    }
}

private function onLoginFault(event:Object):void
{
    this.lbState.text = "登陆失败,请重试!";
}

private function onClear(event:MouseEvent):void
{
    this.txtUserName.text="";
    this.txtPassword.text="";
    this.lbState.text="";
    this.txtUserName.setFocus();
}

RemotingConnection和RtmpConnection是我自己扩展的NetConnection类,功能和NetConnection一样,不同的是封装后的使用相对来说比较方便点。首先通过RemotingService的接口进行用户名和密码验证,通过了则创建一个到RTMP服务器的连接RtmpConnection(等同于NetConnection)。

private function onNetStatusHandler(event:NetStatusEvent):void
{
    trace(event.info.code);
    switch(event.info.code)
    {
        case "NetConnection.Connect.Success":onConnSuccess();break;
        case "NetConnection.Connect.Failed":onConnError();break;
    }
}

private function onConnSuccess():void
{
    //将自己的视频数据发布到RTMP服务器,这里使用的是FluorineFx
    var mic:Microphone = Microphone.getMicrophone();
    var publishNs:NetStream = new NetStream(rtmpnc);
    publishNs.attachCamera(cam);
    publishNs.attachAudio(mic);
    publishNs.client = this;
    publishNs.publish(myInfo.ID.toString()); //将用户ID作为流名进行发布实况流
    
    userSO = SharedObject.getRemote("OnLineUsers",rtmpnc.uri,false);
    userSO.addEventListener(SyncEvent.SYNC,onSyncHandler);
    userSO.client = this;
    userSO.connect(rtmpnc);
    
    timer = new Timer(1000);
    timer.addEventListener(TimerEvent.TIMER,onTimerHandler);
    timer.start();
}

private function onConnError():void
{
    trace("login error");
    writeMessage("<font color=\"#FF0000\">系统提示:连接视频服务器失败</font>");
}

创建连接的同时指定了由那一个方法(onNetStatusHandler)来处理连接状态,通过判断连接状态如果连接成功则将自己的视频数据发布到RTMP服务器(特别提醒:在发布流的时候是使用的用户ID作为流名,在建立视频聊天的时候需要根据这个ID才能查看到视频),同时还连接到服务器上的远程共享对象(作用:通过异步事件处理函数实现在线用户列表),最后建立了一个Timer是不断的调用服务器方法获取当前系统时间(注意:实际开发中不建议这样做);如果连接服务器失败则在聊天消息显示区输入一条提示信息。

在线用户列表使用共享对象来实现,可以及时的处理用户上线下线功能和实现客户端数据同步更新等。下面是共享对象的异步事件处理函数:

private function onSyncHandler(event:SyncEvent):void
{
    var array:Array = event.target.data.UserInfo as Array;
    if(array != null)
    {
        userArray.removeAll();
        for(var i:Number=0; i<array.length; i++)
        {
            var info:UserInfo = array[i] as UserInfo;
            userArray.addItem(info);
        }
        trace("userArray length:" + userArray.length);
    }
}

从异步事件中取出当前最新的数据,然后添加到用户界面的显示列表数组(userArray)里,Flex直接使用List组件显示在线用户列表,通过绑定userArray设置数据源,当userArray改变后List组件的显示也会同步更新显示。

那么怎么去建立视频聊天查看到对方的视频呢?其实实现也很简单,这里还是要从用户列表出发,通过点击用户列表上的在线用户,然后建立与该用户的视频连接。同时判断是否选择的是怎么,本案例中我没有将自己从在线列表里屏蔽而是通过判断当前选择的是否为自己,如果是自己则不进行视频连接,也不能发送文本聊天信息。

private function onUserItemHandler(event:Event):void
{
    info = List(event.target).selectedItem as UserInfo;  //把当前选择的用户信息通过变量保存下来
    this.lbNickName.text = info.NickName;
    
    if(info.UserName == myInfo.UserName)
    {
        writeMessage("<font color=\"#FF0000\">系统提示:不能和自己进行视频聊天</font>");
    }
    else
    {
        //建立视频流的连接
        if(this.ns)
        {
            this.ns.close();
        }
        this.ns = new NetStream(this.rtmpnc);
        ns.client = this;
        sound = this.ns.soundTransform;
        var v1:Video = new Video();
        v1.width = 320;
        v1.height = 240;
        v1.attachNetStream(ns);
        this.videoDisplay.addChild(v1);
        ns.play(info.ID.toString());  //当前选择的用户的ID
    }
}

OK,到这里就成功的完成了用户登录,建立与RTMP服务器的连接,发布视频流,接收指定的视频流等功能,接下来就是实现文字聊天的功能了。实现文字聊天功能是最简单的,我曾经先后在《FMS3系列(六):使用远程共享对象(SharedObject)实现多人时时在线聊天(Flex | Flash) 》和《Flex与.NET互操作(十二):FluorineFx.Net的及时通信应用(Remote Shared Objects)(三) 》这两篇文章中都介绍到了,这里我使用的是第二篇文章里所介绍的方法(提示:该方法就是直接使用SharedObject的send()方法)来实现文字聊天功能。

private function onSendMessage(event:MouseEvent):void
{
    if(info!=null)
    {
        userSO.send("chatMessage", this.txtMessage.text, myInfo, info);
        this.txtMessage.text="";
    }
    else
    {
        writeMessage("系统提示:请选择聊天对象");
    }
}

public function chatMessage(message:String, sayUser:UserInfo, recUser:UserInfo):void
{
    if(recUser.UserName==this.myInfo.UserName)
    {
        message = sayUser.NickName + "对你说:"+message;
        writeMessage(message);
    }
    if(sayUser.UserName==this.myInfo.UserName)
    {
        message = "我对"+recUser.NickName + "说:"+message;
        writeMessage(message);
    }
}

private function writeMessage(message:String):void
{
    this.txtDisMessage.htmlText += message + "\n";
    this.txtDisMessage.verticalScrollPosition = this.txtDisMessage.maxVerticalScrollPosition;
}

OK,大功告成,现在是集视频和文字聊天的多人在线聊天室就实现了,不足的是只能一对一聊天。如果我要对大家说话怎么办呢?于是我在本案例中设计了一个小喇叭功能,通过发送小喇叭实现全服务器喊话。下边是下喇叭组件代码:

<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="540" height="50" 
    headerHeight="8" roundedBottomCorners="true" borderColor="#000000">
    <mx:TextInput x="2" y="3" width="400" id="txtMessage"/>
    <mx:Button x="466" y="3" label="关闭" click="onClose(event)"/>
    <mx:Button x="410" y="3" label="发送" 
        enabled="{txtMessage.text.length > 0 ? true : false}" 
        click="onSend(event)"/>
    
    <mx:Script>
        <![CDATA[
            import mx.core.Application;
            import mx.events.CloseEvent;
            import mx.managers.PopUpManager;
            private function init():void
            {
                this.txtMessage.setFocus();
            }
            
            private function onClose(event:MouseEvent):void
            {
                onCloseHandler(null);
            }
            
            private function onCloseHandler(event:CloseEvent):void
            {
                Application.application.speakFlag = false;
                PopUpManager.removePopUp(this);
            }
            
            private function onSend(event:MouseEvent):void
            {
                Application.application.userSO.send("speakMessage",txtMessage.text,Application.application.myInfo);
                this.txtMessage.text = "";
                onCloseHandler(null);
            }
        ]]>
    </mx:Script>
</mx:TitleWindow>

同样通过远程共享对象的send()方法实现发送小喇叭功能,在客户端定义一个方法(speakMessage)来接受小喇叭发送的消息内容,然后显示在用户聊天界面上。

public var speakFlag:Boolean = false;
private function onSpeaker(event:MouseEvent):void
{
    if(!speakFlag)
    {
        var dis:Speaker = new Speaker();
        dis.x = 230;
        dis.y = 505;
        PopUpManager.addPopUp(dis,this,false);
        speakFlag = true;
    }
}
public function speakMessage(message:String,info:UserInfo):void
{
    message = "【小喇叭】:" + info.NickName + "说:" + message;
    writeMessage(message); 
}

貌似这一整篇都是代码,除了代码我也不知道该怎么去介绍更容易说得清楚了,下面来看看上面的劳动成功,启动服务器后运行多个客户端来聊天测试看看。

现在还差一个重要的功能没有实现了,前面提到过画中画功能,也就是说在和在线朋友进行视频聊天的同时,需要将自己的视频以小视频窗口的方式显示在聊天窗口,实现所谓的画中画功能,显示自己的视频通过初始化方法,程序启动后就直接显示出自己的视频。

private function init():void
{
    //将自己的视频显示在画中画中
    cam = Camera.getCamera();
    if(cam != null)
    {
        this.myVD.attachCamera(cam);
    }
    else
    {
        writeMessage("未能找到视频设备,请检测是否正确安装设备!");
    }
}

本文就介绍到这里,关于聊天表情的实现这里就不作介绍了,由于时间关系本案例里也没有实现这个功能,有兴趣的朋友可以下载源代码自己去扩展实现聊天表情这个功能。这里我将实现的原理简单说一下,通过TileList组件加载表情图片或动画信息显示出来,详细可以参考《使用TileList+TitleWindow组件开发聊天表情功能 》,发送表情则是将图片地址通过SharedObject的send()方法发送出去,接收消息的方法通过图片地址,组合<img src='图片地址' />然后显示在聊天信息窗口中。

版权说明

本文属原创文章,欢迎转载,其版权归作者和博客园共有。

作      者:Beniao

文章出处:http://beniao.cnblogs.com/  或  http://www.cnblogs.com/

转载于:https://www.cnblogs.com/beniao/archive/2009/06/29/1511813.html

FluorineFx + Flex视频聊天室案例开发----客户端相关推荐

  1. Flex与.NET互操作(十六):FluorineFx + Flex视频聊天室案例开发

    本文将使用FluorineFx和Flex结合介绍一个简单的视频聊天室案例开发,希望通过此篇和大家交流FluorineFx和Flex的相关技术,同时也希望本篇可以帮助到需要使用FluorineFx做及时 ...

  2. FMS视频聊天室的开发

    FMS视频聊天室的开发 2009年06月07日 由于FLASH技术的发展, FLASH对本地P2P的支持,越来越进这就出现了FMS FLASH视频聊天室的开发. flash聊天室,fms聊天室源码 一 ...

  3. BAT蝙蝠视频聊天室(服务器+客户端+架设相关软件)免费提供

    BAT蝙蝠视频聊天室(服务器+客户端+架设相关软件) 网盘下载: http://adf.ly/5kgdg 介绍:

  4. 网络视频聊天室的开发指南

    目前网上视频聊天室.视频会议软件.可视IP电话软件随处可见,你是否想自己做一个玩玩?其实这类软件无非是视频加上网络而建成的.如果熟悉视频捕 捉和网络传输技术,根本就难不倒你.本文详细介绍了如何利用别人 ...

  5. FMS案例开发--视频聊天室(三)

    本文要介绍的内容主要有利用SharedObject来实现聊天文字聊天和在线用户的列表,以及实现语音视频聊天等. 前一篇文章介绍了实现用户注册和登录的功能,本文接着介绍用户注册并成功登录后的相关功能开发 ...

  6. 独家揭秘语音视频聊天室开发顶尖制作教程

    互联网的不断发展,各种新技术的兴起,原本做管理软件 的我也逐渐转向从事着互联网相关的运营产品的开发.尤其是目前抄得最火热的音视频互动平台技术,今天我先列出最基本开发流程,适用于开发视频会议系统.语音视 ...

  7. 即时通讯 音视频聊天室开发建议

    目前网上视频聊天室.视频会议软件.可视IP电话软件随处可见,你是否想自己做一个玩玩?其实这类软件无非是视频加上网络而建成的.如果熟悉视频捕 捉和网络传输技术,根本就难不倒你.本文详细介绍了如何利用别人 ...

  8. 网页的视频聊天室开发

    现在网上很多朋友在弄网页的视频聊天室 通过学习,我自己也做了个简单的小例子,几十行JavaScript脚本就能轻松实现视频通话:也不用去下载指定的什么浏览器,因为IE.firefox.chrome等w ...

  9. 多人私密视频直播会议聊天室系统开发

    多人视频直播会议聊天室系统开发 轻便小巧无须安装 绑定公号无须登录 界面简洁操作方便 权限管理避免白嫖 前端/ 会议设置 用户可以设置姓名 管理员可以修改会议主题和分享说明文字 多人视频 左上显示用户 ...

最新文章

  1. 【iOS10 SpeechRecognition】语音识别 现说现译的最佳实践
  2. 参加第二届中国网络营销行业大会会议记录
  3. 汇编语言--通用寄存器
  4. python获取url文件名_python httplib / urllib获取文件名
  5. 英雄传说服务器维护中,英雄传说:星之轨迹 正统《轨迹》手游无法连接服务器是什么原因...
  6. HDU-4536 XCOM Enemy Unknown 枚举
  7. 论文浅尝 - TACL2020 | TYDI QA:Google 发表一个多语言的问答语料库
  8. 终于我还是放手了, 但是只想说,暂别 Aptana Studio 3,Phpstorm来吧!(附:个人遇到的小问题的解决方法)...
  9. Python——类与对象的学习笔记
  10. 系统地介绍计算材料科学的发展现状、主要理论框架和设计实践方法,汪林望博士作序《计算材料学——设计与实践方法(第2版)》
  11. cactiEZ 使用
  12. 如何将CHM转换为PDF文件?
  13. python筛选excel符合条件的数据——python处理excel数据(四)
  14. 618投影仪怎么选?看看极米NEW Z6X、极米Z6X Pro与极米H3S
  15. [转]Web开发者和设计师必须要知道的 iOS 8 十个变化
  16. vivado里那些看不懂的原语
  17. how do java play sql_讲解:Invadem、Java、Java、game mechanicsSQL|Processing
  18. 燕山大学数据结构与算法课程实践——ISBN号识别系统的设计与开发
  19. Grub 4 DOS 简介
  20. 【转】 很美的句子,句句掉泪,不知道原创是谁,感谢

热门文章

  1. 为什么基本类型可以调用方法——以字符串为例
  2. 原理剖析-Netty之服务端启动工作原理分析(上)
  3. sai u 2016
  4. 通用扩展函数--类型转换
  5. Android Toolbar Padding
  6. Posix多线程编程—线程属性
  7. 华为2011上机笔试题2+参考程序
  8. C#二进制格式与文件相互转换
  9. 华为敏捷 DevOps 实践:产品经理如何开好敏捷回顾会议
  10. Cesium入门11 - Interactivity - 交互性