swoole 初探

需要了解知识点

 

1、网络通信,异步,同步

Tcp:传输控制协议

IP:互联网协议

 

2、socket,什么是socket

两台机器想要通信必须遵守tcp/ip协议,udp属于其中一种

1)指定对方地址,

2)打开一个和对方的连接

3)把socket当成普通文件往里写数据

4)要是发现socket里又数据就读出来,必然是对方发送过来的

3、什么是websocket

网页游戏应用,

http协议缺陷通信只能又客户端发起,无法主动推送。不请求则不返回数据。

websocket

h5

socket = new WebSocket(“ws:20.20.0.23:9596”);

socket.onopen();

4、swoole

一个标准的PHP扩展,异步、并行、高效,纯c语言编写

PHP能快速创建资源,释放资源,支持多进程单不支持多线程。

环境 ubuntu14.04 PHP7 mysql

mkdir default

git clone https://github.com/swoole/swoole-src.git

apt-get install php-dev

切换到swoolle

app接口设计之token的php实现

1、首先说一句什么是接口:接口简单来说就是服务器端用来返回给其他程序或者客户端数据的桥梁

2、接口的作用:根据固定参数返回固定数据,比如客户端传a=1,那么服务器端返回a的姓名,客户端传a=2,服务器端返回a的性别,而不会返回其他数据。

3、signature签名的作用:保证接口与数据的安全

4、token的作用:和PC登陆的session一样,作为用户进入的唯一票据

例如:app与服务器端的接口、java与php之间不同程序的接口,这些接口一般通过json格式传输数据

所以为了保证移动端和服务端数据传输相对安全,需要对接口进行加密传输

1、token的设计目的:
因为APP端没有和PC端一样的session机制,所以无法判断用户是否登陆,以及无法保持用户状态,所以就需要一种机制来实现session,这就是token的作用,token是用户登陆的唯一票据,只要APP传来的token和服务器端一致,就能证明你已经登陆(就和你去看电影一样,需要买票,拿着票就能进了)

2、token设计时的种类:
(1)第三方登陆型:这种token形如微信的access_token,设计原理是按照OAuth2.0来的,其特点是定时刷新(比如两小时刷新),目的是因为数据源将登陆权限赋予第三方服务器时必须要控制其有效期和权限,要不然第三方服务器可以不经过用户同意,无限期从数据源服务器获取用户任意数据

(2)APP自用登陆型:这种token就是一般的APP用的token,因为不经过第三方,而是用户直接取数据源服务器数据,所以设计比较随意,只需要保证其token的唯一性就行

3、APP自用登陆型token实现步骤:
(1)数据库用户表添加token字段和time_out这个token过期时间字段
(2)用户登陆时(注册时自动登陆也需要)生成一个token和过期时间存入表中
(3)在其他接口调用前,判断token是否正确,正确则继续,错误则让用户重新登陆

4、APP自用登陆型token实现代码(公司自用框架及逻辑,主要看逻辑,不要直接复制代码):

1//下面是用户登陆时把token插入数据库的代码
$logininfo['token'] = appuser::settoken();
$time_out = strtotime("+7 days");
db::setByPk('u_adver', array('token1' => $logininfo['token'], 'time_out' => $time_out), $logininfo['id']);


(2//下面是生成token方法代码
    public static function settoken()
    {
        $str = md5(uniqid(md5(microtime(true)),true));  //生成一个不会重复的字符串
        $str = sha1($str);  //加密
        return $str;
    }

(3//下面是每个接口都必须调用的token验证代码,验证具体实现是在(4)
$args['token'] = $_POST['token'];
$tokencheck = appuser::checktokens($args['token'], 'u_adver');
        if ($tokencheck != 90001)
        {
            $res['msg_code'] = $tokencheck;
            v_json($res);
        }


(4//token验证方法,db::是数据库操作类,这里设置是token如果七天没被调用则需要重新登陆(也就是说用户7天没有操作APP则需要重新登陆),如果某个接口被调用,则会重新刷新过期时间
    public static function checktokens($token, $table)
    {
        $res = db::getOneForFields($table, 'time_out', 'token1 = ?', array($token));
        if (!empty($res))
        {
            if (time() - $res['time_out'] > 0) 
            {
                return 90003;  //token长时间未使用而过期,需重新登陆
            }
            $new_time_out = time() + 604800;//604800是七天
            if (db::setWhere($table, array('time_out' => $new_time_out), 'token1 = ?', array($token)))
            {
                return 90001;  //token验证成功,time_out刷新成功,可以获取接口信息
            }
        }
        return 90002;  //token错误验证失败
    }

PHP实现一致性hash

 

随着memcache、Redis以及其它一些内存K/V数据库的流行,一致性哈希也越来越被开发者所了解。因为这些内存K/V数据库大多不提供分布式支持(本文以redis为例),所以如果要提供多台redis server来提供服务的话,就需要解决如何将数据分散到redis server,并且在增减redis server时如何最大化的不令数据重新分布,这将是本文讨论的范畴。
取模算法
取模运算通常用于得到某个半开区间内的值:m % n = v,其中n不为0,值v的半开区间为:[0, n)。取模运算的算法很简单:有正整数k,并令k使得k和n的乘积最大但不超过m,则v的值为:m – kn。比如1 % 5,令k = 0,则k * 5的乘积最大并不超过1,故结果v = 1 – 0 * 5 = 1。
我们在分表时也会用到取模运算。如一个表要划分三个表,则可对3进行取模,因为结果总是在[0, 3)之内,也就是取值为:0、1、2。
但是对于应用到redis上,这种方式就不行了,因为太容易冲突了。
哈希(Hash)
Hash,一般翻译做“散列”,也有直接音译为”哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。
简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
目前普遍采用的哈希算法是time33,又称DJBX33A (Daniel J. Bernstein, Times 33 with Addition)。这个算法被广泛运用于多个软件项目,Apache、Perl和Berkeley DB等。对于字符串而言这是目前所知道的最好的哈希算法,原因在于该算法的速度非常快,而且分类非常好(冲突小,分布均匀)。
PHP内核就采用了time33算法来实现HashTable,来看下time33的定义:
  1. hash(i) = hash(i-1) * 33 + str[i]
有了定义就容易实现了:
  1. <?php
  2. function myHash($str) {
  3.     // hash(i) = hash(i-1) * 33 + str[i]
  4.     $hash = 0;
  5.     $s    = md5($str);
  6.     $seed = 5;
  7.     $len  = 32;
  8.     for ($i = 0; $i < $len; $i++) {
  9.         // (hash << 5) + hash 相当于 hash * 33
  10.         //$hash = sprintf(“%u”, $hash * 33) + ord($s{$i});
  11.         //$hash = ($hash * 33 + ord($s{$i})) & 0x7FFFFFFF;
  12.         $hash = ($hash << $seed) + $hash + ord($s{$i});
  13.     }
  14.     return $hash & 0x7FFFFFFF;
  15. }
  16. echo myHash(“test”); //输出 786776064
利用取模实现
现在有2台redis server,所以需要计算键的hash并跟2取模。比如有键key1和key2,代码如下:
  1. <?php
  2. function myHash($str) {
  3.     // hash(i) = hash(i-1) * 33 + str[i]
  4.     $hash = 0;
  5.     $s    = md5($str);
  6.     $seed = 5;
  7.     $len  = 32;
  8.     for ($i = 0; $i < $len; $i++) {
  9.         // (hash << 5) + hash 相当于 hash * 33
  10.         //$hash = sprintf(“%u”, $hash * 33) + ord($s{$i});
  11.         //$hash = ($hash * 33 + ord($s{$i})) & 0x7FFFFFFF;
  12.         $hash = ($hash << $seed) + $hash + ord($s{$i});
  13.     }
  14.     return $hash & 0x7FFFFFFF;
  15. }
  16. echo “key1: ” . (myHash(“key1”) % 2) . “\n”;
  17. echo “key2: ” . (myHash(“key2”) % 2) . “\n”;
对于key1和key2来说,同时存储到一台服务器上,这似乎没什么问题,但正因为key1和key2是始终存储到这台服务器上,一旦这台服务器下线了,则这台服务器上的数据全部要重新定位到另一台服务器。对于增加服务器也是类似的情况。而且重新hash(之前跟2进行hash,现在是跟3进行hash)之后,结果就变掉了,导致大多数数据需要重新定位到redis server。
在服务器数量不变的时候,这种方式也是能很好的工作的。
一致性哈希
由于hash算法结果一般为unsigned int型,因此对于hash函数的结果应该均匀分布在[0,2^32-1]区间,如果我们把一个圆环用2^32 个点来进行均匀切割,首先按照hash(key)函数算出服务器(节点)的哈希值, 并将其分布到0~2^32的圆环上。
用同样的hash(key)函数求出需要存储数据的键的哈希值,并映射到圆环上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器(节点)上。如图所示:
key1、key2、key3和server1、server2通过hash都能在这个圆环上找到自己的位置,并且通过顺时针的方式来将key定位到server。按上图来说,key1和key2存储到server1,而key3存储到server2。如果新增一台server,hash后在key1和key2之间,则只会影响key1(key1将会存储在新增的server上),其它不变。
上图这个圆环相当于是一个排好序的数组,我们先通过代码来看下key1、key2、key3、server1、server2的hash值,然后再作分析:
  1. <?php
  2. function myHash($str) {
  3.     // hash(i) = hash(i-1) * 33 + str[i]
  4.     $hash = 0;
  5.     $s    = md5($str);
  6.     $seed = 5;
  7.     $len  = 32;
  8.     for ($i = 0; $i < $len; $i++) {
  9.         // (hash << 5) + hash 相当于 hash * 33
  10.         //$hash = sprintf(“%u”, $hash * 33) + ord($s{$i});
  11.         //$hash = ($hash * 33 + ord($s{$i})) & 0x7FFFFFFF;
  12.         $hash = ($hash << $seed) + $hash + ord($s{$i});
  13.     }
  14.     return $hash & 0x7FFFFFFF;
  15. }
  16. //echo myHash(“却道天凉好个秋~”);
  17. echo “key1: ” . myHash(“key1”) . “\n”;
  18. echo “key2: ” . myHash(“key2”) . “\n”;
  19. echo “key3: ” . myHash(“key3”) . “\n”;
  20. echo “serv1: ” . myHash(“server1”) . “\n”;
  21. echo “serv2: ” . myHash(“server2”) . “\n”;
现在我们根据hash值重新画一张在圆环上的分布图,如下所示:
key1、key2和key3都存储到了server1上,这是正确的,因为是按顺时针来定位。我们想像一下,所有的server其实就是一个排好序的数组(降序):[server2, server1],然后通过计算key的hash值来得到处于哪个server上。来分析下定位过程:如果只有一台server,即[server],则直接定位,取数组的第一个元素。如果有多台server,则要先看通过key计算的hash值是否落在[server2, server1, …]这个区间上,这个直接跟数组的第一个元素和最后一个元素比较就知道了。然后就可以通过查找来定位了。
利用一致性哈希实现
下面是一个实现一致性哈希的例子,仅仅实现了addServer和find。其实对于remove的实现跟addServer是类似的。代码如下:
  1. <?php
  2. function myHash($str) {
  3.     // hash(i) = hash(i-1) * 33 + str[i]
  4.     $hash = 0;
  5.     $s    = md5($str);
  6.     $seed = 5;
  7.     $len  = 32;
  8.     for ($i = 0; $i < $len; $i++) {
  9.         // (hash << 5) + hash 相当于 hash * 33
  10.         //$hash = sprintf(“%u”, $hash * 33) + ord($s{$i});
  11.         //$hash = ($hash * 33 + ord($s{$i})) & 0x7FFFFFFF;
  12.         $hash = ($hash << $seed) + $hash + ord($s{$i});
  13.     }
  14.     return $hash & 0x7FFFFFFF;
  15. }
  16. class ConsistentHash {
  17.     // server列表
  18.     private $_server_list = array();
  19.     // 延迟排序,因为可能会执行多次addServer
  20.     private $_layze_sorted = FALSE;
  21.     public function addServer($server) {
  22.         $hash = myHash($server);
  23.         $this->_layze_sorted = FALSE;
  24.         if (!isset($this->_server_list[$hash])) {
  25.             $this->_server_list[$hash] = $server;
  26.         }
  27.         return $this;
  28.     }
  29.     public function find($key) {
  30.         // 排序
  31.         if (!$this->_layze_sorted) {
  32.             asort($this->_server_list);
  33.             $this->_layze_sorted = TRUE;
  34.         }
  35.         $hash = myHash($key);
  36.         $len  = sizeof($this->_server_list);
  37.         if ($len == 0) {
  38.             return FALSE;
  39.         }
  40.         $keys   = array_keys($this->_server_list);
  41.         $values = array_values($this->_server_list);
  42.         // 如果不在区间内,则返回最后一个server
  43.         if ($hash <= $keys[0] || $hash >= $keys[$len – 1]) {
  44.             return $values[$len – 1];
  45.         }
  46.         foreach ($keys as $key=>$pos) {
  47.             $next_pos = NULL;
  48.             if (isset($keys[$key + 1]))
  49.             {
  50.                 $next_pos = $keys[$key + 1];
  51.             }
  52.             if (is_null($next_pos)) {
  53.                 return $values[$key];
  54.             }
  55.             // 区间判断
  56.             if ($hash >= $pos && $hash <= $next_pos) {
  57.                 return $values[$key];
  58.             }
  59.         }
  60.     }
  61. }
  62. $consisHash = new ConsistentHash();
  63. $consisHash->addServer(“serv1”)->addServer(“serv2”)->addServer(“server3”);
  64. echo “key1 at ” . $consisHash->find(“key1”) . “.\n”;
  65. echo “key2 at ” . $consisHash->find(“key2”) . “.\n”;
  66. echo “key3 at ” . $consisHash->find(“key3”) . “.\n”;
  1. $ php -f test.php
  2. key1 at server3.
  3. key2 at server3.
  4. key3 at serv2.

VMware Ubuntu下找不到共享文件的解决方法

VMware Ubuntu下找不到共享文件的解决方法

我碰到了与http://ask.csdn.net/questions/163546#answer_133071相同的问题。

问题描述:
VMware无法通过mount挂载共享文件夹

为了要把主机(win7)的文件夹共享到虚拟机(ubuntu14)
VMtools已经装好,并开启了总是共享文件夹,设置好了共享目录

但是在/mnt/hgfs目录下是空的,按照网上办法执行
    sudo mount -t vmhgfs .host:/ /mnt/hgfs
出现错误:
    Error: cannot mount filesystem: No such device

网上的办法找了一圈都试过了,比如很多人说有用的
    sudo apt-get install open-vm-dkms
已经装上了,提示是最新版本
然后重启,还是提示Error: cannot mount filesystem: No such device
用vmware-hgfsclient命令也确实能看到设置的共享目录

求助高手!!!

 

在另一个帖子里找到了解决方法:
http://bbs.csdn.net/topics/390606349?page=1#post-400343840

Step 1:sudo /etc/vmware-tools/services.sh restart

Stopping VMware Tools services in the virtual machine:
VMware User Agent (vmware-user):                                    done
Unmounting HGFS shares:                                             done
Guest filesystem driver:                                            done
Checking acpi hot plug                                              done
Starting VMware Tools services in the virtual machine:
Switching to guest configuration:                                   done
   Guest filesystem driver:                                             failed
Mounting HGFS shares:                                              failed
在这儿出现了两个failed。

Step 2:sudo /usr/bin/vmware-config-tools.pl

VMware automatic kernel modules enables automatic building and installation of
VMware kernel modules at boot that are not already present. This feature can
be enabled/disabled by re-running vmware-config-tools.pl.

Would you like to enable VMware automatic kernel modules?
[no] yes

其中这个地方我选择了yes。

Step 3:sudo mount  -t  vmhgfs  .host:/   /mnt/hgfs

 

问题解决。

php5 php7 nginx 多站点,PHP多版本共存

https://blog.csdn.net/zhousmq/article/details/77765451

https://www.cnblogs.com/phpzhou/p/6288762.html

使用ppa增加源:
$ sudo apt-get install python-software-properties
$ sudo add-apt-repository ppa:ondrej/php
$ sudo apt-get update
$ sudo apt-get install -y php7.0 php7.0-mysql php7.0-curl php7.0-json php7.0-cgi

然后可以查看php版本:
php -v


apt-get install php7.0-fpm

phpstorm常用快捷键

 https://segmentfault.com/a/1190000004225643

查询快捷键


CTRL+N 查找类


Ctrl+Shift+J快捷键,所有多余的字符(空格,引号和加号)被去掉了


CTRL+SHIFT+N 全局搜索文件 ,优先文件名匹配的文件

CTRL+SHIFT+ALT+N 查找php类名/变量名 ,js方法名/变量名, css 选择器


CIRL+B 找变量的来源,跳到变量申明处 (CTRL+ 鼠标单击 也可以)


CTRL+ALT+B 找到继承该接口或者父级 的所有子类, 统计所有子类个数


CTRL+SHIFT+B 找变量的类 (不太懂欢迎评价)


CTRL+G 定位行,跳转行


CTRL+F 在当前窗口查找文本


CTRL+SHIFT+F 在指定路径查找文本字符


CTRL+R 当前窗口替换文本


CTRL+SHIFT+R 在指定路径替换文本


CTRL+E 最近打开的文件

自动代码


CTRL+J 自动代码提示,自动补全


也可以直接输入对应的简拼,按下tab键即可(类似linux命令补全)


ALT+回车 导入包,自动修正

  • CTRL+ALT+L 格式化代码
  • CTRL+ALT+I 自动缩进
  • CTRL+ALT+SPACE 类名或接口名提示(与系统冲突) 提示类名关键字 (abstract public …)


CTRL+P 方法参数提示,显示默认参数


ALT+INSERT 生成代码(如GET,SET方法,构造函数等) , 光标在类中才生效


CTRL+ALT+O 优化导入的类和包 需要配置


CTRL+SHIFT+SPACE 切换窗口

CTRL+SPACE空格 代码自动完成,代码提示,一般与输入法冲突

  • CTRL+ALT+T 把选中的代码放在TRY{} IF{} ELSE{} 里

复制快捷方式


  • F5 复制文件/文件夹

  • CTRL+C 复制
  • CTRL+V 粘贴
  • CTRL+X 剪切,删除行
  • Ctrl + Y 删除行插入符号
  • CTRL+D 复制行 , 快速分布li标签等

  • CTRL+SHIFT+V 可以复制多个文本,将前几次复制的文本保存下来了

高亮


  • SHIFT+F2 高亮错误或警告快速定位错误,多个错误循环高亮

本地历史VCS/SVN


  • Ctrl + K 提交项目VCS
  • Ctrl + T 更新项目从VCS
  • Alt + Shift + C 查看项目最近文件版本变化文件 , CTRL+E 只是查看修改过的文件

  • Alt + ` (table 上面的点) 快速弹出VCS菜单

其他快捷方式


  • CTRL+Z 倒退(代码后悔)
  • CTRL+SHIFT+Z 向前
  • CTRL+H 显示类层级关系图,继承/实现关系

  • Ctrl +F12 文件结构弹出 类似 ALT + 7

  • CTRL+W 块状选中代码,连续按会有其他效果 Ctrl+Shift+W 减少当前选择到以前的状态

  • CTRL+O 魔术方法, 在php类体中有效

  • ctrl+shift+i 快速查看变量或方法定义源 , 也可以鼠标按住+CTRL

  • CTRL+ALT+F12 资源管理器打开文件夹,跳转至当前文件在磁盘上的位置

  • CTRL+ [] 光标移动到{}[]开头或结尾位置

  • CTRL+SHIFT+[] 直接选中块代码 = CTRL+W 按好几下

  • SHIFT+ALT+INSERT 竖编辑模式

  • CTRL+/ 单行注释/取消注释
  • CTRL+SHIFT+/ 块状注释/取消块状注释
  • Ctrl+Shift+U 选中的字符大小写转换
  • ctrl +
    ‘-/+’:可以折叠项目中的任何代码块,包括htm中的任意nodetype=3的元素,function,或对象直接量等等。它不是选中折叠,而是自动识别折叠。
  • ctrl + ‘.’: 折叠选中的代码的代码
  • CTRL+ALT←/→ 返回上次编辑的位置
  • ALT+←/→ 切换代码视图,标签切换
  • ALT+↑/↓ 在方法间快速移动定位
  • ctrl+shift+enter(智能完善代码 如if())

  • ctrl+shift+up/down (移动行、合并选中行,代码选中区域向上/下移动)
  • SHIFT+F6 重命名,重构当前区域内变量重命名/重构
    不但可以重命名文件名,而且可以命名函数名,函数名可以搜索引用的文件,还可以重命名局部变量。还可以重命名标签名。

  • alt +
    ‘7’:显示当前的类/函数结构。类似于eclipse中的outline的效果。试验了一下,要比aptana的给力一些,但还是不能完全显示prototype下面的方法名。

  • Alt + Shift + I 检查当前文件与当前的配置文件

编辑


  • Ctrl + Q 快速文档查询
  • ALT + INSERT 生成的代码…器(getter,setter方法,构造函数)
  • Ctrl + O 覆盖方法
  • Ctrl + I 实现方法
  • Ctrl + J 活动代码提示
  • Alt + Enter 显示意图的行动和快速修复
  • Shift + Tab 键缩进/取消缩进选中的行
  • Ctrl + Shift + J 智能线连接(仅适用于HTML和JavaScript)
  • Ctrl + Enter 智能线分割(HTML和JavaScript)
  • Shift + Enter 开始新的生产线
  • Ctrl + Delete 删除字(word)
  • Ctrl + Backspace 删除整个字 ,单纯Backspace单个字符删除

运行


  • Alt + Shift + F10 选择的配置和运行
  • Ctrl + Shift + X 运行命令行
  • Alt + Shift + F9 选择配置和调试
  • Shift + F10 运行
  • Shift + F9 调试
  • Ctrl + Shift + F10 运行范围内配置编辑器
  • Ctrl+Shift+H 方法的层次结构
  • Ctrl+Alt+H 呼叫层次
  • CTRL+Q 显示代码注释
  • ALT+F1 选择当前文件或菜单中的任何视图工具栏
  • CTRL+UP/DOWN 光标跳转到编辑器显示区第一行或最后一行下
  • ESC 光标返回编辑框
  • SHIFT+ESC 光标返回编辑框,关闭无用的窗口
  • CTRL+F4 关闭当前的编辑器或选项卡
  • Ctrl + Alt + V引入变量
  • Ctrl + Alt + F 类似引入变量
  • Ctrl + Alt + C引入常量
  • Ctrl + Tab 键切换选项卡和工具窗口
  • Ctrl + Shift + A 查找快捷键
  • Alt + #[0-9] 打开相应的工具窗口
  • Ctrl + Shift + F12 切换最大化编辑器
  • Alt + Shift + F 添加到收藏夹
  • Ctrl +反引号(`) 快速切换目前的配色/代码方案/快捷键方案/界面方案
  • Ctrl + Alt + S 打开设置对话框(与QQ冲突)

调试


  • F8步过
  • F7步入
  • Shift + F7智能进入
  • Shift + F8步骤
  • ALT + F9运行到光标
  • Alt + F8计算表达式
  • F9恢复程序
  • Ctrl + F8切换断点
  • Ctrl + Shift + F8查看断点

导航


  • Shift + Esc键隐藏活动或最后一个激活的窗口
  • Ctrl + Shift + F4关闭活动运行/消息/ /…选项卡
  • Ctrl + Shift + Backspace键导航到最后编辑的位置
  • Ctrl + Alt+B 到实施(S)
  • Ctrl + Shift+I 打开快速定义查询
  • Ctrl + U 转到super-method/super-class
  • Alt + Home 组合显示导航栏

书签


  • Ctrl + F11切换书签助记符
  • Ctrl +#[0-9]转到编号书签
  • Shift + F11显示书签

Esc键编辑器(从工具窗口)


  • F1 帮助千万别按,很卡!
  • F2(Shift+F2) 下/上高亮错误或警告快速定位
  • F3 向下查找关键字出现位置
  • F4 查找变量来源
  • F5 复制文件/文件夹
  • F6 移动
  • F11 切换书签
  • F12 返回到以前的工具窗口

轮询和长轮询

  1. 轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接。
    优点:后端程序编写比较容易。
    缺点:请求中有大半是无用,浪费带宽和服务器资源。
    实例:适于小型应用。
  2. 长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。
    优点:在无消息的情况下不会频繁的请求。
    缺点:服务器hold连接会消耗资源。
    实例:WebQQ、Hi网页版、Facebook IM。

另外,对于长连接和socket连接也有区分:

  1. 长连接:在页面里嵌入一个隐蔵iframe,将这个隐蔵iframe的src属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。
    优点:消息即时到达,不发无用请求。
    缺点:服务器维护一个长连接会增加开销。
    实例:Gmail聊天
  2. Flash Socket:在页面中内嵌入一个使用了Socket类的 Flash 程序JavaScript通过调用此Flash程序提供的Socket接口与服务器端的Socket接口进行通信,JavaScript在收到服务器端传送的信息后控制页面的显示。
    优点:实现真正的即时通信,而不是伪即时。
    缺点:客户端必须安装Flash插件;非HTTP协议,无法自动穿越防火墙。
    实例:网络互动游戏。

以上是四种请求方式的介绍和优缺点比较。