php swoole 扩展仿佛为php开发打开了一扇窗户

php workman和swoole原来是两个东东

  • swoole的使用范围更广,能做更多事应该

websocket的介绍

socket 与 websocket也是两个东东

wss 配置 和 nginx的配置

  • wss swoole 服务端
<?php
error_reporting(E_ALL);
set_time_limit(0);

//创建websocket服务器对象,监听0.0.0.0:9502端口
$ws = new swoole_websocket_server("0.0.0.0", 9505, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
$config = [
        'daemonize' => true,
        'ssl_key_file'  => '/workspace/file/2191282_www.havetatami.com.key',
        'ssl_cert_file' => '/workspace/file/2191282_www.havetatami.com.pem'
];
$ws->set($config);
//监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) {
        var_dump($request->fd);
        $ws->push($request->fd, "hello, welcome\n");
});

//监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
        var_dump($ws->connection_list());
        foreach ($ws->connection_list() as $fd){
                $ws->push($fd, "server: {$frame->data}");
        }
});

//监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
    echo "client-{$fd} is closed\n";
});

$ws->start();

  • wss 浏览器端
<html>
<head>
<meta charset=utf-8 >
<title>test</title>
</head>

<body>

<h3 style="text-align:center;">test</h3>

<script>

var wsServer = 'wss://www.havetatami.com:9502/websocket';
var websocket = new WebSocket(wsServer);

function ssend(){
        websocket.send(1);
        setTimeout(ssend, 100);
}

websocket.onopen = function (evt) {
        console.log("Connected to WebSocket server.");
        //ssend();
};

websocket.onclose = function (evt) {
    console.log("Disconnected");
};

websocket.onmessage = function (evt) {
    console.log('Retrieved data from server: ' + evt.data);
};

websocket.onerror = function (evt, e) {
    console.log('Error occured: ' + evt.data);
};

</script>
</body>
</html>

  • nginx 配置
server{

        listen 443 ssl;

        server_name www.havetatami.com;

        ssl_certificate   /workspace/file/www.havetatami.com.chained.crt;
        ssl_certificate_key /workspace/file/www.havetatami.com.key;
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;

        root /workspace/web/gitee/havetatami;


        location / {
                index index.php index.html index.htm;
                if (!-e $request_filename) {
                        rewrite ^/index.php(.*)$ /index.php?s=$1 last;
                        rewrite ^(.*)$ /index.php?s=$1 last;
                        break;
                }
        }


        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
        access_log /workspace/data/nginx/log/www_havetatami_com_access.log;

}

server{
        listen 80;
        server_name www.havetatami.com;
        return 301 https://$server_name$request_uri;
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}
upstream websocket {
    server 39.106.58.30:9505;
}
server{

        listen 9502 ssl;

        server_name www.havetatami.com;

        ssl_certificate /workspace/file/2191282_www.havetatami.com.pem;
        ssl_certificate_key /workspace/file/2191282_www.havetatami.com.key;
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;

        root /workspace/web/gitee/havetatami;

        location /websocket {
                proxy_pass https://websocket;
                proxy_read_timeout 300s;
                proxy_send_timeout 300s;

                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
        }

        access_log /workspace/data/nginx/log/www_havetatami_com_access1.log;

}

vue-cli,nginx反向代理

  • nginx 配置
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}
upstream my_blog {
    server localhost:8080;
    keepalive 2000;
}

server {
    listen      80;
    server_name bloghtml.test;

    rewrite ^(.*)$ $scheme://www.bloghtml.test$1 permanent;
}
server {
    listen      80;
    server_name www.bloghtml.test;
    client_max_body_size 1024M;

    if ($time_iso8601 ~ "^(\d{4}-\d{2}-\d{2})") {
        set $ttt $1;
    }
    access_log  /logs/$host-$ttt-access.log main;

    root        /www/bloghtml/myblog;

    location / {
        #root /www/bloghtml/myblog;
        #index   index.php index.html index.htm;
        #try_files $uri $uri/ @router;
        #proxy_redirect http://my_blog/ http://$host:$server_port/;
        #proxy_cookie_path / /;
	
	proxy_pass http://my_blog/;
        proxy_read_timeout 600;
        proxy_send_timeout 600;
	proxy_connect_timeout 60;
        proxy_http_version 1.1; 
	proxy_set_header Host $host:$server_port;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";    
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   }
   # location @router {
   #     rewrite ^.*$ /index.html last;
   # }

    #location ~* \.php {
    #    include                 fastcgi_params;
    #    fastcgi_index           index.php;
    #    fastcgi_pass            localhost:9000;
    #    fastcgi_split_path_info ^(.+\.php)(.*)$;
    #    fastcgi_param           PATH_INFO       $fastcgi_path_info;
    #    fastcgi_param           SCRIPT_NAME     $fastcgi_script_name;
    #    fastcgi_param           SCRIPT_FILENAME $document_root$fastcgi_script_name;
    #}
}
  • vue 项目根目录下的vue.config.js配置
module.exports = {
    devServer: {
        open: true,
        // host: 'www.bloghtml.test',
        https: false,
        disableHostCheck: true
    }
}

Swoole运行的两种模式

  • swoole_process多进程模式
    TCP连接是和Master进程进行建立,然后再由Master把请求分配给Worker进程进行任务的处理。
  • swoole_base基本模式
    base模式下没有Master进程的角色,只有Manager进程的角色,每个客户端连接由worker进程进行连接。base模式下Manager进程是可选的,当设置worker_num=1,并且没有使用Task和MaxRequest特性时,底层将直接创建一个单独的Woker进程,不创建Manager进程。

进程与线程

  • 进程:计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。
  • 线程:操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。

进程的特点

  • 动态性(pcb进程控制块是进程存在的唯一标志):进程是程序的一次执行,它有着创建,活动,暂停,终止等过程,具有一定的生命周期(由pcb决定),是动态的产生,变化和消亡的。动态性是进程最基本的特征。
  • 并发性:指多个进程实体,同存于内存中,能在一段时间内同时运行,并发性是进程的重要特征,同时也是操作系统的重要特征。引入进程的目的就是为了使程序能与其它进程的程序并发执行,以提高资源利用率。
  • 独立性:指进程实体是一个能独立运行,独立获得资源和独立接受调度的基本单位。凡是未建立pcb的程序都不能作为一个独立的单位参与运行。
  • 异步性:由于进程的相互制约,使进程具有执行的间断性,即进程按照各自独立的,不可预知的速度向前推进。异步性会导致执行结果的不可再现性,为此,在操作系统中必须配置相应的进程同步机制。
  • 结构性:每个进程都配置一个pcb对其进行描述。从结构上看,进程实体由程序段,数据和进程控制段三部分组成。

进程的通讯方式

  • 管道:速度慢,容量有限,只有父子进程能通讯。
  • 有名管道(named pipe):任何进程间都能通讯,但速度慢。
  • 消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题。
  • 信号量:不能传递复杂消息,只能用来同步。
  • 共享内存:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存同样可以用作线程间通讯,不过这个没这个必要,线程间本来就已经共享了同一进程内的一块内存。

线程的特点

  • 轻型实体:线程中的实体基本上不有系统资源,只是有点必不可少的、能保证独立运行的资源。线程的实体包括程序、数据和TCB。线程是动态概念,它的动态特性由线程控制块TCB(Thread Control block)描述。
  • 独立调度和分派的基本单位:在多线程OS中,线程是能独立运行的基本单位,因而也是独立调度和分派的基本
    单位。由于线程很“轻”,故线程的切换非常迅涑且开销小(在同进程中的)。
  • 可并发执行:在一个进程中的多个线程之间,可以并发执行,甚至允许在一个进程中所有线程都能并发执行。同样,不同进程中的线程也能并发执行,充分利用和发挥了处理机与外围设备并行工作的能力。
  • 共享进程资源:在同进程中的各个线程,都可以共享该进程所拥有的资源,这首先表现在:所有线程都具有相同的地址空间(进程的地址空间),这意味着,线程可以访问该地址空间的每个虚地址;此外,还可以访问进程所拥有的已打开文件、定时器、信号量等。
  • 互相通信不必调用内核:由于同个进程内的线程共享内存和文件,所以线程间互相通信不必调用内核。
  • 线程共享的环境包括:进程代码段、进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯)、进程打开的文件描述符、信号的处理器、进程的当前目录和进程用户ID与进程组ID。

扩展阅读

题外话

  • 今天看了书,看到了一句话,安慰自己:一个人愿意让你爱他,就已经是你很大的幸运了。你得好好爱,别辜负了对方的信任和期待。

分类:

技术点:

相关文章: