• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

详解 swoole 教程:(一)laravel 配置使用 swoole

武飞扬头像
Luke
帮助2182

php安装swoole扩展请移步swoole官方网站:

wiki.swoole.com/#/environme…

我这里使用的yum源安装的php环境,在安装的时候已经集成swoole扩展,具体环境安装步骤请移步《CentOS7.8使用yum安装PHP 7.4》

1:安装laravel-swoole扩展:

composer require swooletw/laravel-swoole

2:生成配置文件, 运行以下命令在 /config 命令看生成配置文件 swoole_http.php swoole_websocket.php

php artisan vendor:publish --tag=laravel-swoole

3: Laravel 应用中使用 Swoole 之前,先通过 Composer 安装 LaravelS 扩展包:

LaravelS 官方文档: github.com/hhxsv5/lara…

composer require hhxsv5/laravel-s

该命令会发布配置文件 laravels.php 到 config 目录下,以及脚本文件到 bin 目录下

php artisan laravels publish

4: 如果想用 websocket ,在 config/laravels.php

'websocket'                => [
    'enable' => true,
    'handler' => \App\Services\WebSocketService::class,
],

5:WebSocketService.php

namespace App\Services;
 
use Hhxsv5\LaravelS\Swoole\WebSocketHandlerInterface;
use Illuminate\Support\Facades\Log;
use Swoole\Http\Request;
use Swoole\WebSocket\Frame;
use Swoole\WebSocket\Server;
 
class WebSocketService implements WebSocketHandlerInterface
{
    public function __construct()
    {
 
    }
 
    // 连接建立时触发
    public function onOpen(Server $server, Request $request)
    {
        // 在触发 WebSocket 连接建立事件之前,Laravel 应用初始化的生命周期已经结束,你可以在这里获取 Laravel 请求和会话数据
        // 调用 push 方法向客户端推送数据,fd 是客户端连接标识字段
 
        Log::info('WebSocket 连接建立');
        $server->push($request->fd, 'Welcome to WebSocket Server built on LaravelS');
    }
 
    // 收到消息时触发
    public function onMessage(Server $server, Frame $frame)
    {
        $server->push($frame->fd, 'This is a message sent from WebSocket Server at ' . date('Y-m-d H:i:s'));
    }
 
    // 关闭连接时触发
    public function onClose(Server $server, $fd, $reactorId)
    {
        Log::info('WebSocket 连接关闭');
    }
}

6:启动laravels

cd bin
php laravels start  //使用该命令启动laravels
php laravels stop  //使用该命令停止laravels
php laravels reload  //使用该命令重载laravels
php laravels restart  //使用该命令重启laravels
php laravels info    //使用该命令显示laravels信息
php laravels help   //使用该命令显示laravels帮助

a1.png

注意启动成功之后的端口号,这个配置nginx的时候会用到,我这里的端口号是5200。

7:配置.env文件

将一下代码添加至.env文件中。

#这里的 IP 需要和 nginx upstream 中配置的监听 IP 保持一致
LARAVELS_LISTEN_IP=0.0.0.0
LARAVELS_DAEMONIZE=true

8:测试swoole是否可用。

在根目录下创建ws_server.php文件

<?php
//创建WebSocket Server对象,监听0.0.0.0:9502端口
$ws = new Swoole\WebSocket\Server('0.0.0.0', 9502);
 
//监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) {
    $ws->push($request->fd, "hello, welcome\n");
});
 
//监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
    echo "Message: {$frame->data}\n";
    $ws->push($frame->fd, "server: {$frame->data}");
});
 
//监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
    echo "client-{$fd} is closed\n";
});
 
$ws->start();

然后在服务器使用命令行执行

php ws_server.php

前端代码:我这里使用的vue3.0语法

import { useRouter } from "vue-router";
import {
  PropType,
  ref,
  watch,
  reactive,
  toRefs,
  inject,
  provide,
  onMounted
} from "vue";
// 引入公共js文件
import utils from "/@/assets/js/public/function";
// 定义返回的类型
interface dataRef {
  close: () => void;
}
export default {
  name: "Drawer",
  // VUE3语法 setup函数
  // setup官方文档:https://www.vue3js.cn/docs/zh/guide/composition-api-setup.html#参数
  setup(props: any, content:any): dataRef 
  {
    /**
     * @name: 声明data
     * @author: camellia
     * @email: guanchao_gc@qq.com
     * @date: 2021-01-10 
     */
    const data = reactive({
      drawerShow: common.drawerShow,
    });
    /**
     * @name: 关闭组件
     * @author: camellia
     * @email: guanchao_gc@qq.com
     * @date: 2021-01-10 
     */
    const close = () => {
      data.drawerShow = false;
      common.drawerShow = data.drawerShow;
    }
    // 初始化客户端套接字并建立连接
    var sock = new WebSocket("ws://111.231.162.140:9502");
 
    // 连接建立时触发
    sock.onopen = (event) => {
      console.log("Connection open ...");
      change();
    }
 
    // 接收到服务端推送时执行
    sock.onmessage = (event) => {
      var msg = event.data;
      console.log(event);
      console.log("webscoket 接收到返回消息!");
    };
 
    // 连接关闭时触发
    sock.onclose = (event) => {
      console.log("Connection closed ...");
    }
    // 发送消息给webscoket
    const change = () => {
      var msg = "你好啊~";
      // 将输入框变更信息通过 send 方法发送到服务器
      if (sock.readyState === 1) 
      {
        sock.send(msg);
        console.log('消息发送---success!');
      } 
      else
      {
        console.log('消息发送---faild!');
      }  
    };
    
 
    /**
     * @name: 将data绑定值dataRef
     * @author: camellia
     * @email: guanchao_gc@qq.com
     * @date: 2021-01-10 
     */
    const dataRef = toRefs(data);
    return {
      close,
      ...dataRef
    }
  },
}

这里大概做一下解释,setup中的代码在页面加载完成的时候会执行,和webscoket相关的代码这里基本上都有注释。

我测试得到的结果:

前端:

a2.png

后端:

a3.png

这里就是使用原生代码测试一下,我们安装的swoole是否可以访问。

9:配置nginx支持webscoket

# webscoket配置
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}
upstream laravels {
    # Connect IP:Port # 此处的端口号要与laravel-s启动的端口号相同
    server 0.0.0.0:5200 weight=5 max_fails=3 fail_timeout=30s;
    keepalive 16;
}
# upstream swoole {
#     # Connect IP:Port
#     server 0.0.0.0:5200 weight=5 max_fails=3 fail_timeout=30s;
#     # Connect UnixSocket Stream file, tips: put the socket file in the /dev/shm directory to get better performance
#     #server unix:/yourpath/laravel-s-test/storage/laravels.sock weight=5 max_fails=3 fail_timeout=30s;
#     #server 192.168.1.1:5200 weight=3 max_fails=3 fail_timeout=30s;
#     #server 192.168.1.2:5200 backup;
#     keepalive 16;
# }
server {
        listen       443;
        server_name  xxx.xxx;#填写你的域名
        index index.html index.htm index.php;#默认打开页面
        root   /xx/xx/xxx/xxx/xx/public;#你的index.php路径
        # error_page 404 /index.html;
 
        autoindex off;
 
        #https配置
        ssl on;
        ssl_certificate   xxx/xxxx/xxxx_xxxx.xxx.pem;
        ssl_certificate_key  xxx/xxxx/xxxx_xxxx.xxx;
        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;
 
        #开启gzip功能,加快网站打开速度
        gzip on; 
        #开启gzip静态压缩功能
        gzip_static on; 
        #gzip缓存大小
        gzip_buffers 4 16k;
        #gzip http版本
        gzip_http_version 1.1;
        #gzip 压缩级别 1-10 
        gzip_comp_level 2;
        #gzip 压缩类型
        gzip_types text/plain application/javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;# 是否在http header中添加Vary: Accept-Encoding,建议开启gzip_vary on;
 
        proxy_read_timeout 60s;
 
        location ~ .php(.*)$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_split_path_info  ^((?U). .php)(/?. )$;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param  PATH_INFO  $fastcgi_path_info;
            fastcgi_param  PATH_TRANSLATED  $document_root$fastcgi_path_info;
            include        fastcgi_params;
        }
  
        # location /
        # {
        #         #如果是二级目录就用 rewrite ^/文件夹名称/(.*)$ /index.php?s=/$1 last;)
        #         if (!-e $request_filename)
        #         {
        #                 rewrite ^(.*)$ /index.php?s=/$1 last;
        #                 break;
        #         }
        # }
 
        # Nginx 处理静态资源,LaravelS 处理动态资源
        location / {
                index index.html;
                # vue 动态路由原始配置
                # try_files $uri $uri/ /index.html;
                # laravels 结合vue动态路由配置
                try_files $uri $uri @laravels/ /index.html;
        }
 
        # Http and WebSocket are concomitant, Nginx identifies them by "location"
        # !!! The location of WebSocket is "/ws"
        # Javascript: var ws = new WebSocket("ws://todo-s.test/ws");
        # 处理 WebSocket 通信
        location /websocket {
                proxy_connect_timeout 60s;
                proxy_send_timeout 60s;
                # proxy_read_timeout: Nginx will close the connection if the proxied server does not send data to Nginx in 60 seconds; At the same time, this close behavior is also affected by heartbeat setting of Swoole.
                proxy_read_timeout 60s;
                proxy_http_version 1.1;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Real-PORT $remote_port;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_set_header Scheme $scheme;
                proxy_set_header Server-Protocol $server_protocol;
                proxy_set_header Server-Name $server_name;
                proxy_set_header Server-Addr $server_addr;
                proxy_set_header Server-Port $server_port;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $connection_upgrade;
                proxy_pass http://127.0.0.1:5200; #此处的端口号要与laravel-s启动的端口号相同
 
        }
        
        # laravels 配置
        location @laravels {
                # proxy_connect_timeout 60s;
                # proxy_send_timeout 60s;
                # proxy_read_timeout 60s;
                proxy_http_version 1.1;
                proxy_set_header Connection "";
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Real-PORT $remote_port;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_set_header Scheme $scheme;
                proxy_set_header Server-Protocol $server_protocol;
                proxy_set_header Server-Name $server_name;
                proxy_set_header Server-Addr $server_addr;
                proxy_set_header Server-Port $server_port;
                proxy_pass http://127.0.0.1:5200; #此处的端口号要与laravel-s启动的端口号相同
        }
}

将上边我使用xxx代替的部分改成你自己的信息。

特别说明一下:我这里使用了ssl证书,如果您没有相关的配置,把https那部分换掉就好。

具体的配置含义,请参考官方文档:

github.com/hhxsv5/lara…

10:测试laravel-swoole

Laravel-swoole的优势就是将swoole插件集成至laravel-s插件中,当前laravel-s插件启动的时候,同时持久化的启动了swoole,不需要我们再服务器端再启动一次swoole。

经过我们上边的配置,基本上就已经启动了swoole,经过我们的测试,原生情况下,我们的swoole是没有问题的,如果在框架中测试出问题,那么只能是我们框架这边配置的问题,关于这方面laravel-swoole为我们提供了日志:

storage/logs目录下

我测试使用的前端代码:

import { useRouter } from "vue-router";
import {
  PropType,
  ref,
  watch,
  reactive,
  toRefs,
  inject,
  provide,
  onMounted
} from "vue";
// 引入公共js文件
import utils from "/@/assets/js/public/function";
// 定义返回的类型
interface dataRef {
  close: () => void;
}
export default {
  name: "Drawer",
  // VUE3语法 setup函数
  // setup官方文档:https://www.vue3js.cn/docs/zh/guide/composition-api-setup.html#参数
  setup(props: any, content:any): dataRef 
  {
    /**
     * @name: 声明data
     * @author: camellia
     * @email: guanchao_gc@qq.com
     * @date: 2021-01-10 
     */
    const data = reactive({
      drawerShow: common.drawerShow,
    });
    /**
     * @name: 关闭组件
     * @author: camellia
     * @email: guanchao_gc@qq.com
     * @date: 2021-01-10 
     */
    const close = () => {
      data.drawerShow = false;
      common.drawerShow = data.drawerShow;
    }
    // 初始化客户端套接字并建立连接
    var sock = new WebSocket("wss://guanchao.site/websocket/");
 
    // 连接建立时触发
    sock.onopen = (event) => {
      console.log("Connection open ...");
      change();
    }
 
    // 接收到服务端推送时执行
    sock.onmessage = (event) => {
      var msg = event.data;
      console.log(event);
      console.log("webscoket 接收到返回消息!");
    };
 
    // 连接关闭时触发
    sock.onclose = (event) => {
      console.log("Connection closed ...");
    }
    // 发送消息给webscoket
    const change = () => {
      var msg = "你好啊~";
      // 将输入框变更信息通过 send 方法发送到服务器
      if (sock.readyState === 1) 
      {
        sock.send(msg);
        console.log('消息发送---success!');
      } 
      else
      {
        console.log('消息发送---faild!');
      }  
    };
    
 
    /**
     * @name: 将data绑定值dataRef
     * @author: camellia
     * @email: guanchao_gc@qq.com
     * @date: 2021-01-10 
     */
    const dataRef = toRefs(data);
    return {
      close,
      ...dataRef
    }
  },
}

前端console显示:

a5.png

我这里基本上就算是链接成功了。

 

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanefhj
系列文章
更多 icon
同类精品
更多 icon
继续加载