简单的对话聊天窗体组件

这个也是前面博客  

php+as3简单聊天室这一篇许给大家的东西,本来是挂在我国外租用空间上的,去年国外空间费用调整,我没及时看到通知,所以挂在空间的一些东西丢失了,好在我源码一般都有备份,不过调试环境变化了 ,所以有些东西需要在本地重新配置环境,比如说这个东西,我当时在amfphp1.9+php5.2+mysql5环境下写的,但Php升5.26之后,对amfphp1.9不再支持了,所以这次,我又重新安装了一个低版本的阿帕奇+php环境,跟php+as3那篇博客差的时间有点长,这个东西其实就是玩具,没有任何实用价值,因为第一as3现阶段下行速度太明显,另外这个工具直接通过读写数据库来操作,如果是真实的项目,那么服务器的压力会很快吃不消,真正现在实用的工具,都是用redis和memcached这样的存储服务器来临时保存这么快速更新的数据,过一段时间,在同步到我们的真实数据库,也就是说把我这个东西的php部分用上面两个工具拿到服务器内存里面来工作,不过为什么没用还拿出来呢,因为写这东西的时候网络方面还没啥经验,另外这个工具也能一定程度上减少客户端的工作量,总比从0开始要好,小伙伴们可以根据这个工具的思路来写自己的聊天窗口,只要把这里的连接amfphp部分改成redis和memcached就可以了,当然go语言也可以,我们先看下运行结果

看这个演示,可能细心的小伙伴发现,他跟我前面写的那个聊天室的区别在于它有世界和帮派两个窗口,两个窗口接收的服务器信息是不同的,像不像梦幻西游的聊天窗体呢(当时我就是想山寨一个这样的组件),它是怎么做的呢,我们来看看,

<?php
class flash_guest {
public function flash_guest() {
 mysql_connect("localhost", "root", "root")or die("没找到数据库");
 mysql_select_db("airdb")or die("连接数据库失败");
} 
function addtobase($username, $userqq, $useremail, $usermessage) {
$addto="INSERT INTO `airdb`.`guest` (
`id` ,
`username` ,
`qq` ,
`useremail` ,
`usermessage` 
)
VALUES (
'', '".$username."', '".$userqq."', '".$useremail."', '".$usermessage."'
)
";
mysql_query($addto);
return null;
}
function showmessage() {

return mysql_query("SELECT * 
FROM `guest` ORDER BY `guest`.`id` DESC 
LIMIT 0 , 30");


}
}




?>
这是服务器的php源码,过后我会跟amfphp1.9一起打包给大家,省的大家去网上找了,上面连接数据库的部分记得要自己改下,改成小伙伴自己本地的数据库登录,然后我们看看sql
-- phpMyAdmin SQL Dump
-- version 3.1.3
-- http://www.phpmyadmin.net
--
-- 主机: localhost
-- 生成日期: 2009 年 10 月 17 日 20:55
-- 服务器版本: 5.1.32
-- PHP 版本: 5.2.9-1

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

--
-- 数据库: `mydatabase`
--

-- --------------------------------------------------------

--
-- 表的结构 `guest`
--

CREATE TABLE IF NOT EXISTS `guest` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) NOT NULL,
  `qq` int(20) NOT NULL,
  `useremail` varchar(25) NOT NULL,
  `usermessage` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=41 ;

--
-- 导出表中的数据 `guest`
--

INSERT INTO `guest` (`id`, `username`, `qq`, `useremail`, `usermessage`) VALUES
(1, 'swordfishx82', 95766154, 'swordfishx@163.com', 'godness me');
把sql文件导入到数据库中,我们先在Mysql里面定义一个名为airdb的空库,然后导入


导入之后是这样的,然后我们看看amfphp1.9什么样子,

amfphp1.9之所以一直被国内开发者喜爱是因为,这个版本带了一个flash的可视化窗口工具,在2.0之后不知为啥,这个工具没有了,调试起来反而麻烦了,而且2.0版本之后链接取消了原来的gateway.php文件,直接连接index.php这个文件,我们看下客户端如何写的

左边代码注释的地方是我以前国外空间的地址,现在没用了,所以改成了下面的本地,工具的目录结构如右边,这里注意蓝色的lib,flcs4Component.swc是flash4的可视化组件库,因为as3里面缺少这些东西,所以我在flash5里面把可视化组件打成了swc包方便在as3里面使用,

看代码,
package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import TalkTip.TalkTip;
	
	/**
	 * ...
	 * @author swordfishx
	 */
	public class Main extends Sprite 
	{
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			addChild(new TalkTip());
		}
		
	}
	
}
文档类,这个是我的习惯,因为为了方便整合到其他地方,我总是喜欢,把做好的组件单提出来,让他可以直接new出来使用,所以文档类里面一直都会很干净,

package TalkTip
{
	import fl.controls.Label;
	import flash.display.Bitmap;
	import flash.display.Sprite;
	import fl.controls.TextArea;
	import fl.controls.TextInput;
	import fl.controls.Button;
	import flash.events.MouseEvent;
	import flash.net.NetConnection;
	import flash.net.Responder;
	import flash.events.Event;
	
	/**
	 * ...
	 * @author swordfishx
	 */
	public class TalkTip extends Sprite
	{
		
		[Embed(source="../../lib/TaikTipRes/xs.jpg")]
		private var TalkTipResxs:Class;
		[Embed(source="../../lib/TaikTipRes/xx.jpg")]
		private var TalkTipResxx:Class;
		private var htmstr:String = "<font color='#ff0000' size='25' face='宋体'>" + "健康游戏,抵制外挂" + "</font>"
		private var textareaheight:int = 150;
		//-------------------通讯-----------
		//private var mylocalhost:String = "http://swordfishx.freevar.com/amfphp/gateway.php";
		private var mylocalhost:String ="http://localhost/amfphp1.9/gateway.php";
		private var myconn:NetConnection;
		private var myresponder:Responder;
		
		//-------------------------------------
		private var imgxs:Bitmap = new TalkTipResxs();
		private var imgxx:Bitmap = new TalkTipResxx();
		private var button:Button = new Button();
		private var btnworld:Button = new Button();
		private var btnprivate:Button = new Button();
		private var textarea:TextArea = new TextArea();
		private var inputtxt:TextInput = new TextInput();
		private var nameinput:TextInput = new TextInput();
		private var emailinput:TextInput = new TextInput();
		private var qqinput:TextInput = new TextInput();
		private var qqname:Label = new Label();
		private var namelb:Label = new Label();
		//---------------------------------------------初始化
		private var TalkState:int = 0;
		
		//---------------------------------------
		public function TalkTip()
		{
			init();
		}
		
		private function init():void
		{
			
			textarea.x = 1;
			textarea.width = 300;
			textarea.height = textareaheight;
			textarea.htmlText = htmstr;
			textarea.alpha = 1;
			//-------------------------显示区域
			btnworld.width = 50;
			btnworld.label = "世界";
			btnworld.x = 1;
			btnworld.y = textarea.height + 1;
			btnprivate.width = 50;
			btnprivate.label = "帮派";
			btnprivate.x = btnworld.width + 1;
			btnprivate.y = textarea.height + 1;
			//-----------------------------连接切换
			imgxs.x = 250;
			imgxx.x = 250 + imgxs.width;
			imgxs.y = textarea.height + 1;
			imgxx.y = textarea.height + 3;
			//----------------------------布局
			inputtxt.x = 1;
			inputtxt.width = 250;
			inputtxt.y = textarea.height + 1 + btnprivate.height;
			button.width = 50;
			button.label = "发送";
			button.x = inputtxt.width + 1;
			button.y = textarea.height + 1 + btnprivate.height;
			//------------------------------------------------
			btnworld.addEventListener(MouseEvent.CLICK, btworldstate);
			btnprivate.addEventListener(MouseEvent.CLICK, btnprivatestate);
			button.addEventListener(MouseEvent.CLICK, onsub);
			//---------------------------
			
			
			qqname.text = "qq号码:";
			namelb.text = "名称:";
			qqname.x = 300;
			qqname.y = 1;
			namelb.x = 300;
			namelb.y = 100;
			nameinput.x = 300+qqname.width;
			nameinput.y = 100;
			qqinput.x = 300+qqname.width;
			qqinput.y = 1;
			//--------------------------
			addChild(button);
			addChild(textarea);
			addChild(btnworld);
			addChild(btnprivate);
			addChild(imgxs);
			addChild(imgxx);
			addChild(inputtxt);
			addChild(nameinput);
			addChild(qqinput);
			addChild(namelb);
			addChild(qqname);
			//addChild(emailinput);
		}
		
		private function btworldstate(evt:MouseEvent):void
		{
			TalkState = 0;
			onshow();
			trace("0");
		}
		
		private function btnprivatestate(evt:MouseEvent):void
		{
			TalkState = 1;
			onshow();
			trace("1");
		}
		
		private function onsub(evt:MouseEvent):void
		{
			myresponder = new Responder(onsubresult);
			myconn = new NetConnection();
			myconn.connect(mylocalhost);
			if (TalkState == 0)
			{
				myconn.call("flash_guest.addtobase", myresponder, nameinput.text, int(qqinput.text), emailinput.text, inputtxt.text);
			}
			else if (TalkState == 1)
			{
				myconn.call("flash_guest.addtobase", myresponder, nameinput.text, int(qqinput.text), inputtxt.text, inputtxt.text);
			}
			cleartext();
		
		}
		
		private function onshow():void
		{
			if (TalkState == 0)
			{
				myresponder = new Responder(onshowresult, onshowstatus);
			}
			else if (TalkState == 1)
			{
				
				myresponder = new Responder(onprivateshowresult, onshowstatus);
				
			}
			
			myconn = new NetConnection();
			myconn.connect(mylocalhost);
			myconn.call("flash_guest.showmessage", myresponder);
		}
		
		private function onshowresult(p:Object):void
		{
			textarea.text = "";
			var showarray:Array = new Array();
			showarray = p["serverInfo"]["initialData"];
			
			for (var i:uint; i < showarray.length; i++)
			{
				
				
				//showmessage.text += "\n QQ:"+showarray[i][2];
				if (showarray[i][3] != "")
				{
					textarea.text += String("\n 昵称:" + showarray[i][1]);
					textarea.text += "\n 帮派:" + showarray[i][3];
				}
				else
				{
					textarea.text += String("\n 昵称:" + showarray[i][1]);
					textarea.text += "\n 世界:" + showarray[i][4];
				}
				textarea.text += "\n===================================";
			}
		}
		
		private function onprivateshowresult(p:Object):void
		{
			textarea.text = "";
			trace("帮派");
			var showarray:Array = new Array();
			showarray = p["serverInfo"]["initialData"];
			for (var i:uint; i < showarray.length; i++)
			{
				
				if (showarray[i][3] != "")
				{
					textarea.text += String("\n 昵称:" + showarray[i][1]);
					textarea.text += "\n 帮派:" + showarray[i][3];
					textarea.text += "\n===================================";
				}
				
			}
		}
		
		private function onsubresult(p:Object):void
		{
			
			inputtxt.text = "提交成功!";
			onshow();
		}
		
		private function onshowstatus(p:Object):void
		{
			inputtxt.text = "连接出错";
		}
		
		private function cleartext():void
		{
			
			nameinput.text = "";
			qqinput.text = "";
			emailinput.text = "";
			inputtxt.text = "";
		}
	}

}
代码并不多,我讲讲,amfphp是怎么工作的,首先
private var mylocalhost:String ="http://localhost/amfphp1.9/gateway.php";
这句连接amfphp,通知amfphp工作,然后我们以按钮为例看看他是如何通信的,
button.addEventListener(MouseEvent.CLICK, onsub);
这里鼠标监听onsub,

	private function onsub(evt:MouseEvent):void
		{
			myresponder = new Responder(onsubresult);
			myconn = new NetConnection();
			myconn.connect(mylocalhost);
			if (TalkState == 0)
			{
				myconn.call("flash_guest.addtobase", myresponder, nameinput.text, int(qqinput.text), emailinput.text, inputtxt.text);
			}
			else if (TalkState == 1)
			{
				myconn.call("flash_guest.addtobase", myresponder, nameinput.text, int(qqinput.text), inputtxt.text, inputtxt.text);
			}
			cleartext();
		
		}
		
上面的call方法中这里调用了myresponder,它是amfphp核心responder类的一个实例

	private function onsubresult(p:Object):void
		{
			
			inputtxt.text = "提交成功!";
			onshow();
		}
结果方法,在这个方法中有一个onshow(),

private function onshow():void
		{
			if (TalkState == 0)
			{
				myresponder = new Responder(onshowresult, onshowstatus);
			}
			else if (TalkState == 1)
			{
				
				myresponder = new Responder(onprivateshowresult, onshowstatus);
				
			}
			
			myconn = new NetConnection();
			myconn.connect(mylocalhost);
			myconn.call("flash_guest.showmessage", myresponder);
		}
这里把接收到数据分开,世界和帮派的数据不同就是因为这里,

myresponder = new Responder(onshowresult, onshowstatus);
这里有两个方法,前面的是有数据成功时的调用,后面是失败时的调用,

private function onshowresult(p:Object):void
		{
			textarea.text = "";
			var showarray:Array = new Array();
			showarray = p["serverInfo"]["initialData"];
			
			for (var i:uint; i < showarray.length; i++)
			{
				
				
				//showmessage.text += "\n QQ:"+showarray[i][2];
				if (showarray[i][3] != "")
				{
					textarea.text += String("\n 昵称:" + showarray[i][1]);
					textarea.text += "\n 帮派:" + showarray[i][3];
				}
				else
				{
					textarea.text += String("\n 昵称:" + showarray[i][1]);
					textarea.text += "\n 世界:" + showarray[i][4];
				}
				textarea.text += "\n===================================";
			}
		}
private function onshowstatus(p:Object):void
		{
			inputtxt.text = "连接出错";
		}
如果看过烽烟ol客户端源码的小伙伴会发现,烽烟ol的源码是严格按这种模式来写的,甚至方法名都一样,不过烽烟ol用的是sokect连接,不要弄混了,

代码下载在这里
好了,最后我们说说,如何连接redis,memcached前面的博客有提到如何简单使用,go语言的话,因为它直接集成了memcached(不能叫集成,因为memcached作者是Go语言开发团队的一员,所以go语言直接包括了memcached的功能

以c#为例,连接

RedisClient client=new RedisClient("localhost",6379);

Set<string>(client,"username","swordfishx");

Set<int>(client,"pwd","123456");

client.Save();
Console.Ready();

这就是大概的redis保存流程,好了,我们下一篇再见。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值