Browse Month: 十二月 2016

HTTP 长连接

HTTP 长连接和短连接

HTTP协议是基于请求/响应模式的,因此只要服务端给了响应,本次HTTP请求就结束了,没有长连接这一说。

网络上所说HTTP分为长连接和短连接,其实本质上是说的TCP连接。TCP连接是一个双向的通道,它是可以保持一段时间不关闭的,因此TCP连接才有真正的长连接和短连接这一说。

HTTP协议说到底是应用层的协议,而TCP才是真正的传输层协议,只有负责传输的这一层才需要建立连接。

长连接的设置

服务器和客户端都设置 Connection: keep-alive 就是长连接。

长连接的作用

长连接是为了复用: 长连接是指的TCP连接,也就是说复用的是TCP连接。长连接情况下,多个HTTP请求可以复用同一个TCP连接,这就节省了很多TCP连接建立和断开的消耗。比如请求一个网页,这个网页里肯定还包含了CSS、JS等等一系列资源,如果是短连接(也就是每次都要重新建立TCP连接)的话,那每打开一个网页,都需要建立几个甚至几十个TCP连接,这将极为浪费资源。

长连接并不是永久连接的。如果一段时间内(具体的时间长短,是可以在header当中进行设置的,也就是所谓的超时时间),这个连接没有HTTP请求发出的话,那么这个长连接就会被断掉。

HTTP协议中的短轮询长轮询

短轮询

轮询相信大家都不难理解,比如你现在要做一个电商中商品详情的页面,这个详情界面中有一个字段是库存量。而这个库存量需要实时的变化,保持和服务器里实际的库存一致。

最简单的一种方式,就是你用JS写个死循环,不停的去请求服务器中的库存量是多少,然后刷新到这个页面当中,这其实就是所谓的短轮询。

这种方式有明显的坏处,那就是你很浪费服务器和客户端的资源。客户端还好点,现在PC机配置高了,你不停的请求还不至于把用户的电脑整死,但是服务器就很蛋疼了。如果有1000个人停留在某个商品详情页面,那就是说会有1000个客户端不停的去请求服务器获取库存量,这显然是不合理的。

长轮询

长轮询这个时候就出现了,其实长轮询和短轮询最大的区别是,短轮询去服务端查询的时候,不管库存量有没有变化,服务器就立即返回结果了。而长轮询则不是,在长轮询中,服务器如果检测到库存量没有变化的话,将会把当前请求挂起一段时间(这个时间也叫作超时时间,一般是几十秒)。在这个时间里,服务器会去检测库存量有没有变化,检测到变化就立即返回,否则就一直等到超时为止。

短轮询和长轮询的区别:

而对于客户端来说,不管是长轮询还是短轮询,客户端的动作都是一样的,就是不停的去请求,不同的是服务端,短轮询情况下服务端每次请求不管有没有变化都会立即返回结果,而长轮询情况下,如果有变化才会立即返回结果,而没有变化的话,则不会再立即给客户端返回结果,直到超时为止。

长短轮询和长短连接的区别

第一个区别是决定的方式: 一个TCP连接是否为长连接,是通过设置HTTP的Connection Header来决定的,而且是需要两边都设置才有效。而轮询方式是否为长轮询,是根据服务端的处理方式来决定的,与客户端没有关系。

第二个区别就是实现的方式: 连接的长短是通过协议来规定和实现的。而轮询的长短,是服务器通过编程的方式手动挂起请求来实现的。

参考

http://blog.csdn.net/mengyafei43/article/details/25195445

http://www.cnblogs.com/cswuyg/p/3653263.html

https://www.zhihu.com/question/20831000

http://www.cnblogs.com/hoojo/p/longPolling_comet_jquery_iframe_ajax.html

yii2 行为

behavior 是 yii\base\Behavior 或其子类的实例, behavior,可以无须改变类继承关系即可增强一个已有的 yii\base\Component 类功能。当行为附加到组件后,它将“注入”它的方法和属性到组件,然后可以像访问组件内定义的方法和属性一样访问它们。 此外,行为通过组件能响应被触发的事件, 从而自定义或调整组件正常执行的代码。

定义行为

~/yiint/components/MyBehavior.php

以上代码定义了行为类 @app\components\MyBehavior 并为要附加行为的组件提供了两个属性 prop1 、 prop2 和一个方法 foo()。

附加行为

静态附加行为

覆写行为要附加的组件类的 yii\base\Component::behaviors() 方法, 返回行为配置列表。

每个行为配置格式:

动态附加行为

在对应组件里调用 yii\base\Component::attachBehavior() 方法

可以通过 yii\base\Component::attachBehaviors() 方法一次附加多个行为:

使用行为

将behavior 附加到 yii\base\Component 类或其子类后就可以直接使用它。

行为对象

附加行为到组件时的命名行为, 可以使用这个名称来访问行为对象

移除行为

要移除行为,可以调用 yii\base\Component::detachBehavior() 方法用行为相关联的名字实现:

使用 TimestampBehavior

yii\behaviors\TimestampBehavior 行为支持在 yii\db\ActiveRecord 存储时自动更新它的时间戳属性。

首先,附加这个行为到计划使用该行为的 yii\db\ActiveRecord 类:

以上指定的行为数组:

当记录插入时, 行为将当前的 UNIX 时间戳赋值给 created_at 和 updated_at 属性;

当记录更新时,行为将当前的 UNIX 时间戳赋值给 updated_at 属性。

保存 User 对象, 将会发现它的 created_at 和 updated_at 属性自动填充了当前时间戳:

处理事件

如果要让行为响应对应组件的事件触发, 就应覆写 yii\base\Behavior::events() 方法,如:

yii\base\Behavior::events() 方法返回事件列表和相应的处理器。 上例声明了 yii\db\ActiveRecord::EVENT_BEFORE_VALIDATE 事件和它的处理器 beforeValidate()

yii2 表单使用

准备代码文件

form/entry.php

在视图中生成一个 HTML 表单

声明规则去验证输入的数据

创建一个模型代表用户通过表单输入的数据

表单与输入框字段

视图使用小部件 yii\widgets\ActiveForm 去生成 HTML 表单。 其中的 begin() 和 end() 分别用来渲染表单的开始和关闭标签。

yii\widgets\ActiveForm::field() 方法用于创建输入框。

表单字段

代码探析

ActiveForm 类图与代码解析

是的,其实数据首先由客户端 JavaScript 脚本验证,然后才会提交给服务器通过 PHP 验证。 yii\widgets\ActiveForm 足够智能到把你在 EntryForm 模型中声明的验证规则转化成客户端 JavaScript 脚本去执行验证。 如果用户浏览器禁用了 JavaScript, 服务器端仍然会像 actionEntry() 方法里这样验证一遍数据。 这保证了任何情况下用户提交的数据都是有效的。

输入框的文字标签是 field() 方法生成的,内容就是模型中该数据的属性名。 例如模型中的 name 属性生成的标签就是 Name。

输入验证

FormController.php