(在项目中学习技术)完成使用swoole完成App二维码扫码登录网页端的操作

前言:大家好,我自己有一个项目完成度已经很高了,我自己的技术怎么说也不是太强,在完成这个项目中我学习很多知识,比如说使用swoole实现二维码登录,说实在的,我本身是一个前端,但是日常学习和工作中也会写一下php代码,swoole怎么说呢,也算是专业对口,在断断续续研究一个星期后,我也完成了app扫码登录的功能,怎么说,也算有个新技术傍身,到时候面试的时候还可以跟面试官吹吹牛。 首先呢先要介绍下我这个某某项目的要求和情况,因为毕竟有版权,我不会透露什么项目实际名称,实际上呢是这样的,这个项目分为安卓端(原生),ios端(原生),和网页端(vue),安卓和ios我不懂,这是别人完成的,我们这期的技术是使用swoole二维码登录,这当然是大部分网页端需要实现的功能,苦逼的我只能看了又看,做了又做了。 其实swoole的部署实际是后端接口api的事情,但是我们是一个小项目,php我也会弄,所以就兼职了一下,前面说了这么多,我们就不废话了,开始吧 什么是swoole,我其实不知道,因为用过php,我一直以为是php某个框架上的功能,我把扩展加上去就可以用了,比如laravel框架什么的,看了一个星期的,怎么说呢,其实不是这个样子,因为swoole其实是一个服务器,我们在实现代码后,swoole就会如同apache一样,你去访问请求这个地址,他会根据代码来输出数据,跟apache真的很像,而我们使用了他socket功能,先使用网页(就是请求)访问跟他这个swoole服务器建立连接后,我们会返回一个通道的id,这个id会通过二维码展示出来,然后手机去扫描这个二维码后,获得这个id,然后将手机登录时候获得token(登录验证唯一数据,需要安全保存)和这个id发送给这个swoole服务器连接通道(通过id来判断是哪个通道),通道收到请求后,会发送请求给网页,这个请求数据就包含token,然后网页把token保存起来,再跳转到主页,完成了登录,随后关闭swoole通道连接。

下面我通过代码来给大家解释

首先我们要给php加上swoole的扩展这个具体的请看我MAMP安装swoole记录,踩坑记录

1.新建swoole服务器

php 复制代码
$this->server = new Swoole\WebSocket\Server("127.0.0.1", 9501);

2.监听swoole服务是否运行

php 复制代码
$this->server->on('start', function ($server) { echo "Websocket Server is started at ws://127.0.0.1:9501\n"; });

3.swoole运行后,监听是否有人和swoole建立了连接,前端如果swoole建立了连接,相当于一个通道,他们之间就可以互相发送信息(1)前端建立与swoole连接后

swoole代码: js代码前端连接swoole服务器的代码

js 复制代码
function handShake() {
    qrCodeData.status = 'start'
    qrCodeData.errorInfo = '正在加载'
    getLoginQrCodeUrl()
    var wsServer = 'ws://127.0.0.1:9501';

    var websocket = new WebSocket(wsServer);
    //如果与服务器链接成功,则生成url二维码
    websocket.onopen = function () {
        qrCodeData.status = 'ready'
        qrCodeData.errorInfo = '服务器连接成功'
        websocket.send(JSON.stringify({ test: data.login }));
    };

    websocket.onclose = function () {
        if (qrCodeData.status != 'error') {
            qrCodeData.errorInfo = '二维码失效,请重新链接'
            qrCodeData.status = 'close'
        }
    };

    websocket.onmessage = function (evt) {
        console.log('Retrieved data from server: ' + evt.data);
        let userInfo = JSON.parse(evt.data)
        store.dispatch('test/login', { ...userInfo }).then(() => {
            router.push({ path: '/' })
            websocket.close()
        })
    };

    websocket.onerror = function (evt, e) {
        console.log('Error occured: ' + evt.data);
        console.log(e)
        qrCodeData.status = 'error'
        qrCodeData.errorInfo = '服务器连接错误,请查看网络连接'
    };
}

4.完成前端代码连接大米 我们给php加上swoole的扩展,完成后 新建server文件夹后,在文件夹新建run.php的文件 然后写下以下代码

php 复制代码
<?php
//创建一个对象Swoole_Lite的对象实例
$swooleLite = new Swoole_Lite();

//类声明Swoole_Lite,其中有个构造函数__construct,实例化的同时就会运行此函数,实际上就是把需要运行的函数都放在了__construct
class Swoole_Lite
{
    public $server;
    public $table;
    public function __construct()
    {
        //实例化表格,参数 int : 最大行数 
        //$this->table实际上为了存储前端和swoole连接后的通道id
        $this->table = new swoole_table(1024);
        //设置表格字段  参数 (字段名:string , 字段类型:int、float、string , 长度:int)
        $this->table->column('id',$this->table::TYPE_INT,11);
        //创建表格
        $this->table->create();
        $this->server = new Swoole\WebSocket\Server("127.0.0.1", 9501);
        //设置心跳检测60秒时间内没有数据,自动关闭
        $this->server->set([
            'heartbeat_check_interval' => 30,
            'heartbeat_idle_time'      => 60,
        ]);
        $this->server->on('start', function ($server) {
            echo "Websocket Server is started at ws://127.0.0.1:9501\n";
        });

        $this->server->on('open', function (Swoole\WebSocket\Server $server, $request) {
            echo "server: handshake success with fd{$request->fd}\n";
        });

        $this->server->on('message', function (Swoole\WebSocket\Server $server, $frame)  {
            $data = json_decode($frame->data);
            //判断是否有重复websocket链接,关闭它 通过login来判断
            $this->disconnectRepeatWebSocket($data->login);
            $this->table->set($data->login,['id'=>$frame->fd]);
            // echo $table[$data->login];
            // echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
            // $server->push($frame->fd, "this is server");
        });
        $this->server->on('close', function ($ser, $fd) {
            foreach ($this->table as $key => $value) {
                if($value['id'] == $fd){
                    $this->table->del($key);
                }
            }
            $ser->push($fd,'close');
        });


        $this->server->on('request', function ($request, $response)  {
            $result = array('ret'=>'404','data'=>array('err_code'=>'1','ip'=>$request->server['remote_addr']),'msg'=>'没有可用的连接');
            $response->header('Content-Type', 'text/plain');
            $response->header('Charset', 'utf-8');
            var_dump($request->post);
            foreach ($this->table as $key => $value) {
                var_dump($key);
            }
            if ($this->server->isEstablished($this->table->get($request->post['login'],'id'))) {
                $userInfo = json_encode($request->post);
                $this->server->push($this->table->get($request->post['login'],'id'),$userInfo);
                $result['ret'] = '200';
                $result['data']['err_code'] = '0';
                $result['msg'] = '发送登录信息成功';
            }
            $response->end(json_encode($result));
    
        });
        $this->server->start();
    }

    function disconnectRepeatWebSocket($login){
        if($login){
            if($this->table->exist($login)){
                $this->server->isEstablished($table->get($login, 'id')) &&  $this->server->disconnect($table->get($login, 'id'));
                $this->table->del($login);
            }
        }
    }
    // //发送用户数据给web端,实现登录
    // function pushMessageToWeb($fd,$post_data){
    //     $this->server->push($fd,json_encode($post_data));
    // }
}

这段代码我也是从网上找来的,其中改了点地方,时间很长了,我也记不住了改动了哪里,我说下我的理解吧,也请大家指正, 首先我们先启动swoole服务, 使用cmd或者终端输入 php /路径/server/run.php

如下图 这就表示swoole服务器启动成功了。这样就完成了二维码扫码的功能实现。 哈哈,肯定不能这样结束,我刚刚只是告诉大家怎么使用swoole,并且贴上了代码 下面我还要给大家介绍下二维码登录时怎么实现的,以及解读下前端和swoole还有后端的代码,那我们就开始吧。swoole的run.php的代码分析我就写上面代码块中,一步步地分析,大家可以看下上面的代码注释,

相关推荐
IT_陈寒4 小时前
闭包陷阱让我加了两天班,JavaScript你真行
前端·人工智能·后端
易协同低代码5 小时前
通达OA核心类库TD类深度解析
后端
Gopher_HBo5 小时前
Go语言学习笔记(十八)Gin处理Session
后端
谭光志6 小时前
工具塞满上下文窗口怎么办?深度拆解 AI Agent Tool Search 按需加载实现原理
前端·后端·ai编程
她说..6 小时前
Java 默认值设置方式
java·开发语言·后端·springboot
foggyprojects6 小时前
从0开始,一句话启动AI DataAgent
后端·数据分析·ai编程
郡杰6 小时前
一些基础和问题解决
后端
陈随易6 小时前
前端项目部署只要30秒
前端·后端·程序员
YIAN6 小时前
从零手写文件读取 MCP 服务:一文吃透 Model Context Protocol 全链路通信原理
前端·后端·mcp
Imchendiana6 小时前
《狂人日记NO.9》— 前后端一把梭,我的全栈实录
前端·后端