2013年5月29日 星期三

FMS-FLASH MEDIA SERVER 視訊網站架設教學(2)

這篇主要建立一個簡易的聊天室
登入後,會更新房間人員的清單
發送聊天訊息
使用同一人名登入 會顯示登入失敗

SERVER CODE-main.asc

var roomUser = new Array();
var ERROR_REPEAT_LOGIN=0;
application.onAppStart = function (){ 
 
}
// Called when a client connects
application.onConnect = function(client,userName) {
 var _user=getUserByUserName(userName);
 if(_user)
 {
  application.rejectConnection(client,ERROR_REPEAT_LOGIN);
  return;
 }
 
 var user=new Object();
 user.userName=userName;
 user.id=client.id;
 user.client=client;
 roomLogin(user);
 
 client.chatToAll = function(msg) {
  var user=getUserByClient(client);
  application.broadcastMsg("chatReceive",user.userName,msg);
 }
}

// Called when a client disconnects
application.onDisconnect = function(client) {
 var user=getUserByClient(client);
 removeUser(user);
}

function roomLogin(user)
{
 application.acceptConnection(user.client);
 application.broadcastMsg("systemMessage", user.userName+" in room");
 roomUser.push(user);
 application.broadcastMsg("userList",roomUser);
}

function removeUser(user){
 var ind=roomUser.indexOf(user);
 if(ind!=-1)
 {
  roomUser.splice(ind,1);
  application.broadcastMsg("userList",roomUser);
 }

}

function getUserByUserName(userName){
 for(var i=0;i<roomUser.length;i++)
  {
   if(roomUser[i].userName==userName)
   {
    return roomUser[i];
   }
  }
  return null;
}

function getUserByClient(client){
 for(var i=0;i<roomUser.length;i++)
  {
   if(roomUser[i].client==client)
   {
    return roomUser[i];
   }
  }
  return null;
}





CLIENT CODE-chatRoom.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
      xmlns:s="library://ns.adobe.com/flex/spark" applicationComplete="application1_applicationCompleteHandler(event)"
      xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
 <fx:Script>
  <![CDATA[
   import flash.net.NetStream;
   import flash.utils.setTimeout;
   
   import mx.collections.ArrayCollection;
   import mx.controls.Alert;
   import mx.events.FlexEvent;
   
   private var server_ip:String="rtmp://localhost/chat";
   private var mineNc:NetConnection;
   private var mineNs:NetStream;
   [Bindable]
   private var userArr:ArrayCollection=new ArrayCollection();
   protected function application1_applicationCompleteHandler(event:FlexEvent):void
   {
    chat_input.addEventListener(KeyboardEvent.KEY_UP,onChatKeyUp);
   }
   private function login():void
   {
    var name:String=name_txt.text;
    if(name!="")
    {
     mineNc = new NetConnection();
     mineNc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
     mineNc.connect(server_ip,name);
     login_group.visible=false;
     
     var ncClient:Object = new Object(); 
     mineNc.client = ncClient; 
     ncClient.systemMessage = systemMessage;
     ncClient.userList = userList;
     ncClient.chatReceive = chatReceive;
    }
    else
     Alert.show("請輸入登入別名", "ERROR", Alert.OK,null);
   }
   private function netStatusHandler(event:NetStatusEvent):void
   {
    trace(event.info.code);
    switch (event.info.code)
    {
     case "NetConnection.Connect.Success":
      break;
     case "NetConnection.Connect.Closed":
      Alert.show("Closed", "ERROR", Alert.OK,null);
      break;
     case "NetConnection.Connect.Rejected":
      loginFail(event.info.application); 
      break;
    }
   }
   private function loginFail(type:int):void{
    switch(type)
    {
     case 0:
      Alert.show("重覆登入", "ERROR", Alert.OK,null);
      break;
     default:
      Alert.show("Rejected", "ERROR", Alert.OK,null);
      break;
    }
   }
   private function onChatKeyUp(evt:KeyboardEvent):void
   {   
    if (evt.keyCode == Keyboard.ENTER)
    {
     mineNc.call("chatToAll", null,chat_input.text);
     chat_input.text="";
    }
   }
   
   private function systemMessage(msg:String):void
   { 
    msg+=String.fromCharCode(13);
    content_txt.text+=msg;
   }
   
   private function userList(list:Object):void
   {
    userArr=new ArrayCollection;
    for(var i:int=0;i<list.length;i++)
    {
     userArr.addItem(list[i]);
    }
   }
   
   private function chatReceive(senderName:String,msg:String):void
   {
    msg=senderName+":"+msg+String.fromCharCode(13);
    content_txt.text+=msg;
   }
  ]]>
 </fx:Script>
 <s:HGroup width="100%" height="100%">
  <s:List id="room_list" width="20%" height="100%" dataProvider="{userArr}" itemRenderer="userItem" verticalScrollPolicy="auto" horizontalScrollPolicy="off" contentBackgroundAlpha="0.0" borderVisible="false"/>
  <s:VGroup  width="80%" height="100%">
   <s:TextArea editable="false" id="content_txt" width="100%" height="90%"/>
   <s:TextInput id="chat_input"  width="100%" height="10%"/>
  </s:VGroup>
 </s:HGroup>
 <s:HGroup id="login_group" right="10" top="10">
  <s:TextInput width="100" id="name_txt"/>
  <s:Button label="login" click="login()"/>
 </s:HGroup>
</s:Application>


CLIENT CODE-userItem.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" width="90" height="21" creationComplete="itemrenderer1_creationCompleteHandler(event)">
 <fx:Script>
  <![CDATA[
   import mx.events.FlexEvent;
   
   protected function itemrenderer1_creationCompleteHandler(event:FlexEvent):void
   {
    // TODO Auto-generated method stub
    
   }
   
  ]]>
 </fx:Script>
 <s:Label text="{data.userName}" verticalCenter="0"/>
</s:ItemRenderer>


這篇要注意的幾點
server呼叫單一個client的method 是使用client.call
server廣播所有client的method是application.broadcastMsg
以上2個方法 都需要在application.accept
Connection(client);
允許該client加入之後 ,才可使用。

application.rejectConnection(client,ERROR_REPEAT_LOGIN);
若不同意使用者登入 可以使用rejectConnection
rejectConnection是可以帶參數回去的

其餘的應該都很簡單 就不多做講解了~

沒有留言:

張貼留言