`
zyn010101
  • 浏览: 320097 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

flex + red5实现视频会议

阅读更多

      公司最近要在系统中加视频会议的功能,让我探索,我选择了最流行的red5来实现,网上有一对一聊天的demo,找不到多对多聊天的,也没有具体介绍系统搭建的过程,我通过自己的摸索,将实现的过程和大家一起分享。java的web项目添加flex支持在此不再详述,项目文件结构如图:




 
 


 web.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app
   version="2.4"
   xmlns="http://java.sun.com/xml/ns/j2ee"
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!--
    ** For use with servlet v2.5 replace the lines above with these
    version="2.5"
    xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-->
	<display-name>Red5ChartRoom</display-name>

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

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

	<context-param>
		<param-name>webAppRootKey</param-name>
		<param-value>@webapp.root.key@</param-value>
	</context-param>

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

	<listener>
		<listener-class>org.red5.server.war.WarLoaderServlet</listener-class>
	</listener>

    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

	<servlet>
		<servlet-name>gateway</servlet-name>
		<servlet-class>org.red5.server.net.servlet.AMFGatewayServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet>
		<servlet-name>rtmpt</servlet-name>
		<servlet-class>org.red5.server.net.rtmpt.RTMPTServlet</servlet-class>
		<load-on-startup>2</load-on-startup>
	</servlet>
	
	 <!-- MessageBroker Servlet -->
 <servlet>
  <display-name>MessageBrokerServlet</display-name>
  <servlet-name>MessageBrokerServlet</servlet-name>
  <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
  <init-param>
   <param-name>services.configuration.file</param-name>
   <param-value>/WEB-INF/flex/services-config.xml</param-value>
  </init-param>
  <load-on-startup>11</load-on-startup>
 </servlet>

	<servlet-mapping>
		<servlet-name>gateway</servlet-name>
		<url-pattern>/gateway</url-pattern>
	</servlet-mapping>

    <servlet-mapping>
        <servlet-name>rtmpt</servlet-name>
        <url-pattern>/fcs/*</url-pattern>
    </servlet-mapping>

	<servlet-mapping>
		<servlet-name>rtmpt</servlet-name>
		<url-pattern>/open/*</url-pattern>
	</servlet-mapping>

	<servlet-mapping>
		<servlet-name>rtmpt</servlet-name>
		<url-pattern>/idle/*</url-pattern>
	</servlet-mapping>

	<servlet-mapping>
		<servlet-name>rtmpt</servlet-name>
		<url-pattern>/send/*</url-pattern>
	</servlet-mapping>

	<servlet-mapping>
		<servlet-name>rtmpt</servlet-name>
		<url-pattern>/close/*</url-pattern>
	</servlet-mapping>

	 <servlet-mapping>
 		 <servlet-name>MessageBrokerServlet</servlet-name>
 	 	<url-pattern>/messagebroker/*</url-pattern>
 	</servlet-mapping>
 
	<welcome-file-list>
		<welcome-file>login.html</welcome-file>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
	</welcome-file-list>

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

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

	<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>


 red5ChartRoom-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:lang="http://www.springframework.org/schema/lang"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                           http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd">
<bean id="web.context.chatroom" class="org.red5.server.Context">
	<property name="scopeResolver" ref="red5.scopeResolver"></property>
	<property name="clientRegistry" ref="global.clientRegistry"/>
	<property name="serviceInvoker" ref="global.serviceInvoker"/>
	<property name="mappingStrategy" ref="global.mappingStrategy"/>
</bean>
<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.chatroom"/>
	<property name="handler" ref="web.handler.chatroom"/>
	<property name="contextPath" value="/Red5ChatRoom"/>
	<property name="virtualHosts" value="*,localhost,localhost:8080,127.0.0.1:8080"/>
</bean>
<bean id="web.handler.chatroom" class="com.chinahrt.chat.VedioChatApplication"/>
</beans>

 

red5.properties

# Socket policy
policy.host=0.0.0.0
policy.port=843

# HTTP
http.host=0.0.0.0
http.port=5080
https.port=8443

# RTMP
rtmp.host=0.0.0.0
rtmp.port=1935
rtmp.io_threads=16
rtmp.connect_threads=4
rtmp.send_buffer_size=271360
rtmp.receive_buffer_size=65536
rtmp.ping_interval=1000
rtmp.max_inactivity=60000
rtmp.tcp_nodelay=true

# RTMPS
rtmps.host=0.0.0.0
rtmps.port=8443
rtmps.ping_interval=5000
rtmps.max_inactivity=60000
rtmps.max_keep_alive_requests=-1
rtmps.max_threads=20
rtmps.acceptor_thread_count=2
rtmps.processor_cache=20
# RTMPS Keystore Password
rtmps.keystorepass=password

# RTMPT
rtmpt.host=0.0.0.0
rtmpt.port=8088
rtmpt.ping_interval=5000
rtmpt.max_inactivity=60000
rtmpt.max_keep_alive_requests=-1
rtmpt.max_threads=20
rtmpt.acceptor_thread_count=2
rtmpt.processor_cache=20

# MRTMP
mrtmp.host=0.0.0.0
mrtmp.server=localhost
mrtmp.port=9035
mrtmp.event_threads_core=4
mrtmp.event_threads_max=32
# event threads queue: -1 unbounded, 0 direct (no queue), n bounded queue
mrtmp.event_threads_queue=0
mrtmp.event_threads_keepalive=60
mrtmp.send_buffer_size=271360
mrtmp.receive_buffer_size=65536
mrtmp.ping_interval=5000
mrtmp.max_inactivity=60000
mrtmp.tcp_nodelay=true

# Debug proxy (needs to be activated in red5-core.xml)
proxy.source_host=127.0.0.1
proxy.source_port=1936
proxy.destination_host=127.0.0.1
proxy.destination_port=1935

# JMX
jmx.rmi.port.registry=9999
jmx.rmi.port.remoteobjects=
jmx.rmi.host=127.0.0.1
jmx.rmi.ssl=false


red5.config_root=red5.config_root
red5.root=E\:apache-tomcat-6.0.33

 

java代码

package com.chinahrt.chat;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.python.antlr.PythonParser.return_stmt_return;
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;
import org.red5.server.api.stream.IBroadcastStream;

/**
 * createBy ZYN
 *
 * createTime 2011-9-16 下午03:33:15
 *
 * desc 视频聊天服务器
 *
 */
public class VedioChatApplication extends ApplicationAdapter {
	
	private IScope appScope;
	
	private String userName;
	//共享存贮在线用户
	private ISharedObject listSO;
	
	private Map<String,IConnection> onlineList = new HashMap<String,IConnection> ();//在线用户表
	
	//程序运行
	//程序运行时志向 
	public boolean appStart(IScope app) { 
	  if (!super.appStart(app)) { 
	      return false; 
	  } 
	  appScope = app; 
	  return true; 
	} 
	@Override 
	public boolean appConnect(IConnection arg0, Object[] arg1) { 
	  /** 
	   *  用户首次连接server 时触发,检查用户是否重复登录,将用户添加到在线用户表中 
	   */ 
	  String userId=arg0.getClient().getId(); 
	  if(!super.appConnect(arg0, arg1)){ 
	   return false; 
	  } 
	  if (arg1 != null ) { 
	   userName = (String) arg1[0]; 
	  } 
	  if(onlineList.get(userName) != null){ 
	   rejectClient("请不要重复登录"); 
	   return false; 
	  } 
	  onlineList.put(userName, arg0); 
	  listSO = getSharedObject(appScope, "listSO", false); 
	  listSO.setAttribute(userId, userName); 
	  System.out.println("The user:"+userName+","+userName+" logined successfully"); 
	  return true; 
	} 
	/** 
	  * 通知所有人当前用户登录 
	  * @param params 
	  */ 
	public void getOnloadUser(Object[] params) {   
	  String clientName = params[0].toString();  
	  if(null == clientName || "".equals(clientName)) { 
	     return ; 
	   } 
	  //给所有客户端数据 
	   IScope scope = Red5.getConnectionLocal().getScope(); 
	   Iterator it = scope.getConnections().iterator(); 
	   for (;it.hasNext();) { 
	    Set connections = (Set)it.next(); 
	    IConnection tempConn = (IConnection)connections.iterator().next(); 
	    if (tempConn instanceof IServiceCapableConnection) { 
	     IServiceCapableConnection sc = (IServiceCapableConnection) tempConn; 
	     sc.invoke("result_getOnloadUser", new Object[]{clientName}); 
	    } 
	   } 
	} 
	//聊天 
	  public void sayToAll(Object[] params) { 
	   IConnection conn = Red5.getConnectionLocal(); 
	   String user_id = conn.getClient().getId(); 
	   String clientName =(String) listSO.getAttribute(user_id); 
	   System.out.println("************发言者是:"+clientName); 
	   String sayToName=params[0]==null?"":params[0].toString().trim();   
	   String sayWhat=params[1]==null?"":params[1].toString().trim(); 
	   if("".equals(sayToName)||"All".equals(sayToName))// 发消息给聊天室的所有人. 
	   { 
	    IScope scope = Red5.getConnectionLocal().getScope(); 
	    Iterator it = scope.getConnections().iterator();  
	    for (;it.hasNext();) { 
	      Set connections = (Set)it.next(); 
	      IConnection tempConn = (IConnection)connections.iterator().next(); 
	     if (tempConn instanceof IServiceCapableConnection) { 
	         IServiceCapableConnection sc = (IServiceCapableConnection) tempConn; 
	      // 调用客户端showMessage方法。 
	         sc.invoke("showMessage", new Object[]{clientName+" to All:"+sayWhat}); 
	      } 
	   } 
	   }else{ 
	     IConnection tempConn=onlineList.get(sayToName);     
	     if (tempConn instanceof IServiceCapableConnection) { 
	      IServiceCapableConnection sc = (IServiceCapableConnection) tempConn;     
	      sc.invoke("showMessage", new Object[]{clientName+" to "+sayToName+":"+sayWhat}); 
	      } 
	     IServiceCapableConnection sc = (IServiceCapableConnection) conn; 
	     sc.invoke("showMessage", new Object[]{clientName+" to "+sayToName+":"+sayWhat}); 
	   } 
	  } 
	// 用户断开连接的时候触发 
	  public void appDisconnect(IConnection conn) { 
	   String dis_user_id = conn.getClient().getId(); 
	   String user = (String) listSO.getAttribute(dis_user_id); 
	   // 根据ID删除对应在线纪录 
	   onlineList.remove(user); 
	   // 删除用户列表共享对象的对应属性 
	   listSO.removeAttribute(dis_user_id); 
	   IScope scope = Red5.getConnectionLocal().getScope(); 
	    Iterator it = scope.getConnections().iterator();  
	    for (;it.hasNext();) { 
	     Set connections = (Set)it.next(); 
	     IConnection tempConn = (IConnection)connections.iterator().next(); 
	     if (tempConn instanceof IServiceCapableConnection) { 
	         IServiceCapableConnection sc = (IServiceCapableConnection) tempConn; 
	       // 服务器端调用客户端flash方法。 
	         sc.invoke("disconnectMessage", new Object[]{user}); 
	      } 
	    } 
	  } 
		
		
}

 flex端代码

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			import mx.containers.HBox;
			import mx.controls.Alert;
			
			
			private var listSO:SharedObject;
			private var userArr:Array;
			private var conn:NetConnection;
			private var localUsername:String;
			[Bindable]
			private var cam:Camera;
			[Bindable]
			private var mic:Microphone;
			[Bindable]
			public var cards:ArrayCollection;
			public var videoUsers:Array;
			[Bindable]
			public var videoControlArr:Array;
			
			private var stm:NetStream;
			[Bindable]
			private var video_self:Video;
			
			protected function login(event:MouseEvent):void
			{
				localUsername = txt_name.text;
				if(localUsername== ""){
					Alert.show("用户名不能为空");
				}else{
					if(conn == null){
						conn = new NetConnection();
						conn.client = this;
						conn.addEventListener(NetStatusEvent.NET_STATUS,_statusHandler);
						conn.connect("rtmp://192.168.1.61/Red5ChatRoom",localUsername);
					}
				}
			}
			
			//状态监听
			private function _statusHandler(evt:NetStatusEvent):void
			{
				if(evt.info.code == "NetConnection.Connect.Success"){
					this.currentState = "chat";
					Alert.show("连接成功");
					video_clickHandler();
					this.showJoinInInfo(localUsername);
					_setListSO();
					
					
				}
				if(evt.info.code == "NetConnection.Connect.Failed"){
					Alert.show("连接失败");
				}
				if(evt.info.code == "NetConnection.Connect.Closed"){
					Alert.show("连接关闭");
				}
			}
			
			public function showJoinInInfo(message:String):void
			{
				conn.call("getOnloadUser",null,message);
			}
			
			public function result_getOnloadUser(str:String):void{
				txt_chatmsg.text += str + "加入聊天室" + "\n";
			}
			//创建用户列表共享对象
			private function _setListSO():void
			{
				listSO = SharedObject.getRemote("listSO",conn.uri,false);
				listSO.connect(conn);
				listSO.addEventListener(SyncEvent.SYNC,_listSOSyncHandler);
			}
			
			//用户列表共享对象被更新之后的事件
			private function _listSOSyncHandler(evt:SyncEvent):void{
				_showUserList();//更新用户列表
			}
			
			private function _showUserList():void
			{
				cards = new ArrayCollection(
					[{label:"All"}]
				);
				userArr = new Array();
				//用户数组更新
				for(var tmp:String in listSO.data){
					userArr.push(listSO.data[tmp]);
				}
				//添加到arrayCollection
				for(var i:int = 0; i<userArr.length;i++){
					cards.addItem({label:userArr[i]});
				}
				//将数组添加到列表数组中显示出来
				userList.dataProvider = cards;
				users.dataProvider = cards;
				addVideo(cards);
			}
			
			public function showMessage(message:String):void
			{
				txt_chatmsg.text += message + "\n";
			}
			
			protected function sendMessage(event:MouseEvent):void
			{
				var sendString:String = txt_yousay.text;
				var sendTo:String = userList.selectedItem.label;
				txt_yousay.text = "";
				conn.call("sayToAll",null,sendTo,sendString);
			}
			
			//断线通知
			public function disconnectMessage(disUser:String):void
			{
				txt_chatmsg.text += disUser+"退出聊天室\n";
			}
			//进入视频会议
			public function video_clickHandler():void
			{
				stm = new NetStream(conn);
				cam = Camera.getCamera();
				if(cam==null){
					Alert.show("没有可以使用的摄像头");
					return;
				}else{
					Security.showSettings(SecurityPanel.PRIVACY);
					cam.addEventListener(StatusEvent.STATUS,statusHandler);
					cam.addEventListener(ActivityEvent.ACTIVITY,activityHandler);
					cam.setLoopback(true);
					cam.setMotionLevel(50,100);
					cam.setMode(1280,960,15,true); 
					stm.attachCamera(cam);
				}
				mic = Microphone.getMicrophone();
				mic.addEventListener(StatusEvent.STATUS,micOnstatu);
				if(mic == null){
					Alert.show("没有可以使用的麦克风");
				}else{
					mic.setUseEchoSuppression(true);
					stm.attachAudio(mic);
				}
				stm.play("chinahrt-"+txt_name.text);
				stm.publish("chinahrt-"+txt_name.text,"live");
				video_self = new Video();
				video_self.width = 320;
				video_self.height = 240;
				video_self.attachCamera(cam);
				my_video.addChild(video_self);
				
			}
			
			private function micOnstatu(e:StatusEvent):void
			{
				mic.setLoopBack(true);
				mic.gain = 66;
				mic.rate = 11;
				mic.setUseEchoSuppression(true);
				mic.setSilenceLevel(1,-1);
			}
			
			private function statusHandler(e:StatusEvent):void
			{
				
			}
			
			private function activityHandler(e:ActivityEvent):void
			{
			
			}
			
			private function addVideo(cards:ArrayCollection):void
			{
				label1.text = "我的("+localUsername+")";
				myBox.removeAllChildren();
				var otherPerson:ArrayCollection = new ArrayCollection();
				for(var i:int=0;i<cards.length;i++){
					var o:Object = cards.getItemAt(i);
					if(o["label"]!=localUsername&&o["label"]!="All"){
						otherPerson.addItem(o);			
					}
				}
		//		Alert.show(otherPerson.length+"");
				var yushu:int = 0;
				var yushu:int= otherPerson.length%3;
				var rowNum:int = 0;
				var rowNum:int = otherPerson.length/3;
				
				if(yushu!=0){
					rowNum += 1;
				}
				if(yushu==0){
					for(var i:int=0;i<rowNum;i++){
						var hbox:HBox = new HBox();
						myBox.addChild(hbox);
						for(var ii:int=0;ii<3;ii++){
							var vbox:VBox = new VBox();
							hbox.addChild(vbox);
							var label:Label = new Label;
							label.text = otherPerson.getItemAt(i*3+ii)["label"];
							vbox.addChild(label);
							var videoDisplay:VideoDisplay = new VideoDisplay();
							videoDisplay.live = true;
							videoDisplay.width = 320;
							videoDisplay.height = 240;
							vbox.addChild(videoDisplay);
							var video:Video = new Video();
							video.width = 320;
							video.height = 240;
							var netStream:NetStream = new NetStream(conn);
							video.attachNetStream(netStream);
							netStream.play("chinahrt-"+label.text);
							
							videoDisplay.addChild(video);
						}
					}
				}else{
					for(var i:int=0;i<rowNum-1;i++){
						var hbox:HBox = new HBox();
						myBox.addChild(hbox);
						for(var ii:int=0;ii<3;ii++){
							var vbox:VBox = new VBox();
							hbox.addChild(vbox);
							var label:Label = new Label;
							label.text = otherPerson.getItemAt(i*3+ii)["label"];
							vbox.addChild(label);
							var videoDisplay:VideoDisplay = new VideoDisplay();
							videoDisplay.live = true;
							videoDisplay.width = 320;
							videoDisplay.height = 240;
							vbox.addChild(videoDisplay);
							var video:Video = new Video();
							video.width = 320;
							video.height = 240;
							var netStream:NetStream = new NetStream(conn);
							video.attachNetStream(netStream);
							netStream.play("chinahrt-"+label.text);
							videoDisplay.addChild(video);
						}
					}
					var hbox:HBox = new HBox();
					myBox.addChild(hbox);
					for(var i:int=0;i<yushu;i++){
						var vbox:VBox = new VBox();
						hbox.addChild(vbox);
					//	myBox.addChild(vbox);
						var label:Label = new Label();
						label.text = otherPerson.getItemAt((rowNum-1)*3+i)["label"];
						vbox.addChild(label);
						var videoDisplay:VideoDisplay = new VideoDisplay();
						videoDisplay.live = true;
						videoDisplay.width = 320;
						videoDisplay.height = 240;
						vbox.addChild(videoDisplay);
						var video:Video = new Video();
						video.width = 320;
						video.height = 240;
						var netStream:NetStream = new NetStream(conn);
					//	Alert.show(otherPerson.getItemAt((rowNum-1)*3+i)["label"]);
						video.attachNetStream(netStream);
						netStream.play("chinahrt-"+label.text);
						
						videoDisplay.addChild(video);
					}
				}
				
			}
		]]>
	</mx:Script>
	
	<mx:states> 
		<mx:State id="chatState" name="chat"> 
			<mx:SetProperty target="{form1}" name="width" value="0"/> 
			<mx:SetProperty target="{form1}" name="height" value="0"/> 
			<mx:SetProperty target="{form1}" name="x" value="0"/> 
			<mx:SetProperty target="{form1}" name="y" value="0"/> 
			<mx:AddChild position="lastChild"> 
				<mx:Panel x="10" y="10" width="381" height="370" layout="absolute" title="聊天信息"> 
					
					<mx:TextArea x="10" y="10" width="215" height="235" id="txt_chatmsg"/> 
					<mx:ComboBox x="233" y="34" width="118" id="userList"></mx:ComboBox> 
					<mx:Label x="233" y="11" text="用户列表"/> 
					<mx:DataGrid x="233" y="64" height="256" id="users" width="118"> 
						<mx:columns> 
							<mx:DataGridColumn headerText="用户名" dataField="label"/> 
						</mx:columns> 
					</mx:DataGrid> 
					<mx:TextInput x="10" y="253" height="67" width="150" id="txt_yousay"/> 
					<mx:Button x="168" y="253" label="发送" width="57" click="sendMessage(event)"/> 
				<!--	<mx:Button x="168" y="298" label="进入视频会议" width="57" click="video_clickHandler(event)"/>--> 
				</mx:Panel> 
			</mx:AddChild> 
			<mx:AddChild position="lastChild"> 
				<mx:VideoDisplay live="true" x="10" y="410"  width="320" height="240" id="my_video"/> 
			</mx:AddChild> 
			<mx:AddChild position="lastChild"> 
				<mx:Label id="label1" x="10" y="390" text="我的"/> 
			</mx:AddChild> 
			<!--<mx:AddChild position="lastChild"> 
				<mx:VideoDisplay live="true"  x="399" y="224"  width="320" height="240" id="other_video"/> 
			</mx:AddChild> 
			<mx:AddChild position="lastChild"> 
				<mx:Label x="399" y="198" text="对方的"/> 
			</mx:AddChild> -->
			<mx:AddChild position="lastChild">
				<mx:VBox id="myBox" x="399" y="10"/>
			</mx:AddChild>
		</mx:State> 
	</mx:states> 
	
	<mx:Form x="10" y="10" width="283" height="126" id="form1"> 
		<mx:FormItem label="用户名:"> 
			<mx:TextInput id="txt_name"/> 
		</mx:FormItem> 
		<mx:FormItem> 
			<mx:Button label="登陆" click="login(event)"/> 
		</mx:FormItem> 
	</mx:Form> 
</mx:Application>

 百度网盘:http://pan.baidu.com/s/1hqkgBly

  • 大小: 51.7 KB
  • 大小: 99.5 KB
  • 大小: 84.3 KB
9
3
分享到:
评论
45 楼 lbaaixy 2017-12-06  
楼主,小弟最近也在弄这个东西。有点小问题
java.lang.ClassCastException: org.apache.catalina.deploy.SecurityConstraint cannot be cast to org.apache.catalina.deploy.SecurityConstraint
有这个错误。希望帮个小忙
44 楼 chinaxiaofeng8 2016-12-20  
在吗,兄弟,你那个代码怎么运行看效果的
43 楼 odbcjava 2015-08-13  
麻烦给我一份,多谢,junhu.sun@pcitc.com
42 楼 罗小三 2014-04-25  
楼主发个完整demo吧,十分感谢,急需!!!!!!!!!rondo_aniu@sina.com。多谢!
41 楼 hanshiweihx 2014-01-11  
下载了楼主的源代码,在myeclipse中已经成功导入,但是运行一直出错,因为很急切的要使用这个功能,所以冒昧叨扰楼主,是否有空,可以指点一下,只希望能跑起来即可,可以加我QQ764791256,楼主也可以留下QQ我来加,冒昧打扰,十分抱歉
40 楼 zyn010101 2014-01-10  
梦幻小子 写道
297082744@qq.com

http://pan.baidu.com/s/1hqkgBly
39 楼 zyn010101 2014-01-10  
she2shou 写道
很想得到楼主的完整源码来学习啊.
楼主现在有百度云,腾讯微云, 你能上传一份,然后只要给个地址给我们大家就好了. 多谢

http://pan.baidu.com/s/1hqkgBly
38 楼 zyn010101 2014-01-10  
wcl997670205 写道
楼主,发一份源码吧,灰常感谢 997670205wcl@gmail.com O(∩_∩)O谢谢

http://pan.baidu.com/s/1hqkgBly
37 楼 zyn010101 2014-01-10  
she2shou 写道
很想得到楼主的完整源码来学习啊.
楼主现在有百度云,腾讯微云, 你能上传一份,然后只要给个地址给我们大家就好了. 多谢

http://pan.baidu.com/s/1hqkgBly
36 楼 she2shou 2014-01-10  
很想得到楼主的完整源码来学习啊.
楼主现在有百度云,腾讯微云, 你能上传一份,然后只要给个地址给我们大家就好了. 多谢
35 楼 wcl997670205 2014-01-09  
楼主,发一份源码吧,灰常感谢 997670205wcl@gmail.com O(∩_∩)O谢谢
34 楼 梦幻小子 2014-01-07  
297082744@qq.com
33 楼 梦幻小子 2014-01-07  
楼主  这个发份源码给我学习下好么  万分感谢
32 楼 bin474740536 2013-12-30  
楼主,给我发一份齐全的源码,让我学习一下 474740536@qq.com
31 楼 moonskyii90 2013-12-27  
求楼主传我一份参考 拜谢啊  moonskyii@qq.com
30 楼 chenlk823 2013-12-27  
我最近都被这个烦透了,求demo
chen_like00@163.com
29 楼 IT_ty 2013-12-20  
求楼主源码 643146521@qq.com
28 楼 mzy9950012 2013-12-18  
求发分demo来啊 mzy9950012@163.com
27 楼 hezhaomeng 2013-11-04  
楼主求源码 万分感激 807586760@qq.com
26 楼 cclovehxj52 2013-10-11  
  楼主求一份源码,谢谢 cclovehxj52@163.com

相关推荐

Global site tag (gtag.js) - Google Analytics