您的位置:首页 > 其它

用red5和flex实现的一个小的聊天程序

2014-09-03 20:26 239 查看
程序的基本功能

1.用户连接、断开连接

2.显示用户登录列表

3.信息群聊

4.私聊

red5程序:ChatRoom.java

package com.red5;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import org.red5.server.adapter.ApplicationAdapter;
import org.red5.server.api.IConnection;
import org.red5.server.api.IScope;
import org.red5.server.api.Red5;
import org.red5.server.api.service.IServiceCapableConnection;
import org.red5.server.api.so.ISharedObject;

/**
* @category 一个简单的聊天程序
* @author Administrator
*
*/
public class ChatRoom extends ApplicationAdapter {
private static Logger log = Logger.getLogger(ChatRoom.class.getName());
private Map<String, IConnection> clientDic = new HashMap<String, IConnection>();

/**
* @category 客户端连接时调用
*/
@Override
public synchronized boolean connect(IConnection conn, IScope scope,
Object[] params) {
if(params.length == 0) {
rejectClient("Must pass the login name.");
}

String loginname = params[0].toString();
conn.setAttribute("UserName", loginname);

//如果用户不存在于当前的连接中,则将其加入
//如果不存在共享对象,则创建
if(clientDic.keySet().contains(loginname)) {
rejectClient("The same user has logged in already");
} else {
clientDic.put(loginname, conn);
ISharedObject so = getSharedObject(scope, "UserSO");
if(so == null) {
createSharedObject(scope, "UserSO", true);
so = getSharedObject(scope, "UserSO");
}
so.setAttribute("userlist", clientDic.keySet().toArray());
}

return super.connect(conn, scope, params);
}

/**
* @category 客户端失去连接时调用
*/
@Override
public synchronized void disconnect(IConnection conn, IScope scope) {
String loginname = conn.getAttribute("UserName").toString();
if(loginname != null) {
if(clientDic.keySet().contains(loginname)) {
clientDic.remove(loginname);
ISharedObject so = getSharedObject(scope, "UserSO");
if(so != null) {
so.setAttribute("userlist", clientDic.keySet().toArray());
}
}
}
super.disconnect(conn, scope);
}

/**
* @category 发送全局消息,所有上线的人都能够看到
* @param params
*/
public void sendMessage(List<String> params) {
IConnection conn = Red5.getConnectionLocal();
IScope scope = conn.getScope();
ISharedObject so = getSharedObject(scope, "UserSO");
log.info("Server: call sendMessage and params " + params.get(0));
so.sendMessage("receiveMsg", params);
}

/**
* @category 发送私聊信息,只有被选中的人能够看到信息
* @param params
*/
public void sendPrvMessage(List<String> params) {
if(params.size() == 3) {
String sender = params.get(0);
String content = params.get(1);
String receiver = params.get(2);

if(clientDic.keySet().contains(receiver)) {
IConnection conn = clientDic.get(receiver);
if(conn instanceof IServiceCapableConnection) {
IServiceCapableConnection sc = (IServiceCapableConnection) conn;

log.info("Server: call sendPrvMessage and sender->" + sender
+ " content->" + content + " receiver->" + receiver);

sc.invoke("receivePrvMsg", new Object[]{sender,content});
}
}
}
}

public Boolean appStart() {
return true;
}

public void appStop() {

}
}


相关配置文件:
1.red5-web.properties

webapp.contextPath=/chatRoom
webapp.virtualHosts=localhost, 127.0.0.1


2.red5-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>

<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/red5-web.properties" />
</bean>

<bean id="web.context" class="org.red5.server.Context"
autowire="byType" />

<bean id="web.scope" class="org.red5.server.WebScope"
init-method="register">
<property name="server" ref="red5.server" />
<property name="parent" ref="global.scope" />
<property name="context" ref="web.context" />
<property name="handler" ref="web.handler" />
<property name="contextPath" value="${webapp.contextPath}" />
<property name="virtualHosts" value="${webapp.virtualHosts}" />
</bean>

<bean id="web.handler"
class="com.red5.ChatRoom"
singleton="true" />

<!-- this will support calling methods through "myhandler.<methodName>" -->
<!-- <bean id="myhandler.service"
class="the.path.to.my.ServiceHandler"
singleton="true" /> -->

</beans>

3.web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">

<display-name>firstapp</display-name>

<context-param>
<param-name>globalScope</param-name>
<param-value>default</param-value>
</context-param>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/red5-*.xml</param-value>
</context-param>

<context-param>
<param-name>locatorFactorySelector</param-name>
<param-value>red5.xml</param-value>
</context-param>

<context-param>
<param-name>parentContextKey</param-name>
<param-value>default.context</param-value>
</context-param>

<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>

<context-param>
<param-name>webAppRootKey</param-name>
<param-value>/chatRoom</param-value>
</context-param>

<security-constraint>
<web-resource-collection>
<web-resource-name>Forbidden</web-resource-name>
<url-pattern>/streams/*</url-pattern>
</web-resource-collection>
<auth-constraint/>
</security-constraint>

</web-app>

flex程序:chatRoom.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.charts.chartClasses.StackedSeries;
import mx.formatters.SwitchSymbolFormatter;
import mx.controls.Alert;

private var conn:NetConnection;
private var so:SharedObject;
private var rtmpURL:String = "rtmp://localhost/chatRoom";

private function connHandler(evnet:Event):void {
var loginname:String = loginName.text;
if(loginname == "") {
Alert.show("login name is null");
return;
} else {
if(conn == null) {
initNetConnection(loginname);
}
}
}

/**
* 初始化连接
*/
private function initNetConnection(loginname:String):void {
conn = new NetConnection();
conn.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
conn.connect(rtmpURL, loginname);
}

private function netStatus(event:NetStatusEvent):void {
if("NetConnection.Connect.Success" == event.info.code) {
sendBtn.enabled = true;
so = SharedObject.getRemote("UserSO", conn.uri, true);
so.addEventListener(SyncEvent.SYNC, onSync);
so.client = this;	//设置群聊时接收到消息的窗体
conn.client = this;	//设置私聊时接收到消息的窗体
so.connect(conn);
}
}

private function onSync(event:SyncEvent):void {
for(var i:Object in event.changeList) {
var changeObj:Object = event.changeList[i];
switch(changeObj.code) {
case "success":
break;
case "change":
userList.dataProvider = so.data.userlist;
break;
}
}
}

/**
* 失去连接
*/
private function disconnhandler(event:Event):void {
if(conn != null && conn.connected) {
conn.close();
var nularr:Array = new Array();
userList.dataProvider = nularr;
}
}

/**
* 发送消息
*/
private function sendHandler(event:Event):void {
if(conn != null && conn.connected) {
if(IsPrivate.selected) {
if(userList.selectedIndex == -1) {
Alert.show("must choose a user first");
} else {
var pusername:String = userList.selectedItem.toString();
if(pusername == loginName.text) {
Alert.show("can't say privately to self");
} else {
//调用服务器端的私聊函数
conn.call("sendPrvMessage", null, loginName.text, loginName.text + " says privately: "
+ chatWord.text, pusername);
chatWord.text = "";
}
}
} else {
if(chatWord.text != "") {
//调用服务器端的群聊函数
conn.call("sendMessage", null, loginName.text + " says: " + chatWord.text);
chatWord.text = "";
}
}
}
}

/**
* 接收私聊信息并显示
*/
public function receivePrvMsg(sender:String, msg:String):void {
chatArea.text += msg + "\n";
}

/**
* 接收群聊信息并显示
*/
public function receiveMsg(msg:String):void {
chatArea.text += msg + "\n";
}
]]>
</mx:Script>

<mx:Panel width="585" height="480" layout="absolute" title="ChatRoom" horizontalCenter="0" verticalCenter="0">
<mx:Label x="46" y="26" text="Login Name:"/>
<mx:TextInput x="125" y="24" id="loginName"/>
<mx:Button x="314" y="24" label="Connect" id="connBtn" click="connHandler(event)"/>
<mx:Button x="406" y="24" label="DisConnect" id="disconnBtn" click="disconnhandler(event)"/>
<mx:TextArea x="241" y="73" width="255" height="248" id="chatArea"/>
<mx:Label text="Chat:" horizontalCenter="-140" verticalCenter="175"/>
<mx:TextInput x="169" y="384" width="249" id="chatWord"/>
<mx:Button x="426" y="384" label="send" id="sendBtn" width="68" enabled="false" click="sendHandler(event)"/>
<mx:CheckBox x="68" y="340" label="Private Chat" id="IsPrivate"/>
<mx:TileList x="46" y="73" width="164" height="248" id="userList" columnCount="1" direction="vertical"></mx:TileList>
</mx:Panel>

</mx:Application>

效果图:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: