thinkphp下使用swoole

安装扩展

手动安装

下载地址
https://www.swoole.com/page/download

cd swoole
phpize
./configure --enable-openssl --with-php-config=/www/server/php/72/bin/php-config
make
sudo make install
修改php.ini加入
extension=swoole.so

宝塔安装

在这里插入图片描述
记得去除禁用函数
在这里插入图片描述

安装tp扩展

composer require topthink/think-swoole=2.0.*
php public/index.php im/Index/start

再开个终端
lsof -i:39001  //对应设置的端口号

在这里插入图片描述

开始使用

控制器

<?php

namespace app\im\controller;

use think\swoole\Server;
use think\db;

class IndexController extends Server
{
    protected $host = '0.0.0.0'; //监听所有地址
    protected $port = 39001; //监听39001端口
    protected $serverType = 'socket';
    //开启wss
    protected $sockType = SWOOLE_SOCK_TCP | SWOOLE_SSL;
    protected $option = [
        'ssl_cert_file' => '/www/wwwroot/server.crt',//https时开启
        'ssl_key_file' => '/www/wwwroot/server.key',//https时开启
        'worker_num' => 4, //设置启动的Worker进程数
        'daemonize' => false, //守护进程化(上线改为true)
        'max_request' => 10000,
        'dispatch_mode' => 2, //固定模式,保证同一个连接发来的数据只会被同一个worker处理
        'debug_mode' => 1,
        //心跳检测:每60秒遍历所有连接,强制关闭10分钟内没有向服务器发送任何数据的连接
        'heartbeat_check_interval' => 60,
        'heartbeat_idle_time' => 600
    ];

    //建立连接时回调函数
    function onOpen($server, $req)
    {
        $fd = $req->fd; //客户端标识
        $uid = $req->get['uid']; //客户端传递的用户id
        $this->bind($uid, $req->fd);
        echo "用户{$uid}建立了连接,标识为{$fd}\n";
    }

    //接收数据时回调函数
    public function onMessage($server, $frame)
    {
        $fd = $frame->fd;
        $message = json_decode($frame->data);
        $tid = $message->tid;
        $uid = $message->uid;
        
        $tfd = $this->getFd($tid);

        $data['uid'] = $uid;
        $data['message'] = $message->content;
        $data['post_time'] = date("m/d H:i", time());
        $arr = array('status' => 1, 'message' => 'success', 'data' => $data);
        $this->add($uid, $tid, $message->content); //保存消息

        $server->push($fd, json_encode($arr));

        $fds = []; //所有在线的用户(打开聊天窗口的用户)

        foreach ($server->connections as $fd) {
            array_push($fds, $fd);
        }

        //推送给接收者
        if (in_array($tfd, $fds)) {
            $server->push($tfd, json_encode($arr));
        }

        //推送给全部连接用户
        // foreach($server->connections as $fd) {
        //     $server->push($fd, json_encode($arr));
        // } 
    }

    public function add($fid, $tid, $content)
    {
        $arr = ['fid' => $fid, 'tid' => $tid, 'content' => $content, 'time' => date("y/m/d H:i", time())];
        Db::name('msg')->insertGetId($arr);
    }

    public function getFd($uid)
    {
        //$data = Db::name('friends')->where('uid', $uid)->find();
        $data = cache('uid' . $uid);
        return $data['fid'];
    }

    public function bind($uid, $fd)
    {
        $value = ['uid' => $uid, 'fid' => $fd];
        cache('uid' . $uid, $value, 1800);
        //Db::name('friends')->insert($value, true);
        return true;
    }

    //连接关闭时回调函数
    public function onClose($server, $fd)
    {
        Db::name('fd')->where('fid', $fd)->delete();
    }
}

前端

<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>swoole</title>
    <script src="__TMPL__/demo/public/assets/js/vue.js"></script>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/layer/3.1.0/layer.js"></script>
</head>

<body>

    <div id="app">
        <ol>
            <li v-for="message in messages">
                {{message.message}} -- {{message.post_time}}
            </li>
        </ol>
        <input v-model="message">
        <button v-on:click="sentMessage">发送</button>
    </div>

    <script>
        var client = null;

        var uid = 2; //当前用户id
        var tid = 1; //接受消息用户ID

        var app = new Vue({
            el: '#app',
            data: {
                message: 'Hello swoole!',
                messages: []
            },
            methods: {
                sentMessage: function () {
                    if (this.message == null || this.message == "") {
                        layer.msg('内容为空', {
                            shade: 0.1,
                            icon: 2,
                            time: 600
                        });
                        return false;
                    } else {
                        var Data = {
                            content: this.message,
                            uid: uid,
                            tid: tid,
                        }
                        client.send(JSON.stringify(Data));
                        this.message = '';
                    }
                }
            }
        });


        client = new WebSocket("wss://你的域名:39001?uid=" + uid);

        client.onopen = function () {
            layer.msg('服务器连接成功', {
                shade: 0.1,
                icon: 1,
                time: 600
            });
        };

        client.onerror = function () {
            layer.msg('服务器连接失败', {
                shade: 0.1,
                icon: 2,
                time: 600
            });
        };

        client.onmessage = function (evt) {
            var data = JSON.parse(evt.data);
            console.log(data);
            //错误提示
            if (data.status != 1) {
                layer.alert(data.message, {
                    icon: 2
                });
                return;
            }
            //消息返回
            if (data.status == 1 && data.data.message != '') {
                app.messages.push(data.data);
            }
        };
        client.onclose = function (res) {
            console.log(res)
        };
    </script>
</body>

</html>
发布了70 篇原创文章 · 获赞 25 · 访问量 3687

猜你喜欢

转载自blog.csdn.net/weixin_43993175/article/details/104884028