FMS案例开发--视频聊天室(二)
通过前面的简单分析,下面正式进入视频聊天室的设计开发阶段。根据我以前开发管理软件的经验,我们从基础模块开始,首先设计和开发后台功能模块,实现基本的用户注册和通信接口等相关功能。
聊天室需求简单,主要就一张表用来存储用户注册资料,当用户登陆聊天室的时候,则通过通信接口来验证用户。SQL脚本如下:
USE [ChatRoom]
GO
/****** 对象: Table [dbo].[UserInfo] 脚本日期: 05/16/2009 16:45:53 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[UserInfo](
[ID] [int] IDENTITY(1,1) NOT NULL,
[UserName] [varchar](50) NULL,
[NickName] [varchar](50) NOT NULL,
[Password] [varchar](50) NOT NULL,
[QQ] [varchar](20) NULL,
[RegTime] [datetime] NULL,
CONSTRAINT [PK_UserInfo] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
GO
/****** 对象: Table [dbo].[UserInfo] 脚本日期: 05/16/2009 16:45:53 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[UserInfo](
[ID] [int] IDENTITY(1,1) NOT NULL,
[UserName] [varchar](50) NULL,
[NickName] [varchar](50) NOT NULL,
[Password] [varchar](50) NOT NULL,
[QQ] [varchar](20) NULL,
[RegTime] [datetime] NULL,
CONSTRAINT [PK_UserInfo] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
本案例开发的通信接口采用WebService提供,考虑到只是做一些基本的通信加上本文重在于演示,所以就不去使用使用诸如FluorineFx之类的通信网关了。如有对FluorineFx感兴趣的朋友可以浏览以下文章:《Flex与.NET互操作系列文章》
数据访问通过Linq To Sql实现,对外提供WebService接口,Flex通过WebService和.NET通信达到数据交互的目的。
namespace ChatRoomService
{
/// <summary>
/// CRService 的摘要说明
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
// [System.Web.Script.Services.ScriptService]
public class CRService : System.Web.Services.WebService
{
private static ChatRoomDataContext ctx = new ChatRoomDataContext();
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
/// <summary>
/// 用户登录
/// </summary>
/// <param name="UserName"></param>
/// <param name="Password"></param>
/// <returns></returns>
[WebMethod]
public UserInfo Login(string UserName, string Password)
{
List<UserInfo> list= ctx.UserInfo.Where(u => u.UserName == UserName).Where(p => p.Password == Password).ToList();
if (list.Count>0)
return list[0];
return null;
}
/// <summary>
/// 用户注册
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
[WebMethod]
public string Register(string infos)
{
string[] info = infos.Split('|');
UserInfo userInfo = new UserInfo
{
UserName = info[0],
Password = info[1],
NickName = info[2],
QQ = info[3],
RegTime = DateTime.Now
};
List<UserInfo> list = ctx.UserInfo.Where(n => n.UserName == userInfo.UserName).ToList();
if (list.Count > 0)
return string.Format("{0}|{1}", "Error", "用户" + userInfo.UserName + "已经存在");
try
{
ctx.UserInfo.InsertOnSubmit(userInfo);
ctx.SubmitChanges();
return "Success";
}
catch
{
return "Error";
}
}
}
}
{
/// <summary>
/// CRService 的摘要说明
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
// [System.Web.Script.Services.ScriptService]
public class CRService : System.Web.Services.WebService
{
private static ChatRoomDataContext ctx = new ChatRoomDataContext();
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
/// <summary>
/// 用户登录
/// </summary>
/// <param name="UserName"></param>
/// <param name="Password"></param>
/// <returns></returns>
[WebMethod]
public UserInfo Login(string UserName, string Password)
{
List<UserInfo> list= ctx.UserInfo.Where(u => u.UserName == UserName).Where(p => p.Password == Password).ToList();
if (list.Count>0)
return list[0];
return null;
}
/// <summary>
/// 用户注册
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
[WebMethod]
public string Register(string infos)
{
string[] info = infos.Split('|');
UserInfo userInfo = new UserInfo
{
UserName = info[0],
Password = info[1],
NickName = info[2],
QQ = info[3],
RegTime = DateTime.Now
};
List<UserInfo> list = ctx.UserInfo.Where(n => n.UserName == userInfo.UserName).ToList();
if (list.Count > 0)
return string.Format("{0}|{1}", "Error", "用户" + userInfo.UserName + "已经存在");
try
{
ctx.UserInfo.InsertOnSubmit(userInfo);
ctx.SubmitChanges();
return "Success";
}
catch
{
return "Error";
}
}
}
}
由于是直接使用WebService通信,ActionScript对象和C#对象之间的序列化问题,上面就直接以字符传的形式返回。有了通信接口,下面就可以做用户注册和登录的工作了。在Flex客户端全部通过<mx:WebService>组件和WebService通信,注册的完整代码如下:
Flex注册界面完整代码
用户登录同样是使用WebService通信进行数据库验证,实现代码大致如下:
<mx:WebService id="ctService" wsdl="http://localhost:1535/CRService.asmx?wsdl">
<mx:operation name="Login" result="onLoginRusult(event)" fault="onLoginFaile(event)">
</mx:operation>
</mx:WebService>
private function onLogin():void
{
this.ctService.Login(this.txtUserName.text,this.txtPassword.text);
}
private function onLoginRusult(evt:ResultEvent):void
{
if(evt.result != null)
{
//显示自己的视频
//displayCameraSelf();
//连接FMS服务器发布自己的视频流
publishNc = new NetConnection();
publishNc.connect("rtmp://localhost/ChatRoom");
so = SharedObject.getRemote("ChatSO",publishNc.uri,false);
publishNc.addEventListener(NetStatusEvent.NET_STATUS,onNetStatusHandler);
so.addEventListener(SyncEvent.SYNC,onSyncHandler);
so.connect(publishNc);
myUserName = evt.result.UserName;
myNickName = evt.result.NickName;
this.loginPanel.visible = false;
this.chatRoomPanel.visible=true;
ChatRoomViewStack.selectedChild = chatRoomPanel;
}
else
{
Alert.okLabel="确 定";
Alert.show("登录失败!","系统提示");
}
}
<mx:operation name="Login" result="onLoginRusult(event)" fault="onLoginFaile(event)">
</mx:operation>
</mx:WebService>
private function onLogin():void
{
this.ctService.Login(this.txtUserName.text,this.txtPassword.text);
}
private function onLoginRusult(evt:ResultEvent):void
{
if(evt.result != null)
{
//显示自己的视频
//displayCameraSelf();
//连接FMS服务器发布自己的视频流
publishNc = new NetConnection();
publishNc.connect("rtmp://localhost/ChatRoom");
so = SharedObject.getRemote("ChatSO",publishNc.uri,false);
publishNc.addEventListener(NetStatusEvent.NET_STATUS,onNetStatusHandler);
so.addEventListener(SyncEvent.SYNC,onSyncHandler);
so.connect(publishNc);
myUserName = evt.result.UserName;
myNickName = evt.result.NickName;
this.loginPanel.visible = false;
this.chatRoomPanel.visible=true;
ChatRoomViewStack.selectedChild = chatRoomPanel;
}
else
{
Alert.okLabel="确 定";
Alert.show("登录失败!","系统提示");
}
}
通信主要就这两个功能点,都比较简单,关于Flex与WebServie通信我以前也写过两篇文章在《Flex与.NET互操作系列文章》里,不熟悉的的朋友可以先看看通信方面的实现。
本文就先介绍到这里,下一篇将介绍聊天室的详细开发,包括视频、语音、文字聊天的实现等相关知识点。