Month: 1月 2018

HTML 5 服务器推送事件

HTML5 服务器发送事件(server-sent event)允许网页获得来自服务器的更新。

Server-Sent 事件 - 单向消息传递

Server-Sent 事件指的是网页自动获取来自服务器的更新。

以前也可能做到这一点,前提是网页不得不询问是否有可用的更新。通过服务器发送事件,更新能够自动到达。

例子:Facebook/Twitter 更新、估价更新、新的博文、赛事结果等。

最后更新于 2019年4月1日 …

    

php nginx 实时输出

PHP 里开启实时输出方法是ob_implicit_flush()
但它大部分情况下都不管用,

因为php.ini配置里output_buffering输出缓冲大部分是On开启的,
还有zlib.output_compression也经常会被开启,

除了 PHP 这一层,还有 Nginx 的缓冲设置proxy_buffering,和压缩gzip也大都是开启的。
为了一两个页面的需求,修改整个服务器的网站配置,恐怕没有人会做这种选择。

这里推荐一下简单的方法:

set_time_limit(0);
ob_end_clean();
ob_implicit_flush();

header('X-Accel-Buffering: no'); // 关键是加了这一行。

echo '现在是:'.date('H:i:s').'<br>';
sleep(5);
echo '五秒后:'.date('H:i:s');

 

    

[技术] 谈谈编程思想

这段时间又攒了很多答应了,但还未动手的文章。大概一两周前,有个读者留言:「程序君,能发篇文章有关编程思想的吗?我是编程初学者,对编程思想没啥概念,求传授点经验!」

今天就讲讲编程思想。编程思想是个宏大的主题,我不敢保证我能在短短的一两个小时里讲得全面而深入。推荐给大家一本好书『冒号课堂』,是国内为数不多的讲编程思想的经典之作。无奈这本书已经不再出版,只能在图书馆里一睹芳容(我几年前在国图和它偶遇)。

各种软件思想虽然层出不穷,但其本质是降低系统复杂度,减少重复,减少代码的变更。掌握了这个大方向,理解各种编程思想就容易多了。

(下文所涉及的代码大多是剪短清晰的python代码)

以程序君不太准确的分类,编程思想可以分为以下几个大类:

  • 原则(Principles)
  • 范式(Paradigms)
  • 方法论(Methodologies)
  • 模式(Patterns)

我们一点点展开,说到哪算哪。

原则(Principles)

我认识(或者说现在想得起来的)的原则主要有以下几种:

  • DRY (Don't Repeat Yourself)
  • OCP (Open Close Principle)
  • SoC (Separation of Concerns)
  • IoC (Inversion of Control)
  • CoC (Configuration over Convention)
  • Indirection (Layering)

"Don't repeat yourself"很好理解。当你第二次写同样结构,变化不大的代码时,脑袋里就要闪现一个大大的问号:我是不是在repeat myself?如果是,就要重构,或封装,或抽象,或函数化,总之一个目的,消除重复。以笔者的经验,DRY原则看似基本,实则很多大型软件公司都未能做好,copy & paste到处可见。我们写代码,从一开始就要把握好这个原则,否则在「破窗理论」的指引下,代码的质量会快速划向万劫不复的深渊。

程序员的好日子什么时候才到头?

要不要转行(报考)软件开发?程序员的高薪让我流口水,但好日子总有个到头的时候吧?不会我一入行就见顶了吧?

这样的问题让我不胜其烦。为子女未来前途操碎了心的长辈们,长辈们的朋友们,还有微信知乎上的朋友,像候鸟一样,在一年里的两个时间:春节期间和高考报志愿前夕,准时开问。我大概六月份回答过一位长辈的咨询,他说小陈,你说的好像很有道理的样子啊,应该发篇文章我好能转给我的朋友们。我说叔叔好啊,就写就写。结果开了个头,就因为懒的原因(主要是红包没到位),一直搁在今天。最近翻看 git repo 里面一票未完成的文章,这篇蹦了出来,伸长脖子一个劲儿地向我示意:poke me,poke me,所以,就有了大家看到的这篇文章。…

TCP连接的关闭

TCP连接的关闭

多线程多进程关闭连接的区别

  首先来看看close和shutdown两个系统调用对应的内核函数:

TCP连接的关闭

 

TCP连接的关闭

  上图是调用close和shutdown关闭连接时的函数调用过程,sys_close和sys_shutdown这两个系统调用最终是由tcp_close和tcp_shutdown方法来实现的。

  由此我们可以来看一个问题:当socket被多进程或者多线程共享时,关闭连接时有何区别? 
  从图中可以看到sys_close封装调用过程中有一个fput函数,它有一个引用计数,记录这个socket被引用了多少次。当这个引用计数不为0时,是不会触发真正关闭tcp连接的tcp_close方法的。

  引用计数是怎么来的呢?创建进程和线程都是由clone系统调用实现的,只不过clone的参数不同,行为也不同。

  在clone系统调用中,会调用方法copy_files来拷贝文件描述符(包括socket)。创建线程时,传入的flag参数中包含标志位CLONE_FILES,此时,线程将会共享父进程中的文件描述符。

  而创建进程时没有这个标志位,这时,会把进程打开的所有文件描述符的引用计数加1。所以子进程会将父进程中已经建立的socket加上引用计数,当进程中close一个socket时,只会减少引用计数,仅当引用计数为0时才会触发tcp_close。

  单线程(进程)中使用close与多线程中是一致的,但这两者与多进程的行为并不一致,多进程中共享的同一个socket必须都调用了close才会真正的关闭连接。

  shutdown是没有引用计数什么事的,只要调用了就会去试图按需关闭连接。所以shutdown与多线程、多进程无关。

close发生了什么

  TCP连接是全双工的连接,及连接双方可以并行的发送或者接收消息。这样关闭连接时就存在3种情形:完全关闭连接; 关闭发送消息的功能;关闭接收消息的功能。其中,后者就叫做半关闭,由shutdown实现,前者用close实现。

  我们现在来看看close。

 

TCP连接的关闭

我们依次来看一下这三种情形:

1)关闭监听句柄

  用于listen的监听句柄是close关闭的,它本身并不对应着某个连接,但是附着在它之上的却可能有半成品连接,即1、2次握手完成,第3次未完成,就会在服务器上有许多半连接,close的工作主要是清理这些半连接。

  keepalive定时器是干嘛的?keepalive是TCP中一个可以检测死连接的机制,侧重在保持客户端和服务端的连接,防止僵死、异常退出的客户端占用服务器连接资源。

  比如A与B建立连接后,突然B宕机了,之后时间内B再也没有起来,如果B宕机后A和B一直没有数据通信的需求,A就永远不会发现B已经挂了,那么A的内核里还维护着一份关于A与B之间TCP连接的信息,浪费系统资源。

  所以TCP层面引入了keepalive机制,A会定期给B发送空的数据包,通俗讲就是心跳包。

  内核对于tcp keepalive的调整主要有以下三个参数:

TCP连接的关闭

  当tcp发现未收到对端数据时,开始以间隔tcp_keepalive_intvl(75)秒的频率发送心跳包。

  如果连续tcp_keepalive_probes(9)次以上未响应代表对端已经down了,close该连接。

  参照上图,close首先会移除keepalive定时器,移除此定时器后,若ESTABLISH状态的TCP连接在tcp_keepalive_time时间(如服务器上常配置为2小时)内没有通讯,服务器就会主动关闭连接。接下来,发送RST包去关闭每一个半连接,处理完所有半打开的连接close的任务就基本完成了。

2)关闭普通ESTABLISH状态的连接(未设置so_linger,默认)

  首先检查是否有接收到却未处理的消息。如果有,根据close的行为是要丢掉这些消息的。

  但丢弃消息后,意味着远端误以为发出的消息已经被本机处理了(因为ACK包确认过了),但实际上是收到未处理,此时不能使用正常的四次握手关闭连接,而是会向远端发送一个RST非正常复位关闭连接。所以这要求程序员在关闭连接前,确保接收并处理了连接上的消息。

  如果此时没有未处理的消息,那么发送FIN来关闭连接。这时,再看看是否有待发送消息,如果有,那么会在最后一个报文中加入FIN标志,同时关闭angle算法,一次性将所有包发出;如果没有未发送消息,则仅发送一个FIN报文,发送出去关闭连接。

3)使用了so_linger的连接

  so_linger是干嘛的?so_linger决定系统如何处理残留在套接字发送队列中的数据。我们可能有强可靠性的需求,也就是说,必须确保发出的消息、FIN都被对方收到。

  怎么做到呢?就是等待,close会阻塞住进程,直到对方确认收到了再返回,但是如果对方总是不响应怎么办呢?所以还需要l_linger这个超时时间,控制close阻塞进程的最长时间。

TCP连接的关闭

  上图是l_linger参数的设置及其对应的行为,默认情况下是第一种情况。

  当使用了so_linger后,前半段仍然没有变化。首先检查是否有未处理消息,有则发RST关连接。

  接下来检查是否有未发送消息,这种与第二种情况一致,设好FIN后关闭angle算法。接下来,会设置最大等待时间l_linger,然后进程开始睡眠,直到确认对方接收到消息,将控制权交还给用户进程。

  总结一下就是:调用close时,可能导致发送RST复位关闭连接,例如有未读消息、打开so_linger但l_linger却为0、关闭监听句柄时半打开的连接。更多时会导致发FIN来四次握手关闭连接,但打开so_linger可能导致close阻塞等待着对方的ACK表明收到了消息。

本文转自:小组15级成员--杜肖孟

原文地址:http://blog.csdn.net/tanswer_/article/details/78422879

PHP中类静态调用和范围解析操作符的区别

<?php
//在子类或类内部用“::”调用本类或父类时,不是静态调用方法,而是范围解析操作符。


class ParentClass {
    public static $my_static = 'parent var ';
    public function test() {
        self::who();    // 输出 'parent' 是范围解析,不是静态调用
        $this->who();    // 输出 'child'
        static::who();  // 输出 'child' 延迟静态绑定 是范围解析,不是静态调用
    } 

    public function who() {
        echo 'parent<br>';
    }
}

    

TCP/IP指南

组织:中国互动出版网(http://www.china-pub.com/)
RFC文档中文翻译计划(http://www.china-pub.com/compters/emook/aboutemook.htm)
E-mail:ouyang@china-pub.com
译者:(   )
译文发布时间:2001-12-28
版权:本中文翻译文档版权归中国互动出版网所有。可以用于非商业用途自由转载,但必须保留
本文档的翻译及版权信息。




Network Working Group                                      T. Socolofsky
Request for Comments:  1180                                      C. Kale
                                                  Spider Systems Limited
                                                            January 1991

  
  

TCP/IP指南
(RFC1180——A TCP/IP Tutorial)
  
本备忘录的状态
  
这本 RFC 是 TCP/IP 协议的指南, 重点介绍通过一个路由 
器从来源主机提交一个 IP 数据包到目的地主机的步骤。 
它不指定一个因特网标准。 
  
目录
  
    

php发送http put/patch/delete请求Demo

CURL请求对于PHPer是必备技能,使用curl_opt函数来发送各式各样的http请求动作,不仅限于get和post。
在测试自己的restful api的时候,通过访问这个代理发送http put/patch/delete请求的php页面,完成测试。请参考下面的DEMO。

<?php
/**
 * http.php
 * 用来向服务器的RESTful API发起各类HTTP请求的工具函数。
 *
 * 使用: http://localhost/http.php?action=xxx
 * xxx \in {get,post,put,patch,delete}
 *
 * Created by PhpStorm.
 * User: Lenix
 * Date: 2018/1/6
 * Time: 下午20:22
 */

class commonFunction{
    public function