当前位置:Linux教程 - Linux - SERVER PUSH的具体实现

SERVER PUSH的具体实现



        
    作者/来源:[email protected]


    拙作“推”向更快发表后,笔者收到了很多朋友的来信,希望能了解更多的关于 SERVER PUSH的技术资料,说实话对这一新技术笔者也不是太了解,但本着知无不言的思想,在这里根据笔者的实际使用情况作一些详细的介绍,希望给那些对 SERVER PUSH有兴趣的朋友一点点的帮助和参考。也希望能借此抛砖引玉,求得高手的不吝指教。

    “推”由于篇幅的原因,只对 SERVER PUSH作了一般的介绍,下面我们来看看SERVER PUSH的具体实现过程:
    一、作业系统:
    目前 SERVER PUSH还不能在WIN9X上实现,至少是我自己还没有在WIN9X作为主机上实现过这一功能。经笔者试验成功的作业系统有:WINNT4.0,UNIX,LINUX,,FREEBSD,以LINUX支持最好。因为我使用的LINUX都是最新的版本,可以方便地编译最新的功能模块。当然还有其它的作业系统也能很好地支持 SERVER PUSH功能,但笔者限于条件没有测试过。
    二、WWW服务器:
    其实目前除了IIS和APACHE这两个WWW服务器,你没有更好的选择,值得庆辛的是它们都能很好地支持 SERVER PUSH,当然你应该选择它们的最新版。别的那些小孩子过家家那样的WWW服务器就不用试了。在这里笔者极力推荐在LINUX上安装APACHE,以便能自由编译功能模块,这样可以充分使用SERVER PUSH、FASTCGI,E-CGI、PHP等新的扩展功能。
    三、脚本支持:
    虽然 SERVER PUSH可以用更多的脚本程序来编写,但笔者强烈推荐用PERL或C语言来写CGI脚本,因为PERL已经是CGI脚本程序事实上的标准。而且在PERL5中已经可以直接调用C子程序而不需要任何声明。不管你用什么语言来写CGI脚本, 解释器中应该有CGI.PM模块,笔者试用的版本是 5.004,这一模块的更新版大家可以从网上下载,找不到?用搜索引擎输入CGI.PM就行了,要多少个都有。
    好了,有了上面的工具,下面我们就来写一个 SERVER PUSH程序来说明它的实现过程:
    #!/usr/bin/perl
    use CGI qw/:push -nph/;
    $| = 1;
    print multipart_init(-boundary=>'--boundary');
    while (1) {
    print multipart_start(-type=>'text/plain'),
    "The current time is ",scalar(localtime),"\n",
    multipart_end;
    sleep 1;
    }
    use CGI qw/:push -nph/;这一行告诉CGI解释程序,调用支持SERVER PUSH的功能模块(CGI.PM),在这个模块中预先定义了三个涵数:multipart_init()、

    multipart_start()和multipart_end,只要在程序中有use CGI qw/:push -nph/

    声明。就可以直接使用这三个涵数。
    multipart_init()涵数的作用是声明了一个文档类型,就象普通的CGI程序中的“Content-Type: text/html”声明,告诉服务器下面传送的是HTML文档, 而multipart_init()这一涵数声明的文件类型却是实现SERVER PUSH最根本的方法类型:Content-Type: multipart/x-mixed-replace; boundary='--boundary'

    如果你对HTTP的MIME类型有详细的了解,你就知道multipart类型是一种复合类型,它的子类型是mixed,子类型的X参数大家可以参看详细的MIME类型说明,这里最关键的是replace方法,它不停地用新接收的数据更新旧的数据。这,就是SERVER PUSH最大的技术内涵。boundary只是一个边界值,告诉浏览器从这儿开始,使用SERVER PUSH方法了。其实你完全可以这样理解,只要在脚本程序中声明了multipart/x-mixed-replace; boundary='--boundary'这样一个文档类型, 服务器就和客户机建立了一个特别的连结。服务器就不断地把客户机请求的数据源源不断地推向了客户机。而传统的CLIENT PULL方法是:1、CLIENT和SERVER建立连结。2、CLIENT发送请求。3、SERVER响应请求。4、SERVER断开连结以响应下一请求。通过这两种方法的比较大家可以看出SERVER PUSH优点主要在于服务
    器和客户机之间这种不间断的连结方式。使得它不需要采用CLIENT PULL的<META http-equiv=refresh content="n">这种方法来刷新页面,不仅更新速度快,而且不会产生闪动效果。
    可以看到,如果你不用multipart_init(),直接在脚本程序中用这样的语句也可以达到同样的目的:
    print "Content-Type: multipart/x-mixed-replace; boundary='boundary'\n\
    n"这样做的好处是当系统不能支持multipart_init()涵数时,就可以直接这样声明。
    multipart_start()这个涵数是为服务器指定了传送一个确定的文档,如果不用这个涵数,根据脚本程序的内容服务器可以直接把指定数据传送给客户机,当然客户机不能识别这种类型的文档可以忽略而不会产生错误。但如果你指明了具体的文档类型,如例程中的text/plain(纯文本类型),客户机就不要再对文档加以分析从而提高了处理速度。否则客户机只知道传送过来的是multipart(复合型)
    而要重新对其分析。
    至于multipart_end涵数不需作详细说明,只是说明了一个PUSH过程的结束。

    为了使大家能更好地理解这三个涵数详细的技术内容,我把这三个涵数的实现过程解析给大家:
    sub multipart_init {
    my($self,@p) = self_or_default(@_);
    my($boundary,@other) = $self->rearrange([BOUNDARY],@p);
    $boundary = $boundary || '------- =_aaaaaaaaaa0';
    $self->{'separator'} = "\n--$boundary\n";
    $type = SERVER_PUSH($boundary);
    return $self->header(
    -nph => 1,
    -type => $type,
    (map { split "=", $_, 2 } @other),
    ) . $self->multipart_end;
    }

    sub multipart_start {
    my($self,@p) = self_or_default(@_);
    my($type,@other) = $self->rearrange([TYPE],@p);
    $type = $type || 'text/html';
    return $self->header(
    -type => $type,
    (map { split "=", $_, 2 } @other),
    );
    }

    sub multipart_end {
    my($self,@p) = self_or_default(@_);
    return $self->{'separator'};
    }
    其它的在使用SERVER PUSH时的一些技巧,限于篇幅我不能再作过多的介绍.
    发布人:netbull 来自:PHP联盟