加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

基于stratus +flex+MySQL的简易在线随机视频聊天室的开发

发布时间:2020-12-15 04:32:47 所属栏目:百科 来源:网络整理
导读:前段时间听说flashplayer已经开始支持p2p了,对这块非常感兴趣于是开始玩flex,一玩下来不可自拔。用Stratus搭建p2p环境如此简单,双方只需要能连上Stratus服务器就能直接进行语音视频的聊天,不需要任何客户端。Adobe还真是NB,呵呵出了这么XX的东东,前途无

前段时间听说flashplayer已经开始支持p2p了,对这块非常感兴趣于是开始玩flex,一玩下来不可自拔。用Stratus搭建p2p环境如此简单,双方只需要能连上Stratus服务器就能直接进行语音视频的聊天,不需要任何客户端。Adobe还真是NB,呵呵出了这么XX的东东,前途无可限量啊。

闲话少说,这几天小搞了下,用Mysql和flex弄了个简易随机视频聊天室,和有共同爱好的各位一起分享下。高手可以直接飞过哈,欢迎提出意见,毕竟刚玩没多久,问题很多。

准备工作:

1.我用的是Flash Builder 4开发的,默认用的是Flex SDK4.0

2.开发最好用flash payer 10 debug version(可以进行调试)

3.申请一个 Stratus develper key:8b0f114ef5a20c433d5c2a33-201aeea5601b(用这个也行-_-我申请的)或者在这申请

下面正式开始,程序主体主要分为3大块:

一、p2p语音视频功能模块

这个模块网上有很多教程了,Adobe官方的那个Sample就很好。我就是以此为基础进行开发的。可能有些朋友还不是很了解,为了每个人都能搞清楚,下面针对代码详细地进行下介绍。

由于是p2p模式,每个用户既是呼叫者又是被呼叫者。更具体点,举个例子有两个人A和B打电话。A呼叫B,此时A是呼叫者,B是被呼叫者。反之B是呼叫者,A是被呼叫者。因此在每个p2p模块中必须要有呼叫者和被呼叫者两个部分。

首先要连接上stratus服务器:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private var netConnection:NetConnection;
//监听信息流
private var listenStream:NetStream;???
//播放上面的监听流
private var controlStream:NetStream;?
//对外发布信息流
private var outgoingStream:NetStream;
//接受外部发送的信息流
private var incomingStream:NetStream;
//Adobe stratus 服务器地址
private const SERVER: String = "rtmfp://stratus.adobe.com/" ;
//Developer Key,要自己申请
private const DEVKEY: String = "8b0f114ef5a20c433d5c2a33-201aeea5601b" ;
//创建一个nectConnetion与stratus 服务器进行连接
netConnection= new NetConnection();
netConnection.addEventListener(NetStatusEvent.NET_STATUS,statusHandler);
//连接Adobe stratus 服务器
netConnection.connect(SERVER+DEVKEY);

被呼叫部分:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
????????? //被呼叫者发布监听流,以便呼叫者连接
???????????????? listenStream = new NetStream(netConnection,NetStream.DIRECT_CONNECTIONS);
????? listenStream.addEventListener(NetStatusEvent.NET_STATUS,statusHandler);??
????? listenStream.publish(username);??
//呼叫者一旦订阅上面的监听流,就会触发onPeerConnect事件
????? var c: Object = new Object ();
????? c.onPeerConnect = function (caller:NetStream): Boolean
????? {
??????? if (callState == CallReady)?
??????? {
????????????????? //接受呼叫者发布的视频语音流
??????????? callState = CallRinging;
??????????? idManager.change(callState);
??????????? busyState = busyOn;
??????????? incomingStream = new NetStream(netConnection,caller.farID);
??????????? incomingStream.addEventListener(NetStatusEvent.NET_STATUS,statusHandler);
??????????? video = new Video();
??????????? video.attachNetStream(incomingStream);
??????????? remoteVideoDisplay.addChild(video);
??????????? incomingStream.play( "caller" );
???????????
??????????? var st:SoundTransform = new SoundTransform(speakerVolumeSlider.value);
??????????? incomingStream.soundTransform = st;
//处理呼叫的方法
??????????? var i: Object = new Object ();
??????????? i.onIncomingCall = function (caller: String ): void
??????????? {
??????????????? if (callState != CallRinging)
??????????????? {
??????????????????? txtInfo.text += "onIncomingCall: Wrong call state: " + callState + "n" ;
??????????????????? return ;
??????????????? }
??????????????? send_bn.enabled= true ;
??????????????? txtInfo.text +=? caller + "已经成功与您连接上n" ;
??????????????? partnername = caller;
???????????????
??????????????? //outgoingStream.send("onCallAccepted",username);
??????????????? callState = CallEstablished;
??????????????? //idManager.change(callState);
??????????? }??
???????????? i.onIm = function (caller: String ,text: String ): void
???????????? {
???????????????? txtMessage.text += caller+ ": " +text+ "n" ;
???????????? }
???????????? i.onDisconnected = function (caller: String ): void
???????????? {
???????????????? txtInfo.text += caller+ "和你断开连接n" ;
???????????????? send_bn.enabled= false ;
???????????????? stop();
???????????? }??
??????????? incomingStream.client = i;
//对呼叫者发布自己的语音视频流???
??????????? outgoingStream = new NetStream(netConnection,NetStream.DIRECT_CONNECTIONS);
??????????? outgoingStream.addEventListener(NetStatusEvent.NET_STATUS,callee_outgoingStreamHandler);
??????????? outgoingStream.attachCamera(camera);
??????????? outgoingStream.attachAudio(mic);
??????????? outgoingStream.publish( "callee" );
???????????
??????????? return true ;
?????????? }
??????? txtInfo.text += "onPeerConnect: all rejected due to state: " + callState + "n" ;
???????
??????? return false ;
????? }?
??????? listenStream.client = c;
???????
???????
??????? callState = CallReady;?????

呼叫部分:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
????????????????????????? callState = CallCalling;
idManager.change(callState);
busyState = busyOn;
?????????????????????????? //播放被呼叫者的监听流
controlStream = new NetStream(netConnection,farPeerID);
controlStream.addEventListener(NetStatusEvent.NET_STATUS,statusHandler);
controlStream.play(partnername);
//对被呼叫者发布自己的视频语音流
outgoingStream = new NetStream(netConnection,NetStream.DIRECT_CONNECTIONS);
outgoingStream.addEventListener(NetStatusEvent.NET_STATUS,caller_outgoingStreamHandler);
outgoingStream.attachCamera(camera);
outgoingStream.attachAudio(mic);
outgoingStream.publish( "caller" );
txtInfo.text += "正在与" +partnername+ "建立连接n" ;
?????????????????????????? //播放被呼叫者的视频语音流
??? incomingStream = new NetStream(netConnection,farPeerID);
??? incomingStream.addEventListener(NetStatusEvent.NET_STATUS,statusHandler);
??? video = new Video();
??? video.attachNetStream(incomingStream);
??? remoteVideoDisplay.addChild(video);
??? incomingStream.play( "callee" );
???
??? var st:SoundTransform = new SoundTransform(speakerVolumeSlider.value);
??? incomingStream.soundTransform = st;
?????? //处理呼叫的方法
??? var i: Object = new Object ();
??? i.onIm = function (callee: String ,text: String ): void
??? {
??????? txtMessage.text += callee+ ": " +text+ "n" ;
??? }
??? i.onCallAccepted = function (callee: String ): void
??? {
??????? if (callState != CallCalling)
??????? {
??????????? txtInfo.text += "连接失败" ;
??????????? return ;
??????? }
??????? send_bn.enabled= true ;
??????? txtInfo.text += callee+ "已经成功与您连接上n" ;
??????? callState = CallEstablished;
??????? //idManager.change(callState);
??? }
??? i.onDisconnected = function (callee: String ): void
??? {
??????? txtInfo.text += callee+ "和你断开连接n" ;
??????? send_bn.enabled= false ;
??????? stop();
??? }
??? incomingStream.client = i;

二、用户数据库及webservice接口

?? 这个项目我使用MySQL进行用户数据库设计,用户端产生相应行为后(如登录,下线,聊天,空闲等)会在数据库中更新自己的状态,其他用户根据查询得到的结果进行操作。数据库结构见下图:

???????????????????????????????????????????????????????????????? 用户名?????????? peerID??????? 更新时间????????????? 在线状态??? 聊天状态

?? 该项目只要进行简单的数据库操作就可以了,所以我使用了HTTPService组件和一个简单的php网页进行与数据库的交互。

?? HTTPService组件位于mx.rpc.http包下,当调用 HTTPService 对象的 send() 方法时,将发出对指定 URL 的 HTTP 请求,并且返回 HTTP 响应。可以选择向指定 URL 传递参数。项目中通过HTTPService组件传递用户端的参数到php网页,由php根据相应的参数操作数据库,返回相应的结果交由用户端执行。

?? HTTPService组件部分:

?
1
2
mHttpService = new HTTPService();
?? mHttpService.url = mWebServiceUrl;
?
1
2
3
4
5
6
7
8
9
10
11
12
13
??????? //添加对结果事件的侦听
??????? mHttpService.addEventListener( "result" ,httpResult);
??????? mHttpService.addEventListener( "fault" ,httpFault);
???????? //实例化request请求对象并发送?
??????? var request: Object = new Object ();
var now: Date = new Date ();
request.time = now.getTime();
??????? request.username = user;
??????? request.identity = id;
??????? request.online = x;
??????? request.busy = x;
??????? mHttpService.cancel();
??????? mHttpService.send(request);

? php网页部分:???

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
$output = "<?xml version="1.0" encoding="utf-8"?>" ;
$output .= "<result>" ;
if ( isset($_GET[ "username" ]) || isset($_GET[ "friends" ]) || isset($_GET[ "fetch" ]))
{
??? define( "DATABASE_SERVER" , "localhost" );
??? define( "DATABASE_USERNAME" , "root" );
??? define( "DATABASE_PASSWORD" , "root" );
??? define( "DATABASE_NAME" , "root" );
??? $mysql = mysql_connect( DATABASE_SERVER,
???????????????????? DATABASE_USERNAME,
???????????????????? DATABASE_PASSWORD )
??????????? or die( mysql_error() );
??? mysql_select_db( DATABASE_NAME );??
}
//注册更新部分
if ( isset($_GET[ "username" ]) )
{
???
??? $user?? = mysql_real_escape_string( $_GET[ "username" ] );
??? $identity?? = mysql_real_escape_string( $_GET[ "identity" ] );
??? $online = mysql_real_escape_string( $_GET[ "online" ] );
??? $busy = mysql_real_escape_string( $_GET[ "busy" ] );
??? $query = "SELECT * FROM registrations WHERE m_username='$user' ;" ;
??? $result = mysql_query( $query );
???
??? $isNew = ($result && mysql_num_rows($result) == 0 );
??? if ( $isNew ) {
??????? $query = "INSERT INTO registrations SET " ;
??????? $query .= "m_username='$user',m_identity='$identity',m_updatetime=now(),m_online='$online',m_busy='$busy';" ;
??? } else {
??????? $query = "UPDATE registrations SET " ;
??????? $query .= " m_identity='$identity',m_busy='$busy' where m_username='$user';" ;
??? }
???? $result = mysql_query( $query );
??? if ( $isNew )
??????? $output .= "<update>true</update>" ;
??? else
??????? $output .= "<update>false</update>" ;
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//查找用户部分
if ( isset($_GET[ "friends" ]) )
{
??? $friends??? = mysql_real_escape_string( $_GET[ "friends" ] );
??? $output .= "<friend><user>$friends</user>" ;
??? $query = "select * from registrations where m_username = '$friends' and TIMEDIFF(now(),m_updatetime) >0 ;" ;
???
??? $result = mysql_query( $query );
??? if ( $result ) {
??????? while ( $item = mysql_fetch_assoc( $result ) ) {
??????????????? $output .= "<identity>" .$item[ "m_identity" ]. "</identity>" ;
??????? }
??? }
??? $output .= "</friend>" ;
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//获取返回结果
if ( isset( $_GET[ "fetch" ]) )
{
??? $time = mysql_real_escape_string( $_GET[ "time" ] );
??? $query = "select m_number from registrations order by m_username asc ;" ;
???
??? $result =mysql_query($query);
??? if ( $result )
??? {
??? $num = mysql_num_rows($result);
??? $output .= "<fetch><num>" .$num. "</num>" ;
??? }
???
??? $query = "select m_username from registrations where m_online ='1' and m_busy = '0' order by m_username asc ;" ;
??? $result = mysql_query($query);
???
??? if ( $result )?
??? {
??????? $onlinenum = mysql_num_rows($result);
??????? $output .= "<onlinenum>" .$onlinenum. "</onlinenum><users>" ;
??????? $i = 1 ;
??????? while ($row = mysql_fetch_row($result))
??????? {
??????????? $output .= "<user" .$i. ">" .$row[ 0 ]. "</user" .$i. ">" ;
??????????? $i++;
??????? }
??????????? $output .= "</users></fetch>" ;";
??? }
}
???
$output .= "</result>" ;
header( "Content-Type: text/xml" );
echo $output;
?>

数据库返回所有用户结果如下:

代码

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读