2010年12月20日星期一

如何用Windows VPS搭建翻墙VPN(转)

最近从Photonvps.com 租了一台windows主机用来测试网站,512MB的内存,35GB的硬盘空间,每个月500GB的流量和2个独立IP地址。我感觉价格偏贵,不过售后服务还是蛮不错的,每次提交的ticket很快就会得到回复。

既然有两个IP当然不能浪费了,干脆做个windows VPN用来翻墙。下面详细图文介绍如何用Windows VPS搭建翻墙VPN服务器。首先我们要保证vpn起用的条件,"一停四开":
1.停止window自带的防火墙(windows firewall/internet connection sharing (ICS)服务
2.远程注册表服务(Remote Registry)必须开启
3.server服务 (Server)必须开启
4.route路由服务(Routing and Remote Access)必须开启
5.Workstation 服务必须开启
如果服务器是默认配置的情况下,只需要关闭防火墙就并设置启动方式为禁用。然后在管理工具中打开"路由和远程访问"在列出的本地服务器上点击右键,选择"配置并启用路由和远程访问"。

由于Windows VPS服务器是公网上的一台一般的服务器,不是具有路由功能的服务器,是单网卡的,所以这里选择"自定义配置"这里选"VPN访问"和"NAT/基本防火墙"。下一步,配置向导完成。


点击"是",开始服务。看启动了VPN服务后,"路由和远程访问"的界面下面开始配置VPN服务器,在服务器上点击右键,选择 "属性",在弹出的窗口中选择"IP"标签,在"IP地址指派"中选择"静态地址池"。

然后点击"添加"按钮设置IP地址范围,这个IP范围就是VPN局域网内部的虚拟IP地址范围,每个拨入到VPN的服务器都会分配到一个范围内的IP,在虚拟局域网中用这个IP相互访问。这里设置为 10.10.10.1-10.10.10.10,一共10个IP,默认的VPN服务器占用第一个IP,所以,10.10.10.1实际上就是这个VPN服务器在虚拟局域网的IP。
每个客户端拨入VPN服务器都需要有一个帐号,默认是 windows身份验证,所以要给每个需要拨入到VPN的客户端设置一个用户,并为这个用户制定一个固定的内部虚拟IP以便客户端之间相互访问。在管理工 具中的计算机管理里添加用户,这里以添加一个vpnuser用户为例:先新建一个叫"vpnuser"的用户,创建好后,查看这个用户的属性,在"拨入" 标签中做相应的设置,如图:


远程访问权限设置为"允许访问",以允许这个用户通过VPN拨入服务器。点选"分配静态IP地址",并设置一个VPN服务器中静态IP池范围内的一个IP 地址,这里设为10.10.10.10 。如果有多个客户端机器要接入VPN,请给每个客户端都新建一个用户,并设定一个虚拟IP地址,各个客户端都使用分配给自己的用户拨入VPN,这样各个客 户端每次拨入VPN后都会得到相同的IP。如果用户没设置为"分配静态IP地址",客户端每次拨入到VPN,VPN服务器会随机给这个客户端分配一个范围 内的IP。

至此,客户端就可以直接通过windows连接向导连接VPN服务器了,但是服务器还没有完全配置完,这里需要特别说明一下:我们搭建VPN服务器的目的是翻墙,而不是访问服务器所在的内网。如果仅仅是为了访问内网资源而搭建VPN请看《windows2003架设VPN穿越Juniper防火墙设置步骤》这篇文章介绍了用Windows2003搭建VPN需要注意的细节及通过VPN跨网段访问内网资源的设置。

再回到路由和远程控制,找到"NAT/基本防火墙"右键点击新建接口并选择本地区域链接。如图:

在NAT/基本防火墙设置中选择公共接口链接到Internet,并在这个接口上启用NAT。如图:

选择IP地址池选项卡,将ISP也就是你的主机供应商分配给的公网IP地址添上。如图:

为了维护起来方便,我们可以将VPN用户名和IP绑定起来,也就说每个用户连接VPN会分到固定的IP地址,点击预留IP将公网IP和私有IP进行 绑定,我刚刚建立了一个vpnuser的用户并给此用户分配了私有IP:10.10.10.10 那么我就把这个私有IP绑定在多余的IP地址上。如图:

OK!到这里VPN就配置完成了。尽情享受翻墙的乐趣吧!

摘自:http://www.fendou.info/network/windows-vps-vpn.html

2010年12月18日星期六

一个简单好用的AJAX类,支持超时处理,兼容IE6/IE7/IE8/firefox/chrome/opera(转)

做一回标题党,因为很多人会通过那些关键字搜索进来。是否“简单好用”不太好说,因人而异,但后面两句还是比较靠谱的。


这个AJAX“类”是自己几年前写的,最近抽空整理了一下发出来,供新手或有需要的人参考

在用AJAX的时候,一般只需要关心三个步骤:

1) 请求发送前做什么;

     比如:展现给用户一个loading的图片或文字信息。


2) 发送请求;

     这里有三个参数:url—发送到哪里,data—发送什么数据,method—用什么方式发送数据(GET or POST)


3) 请求返回后做什么;

     比如:将返回后的数据直接或组织成html后插入到页面中展现给用户。


考虑在某些情况下,请求返回的时间很长甚至没有返回,如果一直在loading,恐怕不是一种好的用户体验。所以增加一个在超时的情况下要做的步骤。


由于GET方式经常用,所以单独为它准备了一个方法。


在demo中的test3,除了演示另一种调用方式外,还演示了客户端和服务端之间通过JSON进行通信。


 

最 后面附有完整demo的源代码供下载 <script src="/javascripts/tinymce/themes/advanced/langs/zh.js" type="text/javascript"></script><script src="/javascripts/tinymce/plugins/javaeye/langs/zh.js" type="text/javascript"></script>

Js代码
  1. /*! 
  2. * 一个简单的Ajax类 
  3. * author: ichenshy@gmail.com 
  4. * date:   2010/06/04 Friday 
  5. * 
  6. * @param function fnBefore     用户自定义函数 Ajax开始前执行,若无则为null 
  7. * @param function fnAfter      用户自定义函数 Ajax完成后执行,若无则为null 
  8. * @param function fnTimeout    用户自定义函数 Ajax请求超时后执行,若无则为null 
  9. * @param integer  iTime        设置超时时间 单位毫秒 
  10. * @param boolean  bSync        是否为同步请求,默认为false 
  11. */  
  12.   
  13. function Ajax(fnBefore,fnAfter,fnTimeout,iTime,bSync){  
  14.     this.before     = fnBefore;  
  15.     this.after      = fnAfter;  
  16.     this.timeout    = fnTimeout;  
  17.     this.time       = iTime ? iTime : 10000;  
  18.     this.async      = bSync ? false : true;  
  19.     this._request   = null;  
  20.     this._response  = null;  
  21. }  
  22.   
  23. Ajax.prototype = {  
  24.     /** 
  25.     *  将需要发送的数据进行编码 
  26.     * 
  27.     *  @param object data  JSON格式的数据,如: {username:"fyland",password:"ichenshy"} 
  28.     */  
  29.     formatParam : function( data ){  
  30.         if ( ! data || typeof data != "object" ) return data;  
  31.         var k,r = [];  
  32.         for ( k in data ) {  
  33.             r.push([k,'=',encodeURIComponent(data[k])].join(''));  
  34.         }  
  35.         return r.join('&');  
  36.     },  
  37.   
  38.     /** 
  39.     * 创建 XMLHttpRequest对象 
  40.     */  
  41.     create : function(){  
  42.         if( window.XMLHttpRequest ) {  
  43.             this._request = new XMLHttpRequest();  
  44.         } else {  
  45.             try {  
  46.                 this._request = new window.ActiveXObject("Microsoft.XMLHTTP");  
  47.             } catch(e) {}  
  48.         }  
  49.     },  
  50.   
  51.     /** 
  52.     * 发送请求 
  53.     * 
  54.     * @param string             url     请求地址 
  55.     * @param object or string   data    可以是字符串或JSON格式的数据,如: {username:"fyland",password:"ichenshy"} 
  56.     * @param string             method  请求方式 : GET or POST 
  57.     * @param boolean            ifCache 返回数据是否在浏览器端缓存,默认为false; 
  58.     */  
  59.     send : function(url,data,method,ifCache){  
  60.         if ( typeof this.before == "function" ) this.before();  
  61.   
  62.         method = method.toUpperCase();  
  63.         this.create();  
  64.   
  65.         var self = this;  
  66.         var timer = setTimeout(function(){  
  67.                 if ( typeof self.timeout == "function" ) self.timeout();  
  68.                 if ( self._request ) {  
  69.                     self._request.abort();  
  70.                     self._request = null;  
  71.                 }  
  72.                 return true;  
  73.             },this.time);  
  74.   
  75.         var sendBody  = this.formatParam(data);  
  76.   
  77.         if ( 'GET' == method ) {  
  78.             url = [url, ( url.indexOf('?') == -1 ? '?' : '&') ,sendBody].join('');  
  79.             sendBody = null;  
  80.         }  
  81.   
  82.         if ( ! ifCache ) {  
  83.             url = [url, ( url.indexOf('?') == -1 ? '?' : '&') , "ajaxtimestamp=" , (new Date()).getTime()].join('');  
  84.         }  
  85.   
  86.         this._request.open(method,url,this.async);  
  87.         if ( "POST" == method ) this._request.setRequestHeader("Content-Type""application/x-www-form-urlencoded");  
  88.   
  89.         this._request.onreadystatechange = function(){  
  90.             if( self._request.readyState==4 ){  
  91.                 if ( self._request.status==200 ){  
  92.                     if ( timer ) clearTimeout(timer);  
  93.                     self._response = self._request.responseText;  
  94.                     if ( typeof self.after == "function") self.after(self._response);  
  95.                 }  
  96.             }  
  97.         }  
  98.         this._request.send( sendBody );  
  99.     },  
  100.   
  101.     /** 
  102.     *   简单的GET请求 
  103.     * 
  104.     *   @param string url  请求地址 
  105.     *   @param null or string or object data 
  106.     *   @param object html element or string id   e 
  107.     *   @param string loading                     loading时在e中的显示 
  108.     *   @param boolean  ifCache    浏览器是否缓存 
  109.     */  
  110.     get : function(url,data,e,loading,ifCache){  
  111.             if ( typeof e == "string" ) e = document.getElementById(e);  
  112.             if ( loading ) {  
  113.                 var rg = /\.(gif|jpg|jpeg|png|bmp)$/i;  
  114.                 if ( rg.test(loading) ){  
  115.                     loading = ['<img src="', loading , '"  align="absmiddle" />'].join('');  
  116.                 }  
  117.                 this.before = function(){e.innerHTML = loading;}  
  118.             }  
  119.             this.after      = function(s){e.innerHTML = s;}  
  120.             this.timeout    = function(){e.innerHTML = ' 请求超时! ';}  
  121.             this.send(url,data,"GET",ifCache ? true : false);  
  122.     }  
  123. };  

 

常用调用方式:

Js代码
  1. function test1(){  
  2.      (new Ajax()).get("./process.php?test=1",'',$("view"),"test1正在读取数据……"); // 这里可以传入一个loading的图片地址  
  3. }  
  4.   
  5. function test2(){  
  6.     (new Ajax(function(){  
  7.         $("view").innerHTML = "test2正在读取数据,请稍候";  
  8.     },function(s){  
  9.         $("view").innerHTML = s;  
  10.     },function(){  
  11.         $("view").innerHTML = "Sorry,请求超时!";  
  12.     },5000) ).send("./process.php?test=2",{author:"fyland",mail:"ichenshy@gmail.com",date:"2010-06-03"},"POST");  
  13. }  
  14.   
  15. function test3(){  
  16.     var jx = new Ajax();  
  17.     jx.before = function(){  
  18.         $("view").innerHTML = "test3正在读取数据,请稍候";  
  19.     }  
  20.   
  21.     jx.after = function(s){  
  22.         var r = jsonDecode(s);  
  23.         for ( var k in r ){  
  24.             alert(k + ' : ' + r[k]);  
  25.         }  
  26.         $("view").innerHTML = "test3数据读取完毕";  
  27.     }  
  28.   
  29.     jx.timeout = function(){  
  30.         $("view").innerHTML = "Sorry,TEST3请求超时!";  
  31.     }  
  32.   
  33.     jx.time = 5000;  
  34.   
  35.     var data = {  
  36.                     author: "fyland",  
  37.                     mail  : "ichenshy@gmail.com",  
  38.                     date  : "2010-06-03"  
  39.                 };  
  40.   
  41.     jx.send("./process.php?test=3",data,"GET");  
  42. }  

 


注:
1、method只支持GET和POST
2、ifCache设为false或者不设置,可以控制浏览器不缓存,但设为true后,不一定能控制浏览器缓存返回的数据,因为还需要服务端的配合。

 

  • 大小: 4.6 KB
摘自:http://www.javaeye.com/topic/685578

2010年12月17日星期五

Mysql5一主库两从库同步配置(转)

一、安装包选择
mysql-5.0.67.tar.gz  (安装在主库机:server1
mysql-5.0.45.tar.gz  (安装在从库机:server2
MySQL-client-community-5.0.67-0.sles10.i586.rpmMySQL-server-community-5.0.67-0.sles10.i586.rpm  (安装在从库机:server3
最好使用同一版本的安装包。在这里只是想试验一下。
二、安装环境
192.168.100.188  RHEL5.1  数据文件的存放位置/usr/local/mysql5/var
待同步数据库juwangtest 
192.168.100.39   CentOS5.2  /usr/local/mysql/var
192.168.100.15   OpenSuSE11  /var/lib/mysql
rpm包在suse下的mysql服务启动:/etc/init.d/mysql  start
在源码包安装在CentOSRHEL5.1mysql服务分别为:
/usr/local/mysql/bin/mysqld_safe –user=mysql &
/usr/local/mysql/bin/mysqld_safe –user=mysql &
停止服务:bin/mysqladmin shutdown
三、主服务器配置
1)建立用户
grant  replication  slave .  *.*  to  slave1@192.168.100.39  identified by '123456';
grant  replication  slave .  *.*  to  slave2@192.168.100.15  identified by '123456';
flush  privileges;
2)修改my.cnf
vi  /etc/my.cnf
server-id = 1
log-slave-updates
binlog-do-db=juwang 
ç关于复制的数据库一定要分开写。不能写成binlog-do-db=juwang,test。这是无效的,两个数据库一个都不会复制。
binlog-do-db=test
binlog-ignore-db=mysql
3锁主库表
mysql> FLUSH TABLES WITH READ LOCK;
4显示主库信息
SHOW MASTER STATUS;
5另开一个终端,打包主库
cd  /usr/local/mysql5/var
tar  czvf  juwang.tar.gz  juwang
四、设置SLAVE
1)传输主库压缩包、解压
cd  /usr/local/mysql/var
scp  /usr/local/mysql5/var/juwang.tar.gz .
tar  xf  juwan.tar.gz
2)解锁主库表
mysql> UNLOCK TABLES;
3查看修改juwang文件夹权限
# chown mysql:mysql juwang –R
4修改my.cnfCentOS
replicate-do-db=test
log-slave-updates
修改my.cnfSuSe
server-id=3  ç千万别和其它机器的server-id号写重名了。
master-host=192.168.100.188
master-user=slave2
master-password=123456
master-port=3306
replicate-do-db=juwang
replicate-do-db=test
log-slave-updates
 
5验证连接MASTER
 
# mysql -h192.168.100.188 –uslave2 –p123456
mysql> show grants for slave1@192.168.100.39;
 
6SLAVE上设置同步
设置连接MASTER MASTER_LOG_FILE为主库的FileMASTER_LOG_POS为主库的Position
============================
mysql> CHANGE MASTER TO MASTER_HOST='192.168.100.188',MASTER_USER='slave',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000005',MASTER_LOG_POS=98;
============================
7启动SLAVE服务
mysql> slave start;
查看SLAVE状态
mysql> SHOW SLAVE STATUS\G;
其中 Slave_IO_Running Slave_SQL_Running 两列的值都为 "Yes",表明 Slave I/O SQL 线程都在正常运行。
到此主从库搭建成功。

在配置过程中出现:Slave_SQL_Running 的值都为 "No"
mysql> show slave status\G;
Slave_IO_Running: Yes
Slave_SQL_Running: No
Last_Errno: 1062
 
原因:
1.程序可能在slave上进行了写操作 。(我确定这样操作过。)
2.也可能是slave机器重起后,事务回滚造成的.
 
解决办法I
1.首先停掉Slave服务:slave stop
到主服务器上查看主机状态:
记录FilePosition对应的值。
3.slave服务器上执行手动同步:
mysql> show master status;
在从库机上操作如下:
注意:
/etc/init.d/mysql start SuSe中),应这样启动服务:/etc/init.d/mysql  --skip-slave-start
mysql> change master to
> master_host='master_ip',
> master_user='user',
> master_password='123456',
> master_port=3306,
> master_log_file='mysql-bin.000006',
> master_log_pos=98;
1 row in set (0.00 sec)
mysql> slave start;
1 row in set (0.00 sec)
 
再次查看slave状态发现:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
Seconds_Behind_Master: 0
解决办法II
mysql> slave stop;
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
mysql> slave start;
 
解决办法III
重新获取主库上的数据库相关物理文件,然后,再拷贝到从库的相应的位置。重复上述有关操作。
 
在启动从库机mysql服务器时出现了,启动mysqld_safe的时候遇到这个错误:Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't exist
data删除之后mysql_install_db --user=mysql就行了

摘自:http://sqlnet.blog.51cto.com/343343/102980

MYSQL 主库与从库的建立 (转)

MySQL 版本:4.1

环境介绍:主库 192.168.0.205 从库 192.168.0.206

1、主库创建/etc/my.cnf,修改[mysqld]里边的键值增加
server-id=1
log-bin=binlog_name

2、主库增加用户,用于从库读取主库日志。
grant replication slave,reload,super on *.* to 'slave'@'192.168.0.206' identified by '123456'

3、从库连接主库进行测试。
/opt/mysql/bin/mysql -u slave -p -h 192.168.0.205

4、停从库,修改从库/etc/my.cnf,增加选项:

[mysqld] 
server-id=2
master-host=192.168.0.205
master-user=slave
master-password=123456

5、启动从库,进行主从库数据同步

/opt/mysql/share/mysql/mysql start
/opt/mysql/bin/mysql -u root -p
mysql>load data from master;
说明:这一步也可以用数据库倒入或者直接目录考过来。

6、进行测试:

主库创建表,

mysql>create database sampdb; 
mysql>create table new (name char(20),phone char(20));
mysql>insert into new ('abc,'0532555555');

打开从库,察看:

/opt/mysql/bin/mysql -u root -p 
mysql>show database;
mysql
sampdb
test
mysql>use sampdb;
mysql>show tables;
new
说明主从数据库创建成功。

7、主从数据库相关命令:

slave stop; slave start ; 开始停止从数据库。
show slave status\G; 显示从库正读取哪一个主数据库二进制日志
purge master logs to 'binlog.000004'; 此命令非常小心,删除主数据库没用的二进制日志文件。如果误删除,那么从库就没有办法自动更新了。
change master; 从服务器上修改参数使用。

摘自:http://apps.hi.baidu.com/share/detail/23068157

2010年12月15日星期三

LBS的核心在于服务(转)

 LBS的核心在于服务

  LBS是基于位置的服务。很多想要投身到LBS大潮之中去的人或公司,都在研究,要如何利用好位置这个新加进来的技术。但是从语法上分析,基于位置的服务,其关键核心其实是服务,位置只是一种限定。

  当前流行的POI模式的LBS,也就是信息点服务。其核心实际上是一种将线下资源结合地理信息之后,整合上线的过程。把存放有信息的位置点,标记在地图上。当用户走到这附近的时候,根据距离远近,查阅附近的信息。

  对于发布信息和接受信息的双方来说,他们所需要的并不是这些信息,而是这些信息背后的服务。对于发布信息的人或机构来说,他们所发布的其实是广告。 而对于接收这些信息的人们来说,他们所需要的是一种咨询服务。从广告中提取信息,并为用户提供咨询服务,这就是POI提供的服务。通过咨询服务,吸引用户 去周围的商家,进行消费,这也是POI提供的服务。国内的POI应用,在服务上还不够完善,只是完成了信息的传递和推送,顾问和吸引消费的能力还不是很 强。但是,这些服务商已经迫不及待的开始通过餐厅定位、商家排序,以及帮助商家删除有害信息等方式,开始吸收现金了。

  现在很热的Check In模式,其本身是很难独立运作起来的。因为,Check in的结果,其实是告诉别人,我"到此一游"。通常做这件事情的人,想要告诉的是两种人,第一是自己的朋友;第二是到达此地的陌生人。当然,如果是自己的 朋友能够到达此地的话,那就更好了。

  但是喜欢四处去留下痕迹的人,毕竟不是很多,人类并不需要像某些动物那样通过随地小便来标记自己的领地。特别是在一片完全空白的领地里面(任何 Check In式的LBS应用,开始的时候都是一片空白),做这种标记实在是没什么意思啊。于是大部分Check in方式的应用都结合了POI系统。也就是说,通过在信息点签到,来得到一些好处。

  现在,大多数此类系统,为了能够快速的积累大量的用户和内容,对于签到限制得非常宽松。有些甚至可以允许我坐在办公室的电脑前,就到全世界任何 地方去签到。即使有些限制的,也只是能够拒绝在距离用户当前位置几公里范围之外的地方去签到,毕竟就像上文所说的那样,现在的LBS还存在很多技术缺陷。 签到限制太过宽松,就导致了签到的行为无法给POI上面那些提供服务的商家带来什么具体的收入。那么这些商家也自然就不会愿意将已经到手的利润分配给那些 不知所云的LBS服务商了。

  交友服务,在中国可能很难开展,由于没有经济利益的驱动(有了经济利益驱动,恐怕就更麻烦了),所以这种东西很难发展起来,比Check In系统更难积累用户。

  LBS的核心是服务,但是现在能够看到的那些LBS应用,其服务做得都不是那么让人满意。下面就让我们去分析一下,到底用户需要什么样的服务。LBS服务商又应该如何去满足这些需求,为用户提供服务呢?

  享用服务的实体

  在LBS中需要享受服务的实体,一共有三种。他们分别是商户、人和人们。下面,让我们来分析一下这些实体,以及他们需要什么样的服务。

  商家

  商家最需要的服务,就是将周围的人吸引到自己这里来消费。这些商家都是有着固定的位置,他们希望知道谁从身边经过了,希望知道这些人是不是能够到自己这里来消费,并且希望能够尽量多的人,到他的店里面去消费尽量多的服务。

  能够来看我的博客, 大多都应该进过电脑市场吧,现在的电脑市场里面到处游走着的都是拉生意的人。他们会拉住身边经过的每一个顾客,询问他们需要什么样的服务,如果这个顾客所 需要的服务,正好是自己所能够提供的,他们会很热心的把顾客拉到自己的柜台前。商家其实就是希望能够通过LBS服务,得到这样的效果。有些地方,甚至在移 动基站插播广告,向每一个进入这个移动基站覆盖范围内的手机用户发送广告短信。

  更深一层来说,那些提供服务的商铺,他们总有高峰时段和低谷时段。高峰时段通常是需要排队的,那么这些商铺,肯定希望消费者能够错峰出来消费,或者是尽量压缩在高峰时间消费相同服务所需要的时间。这已经不再是LBS的范畴了,以后可以再在其他文章里面阐述。

  最后,商家希望能够了解客户。哪些人经常在周围转悠,这些人都喜欢什么样的服务,他们在消费了一些服务之后,有什么感想。如何能够让这些人更多的到自己这里来消费?对于这方面的需求,目前的LBS服务商做得怎么样,还不得而知。

  LBS实际上是为一个很小区域服务的,但是现在的LBS服务商都在努力的像互联网企 业那样,为全世界服务,所以针对于每一个区域的服务,肯定就没法那么细致了。而为了搞到更多的在线用户,更多的点击,更多的POI信息,他们也不希望对用 户和区域进行过于精细的划分。本来用户就不多,再画上格子,那么分到每个格子里面的人,就越发少了。这是一个矛盾,因为只有将格子缩小,才能提供更加有针 对性的服务。

  现在的POI系统里面充斥着各种广告信息,而其最大作用就是使用户能够看到拐角后面的招牌。拐角之前的招牌,用肉眼就可以看到了,POI系统的 作用就在于,拐角之后的那些商铺付一些钱,然后系统告诉用户,拐角后面还有更好的。这对于商铺来说,其实是一把双刃剑,系统既能将拐角另一边的用户吸引过 来,也有可能会把已经站在店铺门口的用户吸引走。只有一点是肯定的,不论是拐角哪一边的商铺都要向POI系统缴费。这其实是非常不公平的。

  个人

  有些人是喜欢四处去以各种各样的形式去写"到此一游"的。比如我,我喜欢在旅行箱上贴标签。我坐飞机到任何地方,如果需要托运行李的话,机场就 会在我的行李箱上贴一个标签。再坐飞机,就再贴一个,逐渐积攒起来,就像很多勋章,标记着我走过的每一座城市。遗憾的是,后来机场的人再往上贴标签的时 候,因为害怕搬运工因为看错标签,导致行李装上错误的航班,而将以前的旧标签统统撕掉。实在是太遗憾了。这其实就是一种最原始的Check in系统。

  人是一种社会性的生物,所以他们希望能够得到身边其他人的认可,希望能够在闲暇的时候,和其他什么人去聊一聊。就像我上面所说过的那样,我喜欢 向和我一样出入机场的那些旅人,炫耀行李箱上的那些标记着一个个城市的标签。很多人都喜欢炫耀一些什么,只是方式和方法不尽相同。很多人非常八卦,他们希 望能够了解身边的人或事物。特别是在无聊的时候,他们希望能够知道身边的人是不是也像他们一样无聊,是不是能够有个什么人和他聊一聊。这就是那种基于地理 位置的交友系统应该满足的东西了。

  当一个人走到一个陌生地方的时候,他需要找到好吃的东西,好玩儿的东西。他所需要的其实并不是简单的了解身边的店铺信息。POI系统所提供的大多是一些赤裸裸的广告。来到陌生地点的用户,最需要的实际上应该是伴随式的导游服务,或者是咨询顾问式的服务。

  人群

  具有一定相似性的人们,就是这里所要描述的人群了。这些人并不一定会聚集在一起,但是他们互相之间希望能够得到一些对方的信息。即使是聚集在一 起的人群,其中很多人也是孤单寂寞的,他们想找些人聊一聊,但又有些顾虑。顾虑在于两个方面,第一:找不到有共同语言的人;第二:害怕被拒绝。那些基于地 理位置的SNS,要做的就是这样一件事情,进行配对和筛选。从而解决前面的两个顾虑。

  有些信息是我们希望了解的,比如我的朋友是不是来到了我所在的城市。我并不需要了解这位朋友具体住在哪家酒店,更不需要了解这位朋友是在旅店的 餐厅、客房或厕所里面。我只需要了解到我的朋友到了我的城市,那么就有机会去和他坐一坐、聊一聊。而对于我的朋友来说,他们也可以在要前往某个城市之前, 看看有谁在那里,然后提前准备一些礼物什么的。当我和朋友约好,要前去和他会合的时候,LBS系统就应该能够提供更加详细的地理位置信息。

  信息的流转

  LBS提供服务的过程其实就是信息流转的过程,将合适的信息发送给合适的人。或者让人能够找到他们所需要的信息。

  这两个过程的差异就在于,一个是主动的推送,一个则是自取。在现阶段,这两种方式都是非常普遍的。不同的应用模式,应该结合自己的需要,挑选其中的一种。这里面是不存在优劣之分的,关键在于是否合适。

  信息的过滤

  信息流转的第一步是信息的过滤。并不是什么信息都可以发送的,也不是任何信息都可以接收的。

  首先说发送信息的问题。商家肯定希望能够将尽可能多的信息推送到用户面前,但是又担心用户会感到讨厌。那么,就需要挑选更精要,更有吸引力的信息。这就存在了一个过滤的问题。

  人在LBS系统中,如果无时无刻都把自己的精确坐标公布到网上,供全社会监督,这种情况光是想一想就会感到毛骨悚然的。但是,我们又希望能够向 其他人,熟人朋友或陌生人去宣告自己的到来。就像我以前做过的那样,在行李箱上贴机场托运标签那样。大部分人在大部分时间,并不会介意别人了解到他们身处 哪一个城市,或到达过哪一些城市。甚至会希望路过好友身边的时候,能够打个招呼。毕竟像古人那样乘兴而来败兴而归的故事,并不是经常发生的。所以个人的地 理位置信息,对于不同的人,不同的地点,不同的时间,不同的场景来说,其提供的精度是绝对不一样的。大多数时候,对于大多数地点,以及大多数查询者来说, 只是提供一个精确到城市的坐标就够了。但是,有的时候,特别是对于一些朋友来说,就可以提供更为精确的坐标。

  这里有一个不能算是故事的故事来说明一下这个问题。在国外,两个中国人遇到一起,那么他们就是老乡了,因为他们来自同一个国家。但是,同样的问 题在国内发生,在一个陌生的城市,只有两个人来自同一个省,才能算是老乡。以此类推,到了一个省里面,只有来自同一个地区的人才是老乡;到了地区,老乡则 必须是从同一个县出来的;进了县城,老乡指的是同一个乡的;到了乡里,老乡就是从同一个村里出来的人。

  很多人攀老乡的时候,也都是这么做的,首先问:你是哪个省的?如果和自己来自同一个省,再问对方是来自哪一个地市、县、乡、村。当然,如果哪一个层级出现了差异,则会停下来,然后开始计算在这一个级别的行政区划之间的距离和方向。

  比如两个人在攀老乡,先确定大家的口音相近,那才能开始攀老乡。通常会先说:我听你说话像是山东(或者是其他的什么省)的吧。并通过这个过程展 示一下自己的纯正乡音,然后再问,我是临沂(市)的,你呢?对方可能回答也是临沂的;然后再说:我是苍山(县)的,这个时候对方的回答可能就是,我是沂南 (县)的,离你们那里还挺远的呢。

  从这个过程中可以看出,这种沟通实在不断的尝试中逐步深入、逐步精确的。在确定了可以和对方精确到一个什么样的程度之后,信息可以精确到一个什 么样的程度就可以确认了。上面两个老乡之间可能会探讨他们所在的两个县之间的方向和距离,但是他们绝不会去研究两个人所处的村子是一个什么样的关系。不 过,这并不妨碍大家探讨一下村里寡妇门前的是是非非。这个时候,如果一个人说,我去过你们县的,那么话题才会继续围绕着他去过的那个位置再细化。

  这个攀老乡的故事,就是现在的LBS+SNS的原始模型,遗憾的是能够将这个东西研究明白并应用起来的人并不多。这中间的关键在于信息过滤的颗粒度,如果两个陌生人凑到一起就开始互相说我是哪个村的,那估计天下就没有老乡遇老乡,两眼泪汪汪的故事了。

  地理位置信息的标记和隐私的保护

  前面所说到的信息的过滤方式,就是信息发送或广播过程中,进行有效的隐私保护的方式。对地理位置信息的精细程度进行分级,是最简单的方法。对于 绝大多数人来说,当前的位置被标明为:在地球上,应该不算是泄漏个人隐私吧。那么进一步说,标明在哪个国家应该也问题不大,甚至我还希望能够将所有我去过 的国家都标记出来。绝大部分时间,我也不介意其他人是不是知道我到底是在上班,还是在家。单位的地址也是公开的。在家的话,别人只需要知道我在家就好了, 不需要知道我家的具体位置了,了解一个大概位置就好了。这样的话,有人走到我家附近,他不会直接到我家来敲门,但是可以给我打个电话,约我出去吃东西。这 就是一个度的把握了。如果我在单位上班,或者是在一个公共场所里面,那么就可以给出更详细的位置坐标。如果我需要和其他人约好了一起到什么地方汇合,那么 肯定就需要直接将最详尽的位置发过去。

  对于得不到太多有价值服务的用户来说,强制他们去Check in实在是有些强人所难。

摘自:http://news.iresearch.cn/0200/20101116/127866.shtml

2010年12月13日星期一

PHP中$_SERVER的详细参数与说明(转)

$_SERVER['PHP_SELF'] #当前正在执行脚本的文件名,与 document root相关。
$_SERVER['argv'] #传递给该脚本的参数。
$_SERVER['argc'] #包含传递给程序的命令行参数的个数(如果运行在命令行模式)。
$_SERVER['GATEWAY_INTERFACE'] #服务器使用的 CGI 规范的版本。例如,"CGI/1.1"。
$_SERVER['SERVER_NAME'] #当前运行脚本所在服务器主机的名称。
$_SERVER['SERVER_SOFTWARE'] #服务器标识的字串,在响应请求时的头部中给出。
$_SERVER['SERVER_PROTOCOL'] #请求页面时通信协议的名称和版本。例如,"HTTP/1.0"。
$_SERVER['REQUEST_METHOD'] #访问页面时的请求方法。例如:"GET"、"HEAD","POST","PUT"。
$_SERVER['QUERY_STRING'] #查询(query)的字符串。
$_SERVER['DOCUMENT_ROOT'] #当前运行脚本所在的文档根目录。在服务器配置文件中定义。
$_SERVER['HTTP_ACCEPT'] #当前请求的 Accept: 头部的内容。
$_SERVER['HTTP_ACCEPT_CHARSET'] #当前请求的 Accept-Charset: 头部的内容。例如:"iso-8859-1,*,utf-8"。
$_SERVER['HTTP_ACCEPT_ENCODING'] #当前请求的 Accept-Encoding: 头部的内容。例如:"gzip"。
$_SERVER['HTTP_ACCEPT_LANGUAGE']#当前请求的 Accept-Language: 头部的内容。例如:"en"。
$_SERVER['HTTP_CONNECTION'] #当前请求的 Connection: 头部的内容。例如:"Keep-Alive"。
$_SERVER['HTTP_HOST'] #当前请求的 Host: 头部的内容。
$_SERVER['HTTP_REFERER'] #链接到当前页面的前一页面的 URL 地址。
$_SERVER['HTTP_USER_AGENT'] #当前请求的 User_Agent: 头部的内容。
$_SERVER['HTTPS'] ― 如果通过https访问,则被设为一个非空的值(on),否则返回off
$_SERVER['REMOTE_ADDR'] #正在浏览当前页面用户的 IP 地址。
$_SERVER['REMOTE_HOST'] #正在浏览当前页面用户的主机名。
$_SERVER['REMOTE_PORT'] #用户连接到服务器时所使用的端口。
$_SERVER['SCRIPT_FILENAME'] #当前执行脚本的绝对路径名。
$_SERVER['SERVER_ADMIN'] #管理员信息
$_SERVER['SERVER_PORT'] #服务器所使用的端口
$_SERVER['SERVER_SIGNATURE'] #包含服务器版本和虚拟主机名的字符串。
$_SERVER['PATH_TRANSLATED'] #当前脚本所在文件系统(不是文档根目录)的基本路径。
$_SERVER['SCRIPT_NAME'] #包含当前脚本的路径。这在页面需要指向自己时非常有用。
$_SERVER['REQUEST_URI'] #访问此页面所需的 URI。例如,"/index.html"。
$_SERVER['PHP_AUTH_USER'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的用户名。
$_SERVER['PHP_AUTH_PW'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的密码。
$_SERVER['AUTH_TYPE'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是认证的类型。

摘自:http://www.chinaz.com/Program/PHP/01291053F2010.html

Thinkphp常用配置(转)

摘自:http://hi.baidu.com/a00514/blog/item/6485ff5509849b58574e002f.html

CHECK_FILE_CASE -- windows环境下面的严格检查大小写。

    /* 项目设定 */
    'APP_DEBUG'    => false, // 是否开启调试模式
    'APP_DOMAIN_DEPLOY'     => false,   // 是否使用独立域名部署项目
    'APP_PLUGIN_ON'         => false,   // 是否开启插件机制
    'APP_FILE_CASE'         => false,   // 是否检查文件的大小写 对Windows平台有效
    'APP_GROUP_DEPR'        => '.',     // 模块分组之间的分割符
    'APP_GROUP_LIST'        => '',      // 项目分组设定,多个组之间用逗号分隔,例如'Home,Admin'
    'APP_AUTOLOAD_REG'      => false,   // 是否开启SPL_AUTOLOAD_REGISTER
    'APP_AUTOLOAD_PATH'     => 'Think.Util.',// __autoLoad 机制额外检测路径设置,注意搜索顺序
    'APP_CONFIG_LIST'       => array('taglibs','routes','tags','htmls','modules','actions'),// 项目额外需要加载的配置列表,默认包括:taglibs(标签库定义),routes(路由定义),tags(标签定义),(htmls)静态缓存定义, modules(扩展模块),actions(扩展操作)

    /* Cookie设置 */
    'COOKIE_EXPIRE'         => 3600,    // Coodie有效期
    'COOKIE_DOMAIN'         => '',      // Cookie有效域名
    'COOKIE_PATH'           => '/',     // Cookie路径
    'COOKIE_PREFIX'         => '',      // Cookie前缀 避免冲突

    /* 默认设定 */
    'DEFAULT_APP'           => '@',     // 默认项目名称,@表示当前项目
    'DEFAULT_GROUP'         => 'Home', // 默认分组
    'DEFAULT_MODULE'        => 'Index', // 默认模块名称
    'DEFAULT_ACTION'        => 'index', // 默认操作名称
    'DEFAULT_CHARSET'       => 'utf-8', // 默认输出编码
    'DEFAULT_TIMEZONE'      => 'PRC', // 默认时区
    'DEFAULT_AJAX_RETURN'   => 'JSON', // 默认AJAX 数据返回格式,可选JSON XML ...
    'DEFAULT_THEME'    => 'default', // 默认模板主题名称
    'DEFAULT_LANG'          => 'zh-cn', // 默认语言

    /* 数据库设置 */
    'DB_TYPE'               => 'mysql',     // 数据库类型
     'DB_HOST'               => 'localhost', // 服务器地址
     'DB_NAME'               => '',          // 数据库名
     'DB_USER'               => 'root',      // 用户名
     'DB_PWD'                => '',          // 密码
     'DB_PORT'               => 3306,        // 端口
     'DB_PREFIX'             => 'think_',    // 数据库表前缀
   'DB_SUFFIX'             => '',          // 数据库表后缀
    'DB_FIELDTYPE_CHECK'    => false,       // 是否进行字段类型检查
    'DB_FIELDS_CACHE'       => true,        // 启用字段缓存
    'DB_CHARSET'            => 'utf8',      // 数据库编码默认采用utf8
    'DB_DEPLOY_TYPE'        => 0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
    'DB_RW_SEPARATE'        => false,       // 数据库读写是否分离 主从式有效

    /* 数据缓存设置 */
    'DATA_CACHE_TIME' => -1,      // 数据缓存有效期
    'DATA_CACHE_COMPRESS'   => false,   // 数据缓存是否压缩缓存
    'DATA_CACHE_CHECK' => false,   // 数据缓存是否校验缓存
    'DATA_CACHE_TYPE' => 'File', // 数据缓存类型,支持:File|Db|Apc|Memcache|Shmop|Sqlite| Xcache|Apachenote|Eaccelerator
    'DATA_CACHE_PATH'       => TEMP_PATH,// 缓存路径设置 (仅对File方式缓存有效)
    'DATA_CACHE_SUBDIR' => false,    // 使用子目录缓存 (自动根据缓存标识的哈希创建子目录)
    'DATA_PATH_LEVEL'       => 1,        // 子目录缓存级别

    /* 错误设置 */
    'ERROR_MESSAGE' => '您浏览的页面暂时发生了错误!请稍后再试~',//错误显示信息,非调试模式有效
    'ERROR_PAGE'    => '', // 错误定向页面

    /* 静态缓存设置 */
    'HTML_CACHE_ON'   => false,   // 默认关闭静态缓存
    'HTML_CACHE_TIME' => 60,      // 静态缓存有效期
    'HTML_READ_TYPE'        => 0,       // 静态缓存读取方式 0 readfile 1 redirect
    'HTML_FILE_SUFFIX'      => '.shtml',// 默认静态文件后缀

    /* 语言设置 */
    'LANG_SWITCH_ON'        => false,   // 默认关闭多语言包功能
    'LANG_AUTO_DETECT'      => true,   // 自动侦测语言 开启多语言功能后有效

    /* 日志设置 */
    'LOG_RECORD'            => false,   // 默认不记录日志
    'LOG_FILE_SIZE'         => 2097152, // 日志文件大小限制
    'LOG_RECORD_LEVEL'      => array('EMERG','ALERT','CRIT','ERR'),// 允许记录的日志级别

    /* 分页设置 */
   'PAGE_ROLLPAGE'         => 5,      // 分页显示页数
   'PAGE_LISTROWS'         => 20,     // 分页每页显示记录数

    /* SESSION设置 */
    'SESSION_AUTO_START'    => true,    // 是否自动开启Session
    // 内置SESSION类可用参数
    //'SESSION_NAME'          => '',      // Session名称
    //'SESSION_PATH'          => '',      // Session保存路径
    //'SESSION_CALLBACK'      => '',      // Session 对象反序列化时候的回调函数

    /* 运行时间设置 */
    'SHOW_RUN_TIME'   => false,   // 运行时间显示
    'SHOW_ADV_TIME'   => false,   // 显示详细的运行时间
    'SHOW_DB_TIMES'   => false,   // 显示数据库查询和写入次数
    'SHOW_CACHE_TIMES' => false,   // 显示缓存操作次数
    'SHOW_USE_MEM'   => false,   // 显示内存开销
    'SHOW_PAGE_TRACE' => false,   // 显示页面Trace信息 由Trace文件定义和Action操作赋值
    'SHOW_ERROR_MSG'        => true,    // 显示错误信息

    /* 模板引擎设置 */
    'TMPL_ENGINE_TYPE' => 'Think',     // 默认模板引擎 以下设置仅对使用Think模板引擎有效
    'TMPL_DETECT_THEME'     => false,       // 自动侦测模板主题
    'TMPL_TEMPLATE_SUFFIX' => '.html',     // 默认模板文件后缀
    'TMPL_CACHFILE_SUFFIX' => '.php',      // 默认模板缓存后缀
    'TMPL_DENY_FUNC_LIST' => 'echo,exit', // 模板引擎禁用函数
    'TMPL_PARSE_STRING'     => '',          // 模板引擎要自动替换的字符串,必须是数组形式。
    'TMPL_L_DELIM'          => '{',   // 模板引擎普通标签开始标记
    'TMPL_R_DELIM'          => '}',   // 模板引擎普通标签结束标记
    'TMPL_VAR_IDENTIFY'     => 'array',     // 模板变量识别。留空自动判断,参数为'obj'则表示对象
    'TMPL_STRIP_SPACE'      => false,       // 是否去除模板文件里面的html空格与换行
    'TMPL_CACHE_ON'   => true,        // 是否开启模板编译缓存,设为false则每次都会重新编译
    'TMPL_CACHE_TIME' => -1,         // 模板缓存有效期 -1 为永久,(以数字为值,单位:秒)
    'TMPL_ACTION_ERROR'     => 'Public:success', // 默认错误跳转对应的模板文件
    'TMPL_ACTION_SUCCESS'   => 'Public:success', // 默认成功跳转对应的模板文件
    'TMPL_TRACE_FILE'       => THINK_PATH.'/Tpl/PageTrace.tpl.php',     // 页面Trace的模板文件
    'TMPL_EXCEPTION_FILE'   => THINK_PATH.'/Tpl/ThinkException.tpl.php',// 异常页面的模板文件
    'TMPL_FILE_DEPR'=>'/', //模板文件MODULE_NAME与ACTION_NAME之间的分割符,只对项目分组部署有效
    // Think模板引擎标签库相关设定
    'TAGLIB_BEGIN'          => '<', // 标签库标签开始标记
    'TAGLIB_END'            => '>', // 标签库标签结束标记
    'TAGLIB_LOAD'           => true, // 是否使用内置标签库之外的其它标签库,默认自动检测
    'TAGLIB_BUILD_IN'       => 'cx', // 内置标签库名称(标签使用不必指定标签库名称),以逗号分隔
    'TAGLIB_PRE_LOAD'       => '',   // 需要额外加载的标签库(须指定标签库名称),多个以逗号分隔
    'TAG_NESTED_LEVEL' => 3,    // 标签嵌套级别
    'TAG_EXTEND_PARSE'      => '',   // 指定对普通标签进行扩展定义和解析的函数名称。

    /* 表单令牌验证 */
    'TOKEN_ON'                    =>   true,     // 开启令牌验证
    'TOKEN_NAME'                =>   '__hash__',    // 令牌验证的表单隐藏字段名称
    'TOKEN_TYPE'                 =>    'md5',   // 令牌验证哈希规则

    /* URL设置 */
'URL_CASE_INSENSITIVE' => false,   // URL地址是否不区分大小写
    'URL_ROUTER_ON'         => false,   // 是否开启URL路由
    'URL_DISPATCH_ON'       => true, // 是否启用Dispatcher
    'URL_MODEL'      => 1,       // URL访问模式,可选参数0、1、2、3,代表以下四种模式:
    // 0 (普通模式); 1 (PATHINFO 模式); 2 (REWRITE 模式); 3 (兼容模式) 当URL_DISPATCH_ON开启后有效; 默认为PATHINFO 模式,提供最好的用户体验和SEO支持
    'URL_PATHINFO_MODEL'    => 2,       // PATHINFO 模式,使用数字1、2、3代表以下三种模式:
    // 1 普通模式(参数没有顺序,例如/m/module/a/action/id/1);
    // 2 智能模式(系统默认使用的模式,可自动识别模块和操作/module/action/id/1/ 或者 /module,action,id,1/...);
    // 3 兼容模式(通过一个GET变量将PATHINFO传递给dispather,默认为s index.php?s=/module/action/id/1)
    'URL_PATHINFO_DEPR'     => '/', // PATHINFO模式下,各参数之间的分割符号
    'URL_HTML_SUFFIX'       => '', // URL伪静态后缀设置

    /* 系统变量名称设置 */
    'VAR_GROUP'             => 'g',     // 默认分组获取变量
    'VAR_MODULE'            => 'm', // 默认模块获取变量
    'VAR_ACTION'            => 'a', // 默认操作获取变量
    'VAR_ROUTER'            => 'r',     // 默认路由获取变量
    'VAR_PAGE'              => 'p', // 默认分页跳转变量
    'VAR_TEMPLATE'          => 't', // 默认模板切换变量
'VAR_LANGUAGE'          => 'l', // 默认语言切换变量
    'VAR_AJAX_SUBMIT'       => 'ajax', // 默认的AJAX提交变量
    'VAR_PATHINFO'          => 's', // PATHINFO 兼容模式获取变量例如 ?s=/module/action/id/1 后面的参数取决于URL_PATHINFO_MODEL 和 URL_PATHINFO_DEPR