zoukankan      html  css  js  c++  java
  • ThinkPHP 5.1下使用PHPSocket.IO实现websocket通讯

    https://beltxman.com/1885.html

    PHPSocket.IO的官方介绍:

    PHPSocket.IO是PHP版本的Socket.IO服务端实现,基于workerman开发,用于替换node.js版本Socket.IO服务端。PHPSocket.IO底层采用websocket协议通讯,如果客户端不支持websocket协议, 则会自动采用http长轮询的方式通讯。PHPSocket.IO实现的Polling通信机制包括Adobe Flash Socket、AJAX长轮询、JSONP轮询等。具体采用哪种机制通讯对于开发者完全透明, 开发者使用的是统一的接口。

    项目github地址https://github.com/hsu1943/thinksocketio,项目已经做了很多更新,请按照项目readme使用。

    下面我们使用ThinkPHP5.1框架来整合PHPSocket.IO实现客户端和服务端的通讯。

    使用的本地开发环境是PHP5.6.30 + Apache2.4.25

    创建新项目

    // 使用ThinkPHP5.1新建项目thinksocket;
    $ composer create-project topthink/think thinksocket 5.1.*;
    // 进入项目,下载workerman/phpsocket.i包;
    $ cd thinksocket
    $ composer require workerman/phpsocket.io
    
    Bash

    这样你的安装工作就做好了。接下来配置需要的模

    配置模块

    结合前阵子的文章:ThinkPHP 5.1自动生成模块及目录、文件
    我们编辑好build.php文件:

    return [
        // 生成应用公共文件
        '__file__' => ['common.php'],
        // 定义socketio模块的自动生成
        'socketio'     => [
            '__file__'   => ['common.php'],
            '__dir__'    => ['controller', 'model', 'view'],
            'controller' => ['Index', 'Server'],
            'model'      => [],
            'view'       => ['index/index'],
        ],
        // 其他更多的模块定义
    ];
    
    PHP

    然后运行

    $ php think build
    Successed
    
    Bash

    这样就有了socketio模块下面controllerIndex.phpServer.php两个控制器和view下一个index/index一个视图。

    创建服务端

    编辑控制器Server.php为(具体参考注释):

    <?php
    namespace appsocketiocontroller;
    
    use WorkermanWorker;
    use PHPSocketIOSocketIO;
    use thinkDb;
    
    class Server{
    
        public function index(){
            // 在2021端口创建服务
            $io = new SocketIO(2021);
            $io->on('connection', function($socket)use($io){
                $socket->on('chat message', function($msg)use($io){
                    $io->emit('chat message', $msg);
                });
                // 监听到新的客户端连接即在服务端输出'new connection'
                echo 'new connection'."
    ";
                // 并向服务端发送'连接成功'
                $socket->emit('success', '连接成功');
                // 服务端发送消息过来
                $socket->on('sendMsg', function($msg)use($io){
                    // 在服务端输出消息
                    echo $msg."
    ";
                    // 在收到的消息前面拼接'收到'后向客户端发送回去
                    $io->emit('sendMsg', '收到"'.$msg.'"');
                    // 将接受到的消息存储到数据库
                    $data['msg'] = $msg;
                    Db::table('msg')->insert($data);
                });
            });
            // 启动服务
            Worker::runAll();
        }
        // 测试数据库链接
        public function ceshi(){
            $msg = Db::table('msg')->select();
            var_dump($msg);
        }
    }
    
    PHP

    为了测试,在数据库新建了一张表msg用来存储客户端发送过来的消息。

    CREATE TABLE `msg` (
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `msg` varchar(250) DEFAULT NULL,
      `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4;
    
    SQL

    这样一个可以返回连接成功消息、接收消息、回复消息、存储消息的简单服务端就做好了。

    创建客户端

    我们在Index.php控制器中这样写:

    <?php
    namespace appsocketiocontroller;
    
    use thinkController;
    
    class Index extends Controller
    {
        public function index()
        {
            return view();
        }
    }
    
    PHP

    在对应的模版文件view/index/index.html中代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>测试WebSocket</title>
    </head>
    <body>
    
    <input type="text" name="" id="msg">
    <button id='send'>发送消息</button>
    
    </body>
    <script src='https://cdn.bootcss.com/socket.io/2.0.3/socket.io.js'></script>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script>
    // 如果服务端不在本机,请把127.0.0.1改成服务端ip
    var socket = io('http://127.0.0.1:2021');
    // 当连接服务端成功时触发connect默认事件
    socket.on('connect', function(){
        console.log('connect success');
    });
    socket.on('success', function(msg){
        // 连接后弹出服务端返回的消息'连接成功'
        alert(msg);
    });
    
    socket.on('sendMsg', function(msg){
        // 将服务端返回的消息输出到控制台
        console.log(msg);
    });
    
    // 向服务端发送消息
    $('#send').on('click', function(){
        var text = $('#msg').val();
        socket.emit('sendMsg', text);
        // alert(text);
    })
    </script>
    </html>
    
    HTML

    到这里,一个具备连接服务端,发送消息,接受并输出消息到控制台的简单websocket客户端就建好了。

    为服务端绑定入口文件

    在项目的public文件夹下新建一个入口文件server.php并将其绑定到socketio模块的Server控制器index方法;
    入口文件server.php代码:

    <?php
    // [ 应用入口文件 ]
    namespace think;
    
    // 加载基础文件
    require __DIR__ . '/../thinkphp/base.php';
    
    // 执行应用并响应(绑定)
    Container::get('app')->bind('socketio/Server')->run()->send();
    
    PHP

    测试通讯

    运行服务端
    直接运行项目public目录下的server.php

    D:xampphtdocs	hinksocketpublic>php server.php
    ----------------------- WORKERMAN -----------------------------
    Workerman version:3.5.11          PHP version:5.6.30
    ------------------------ WORKERS -------------------------------
    worker               listen                              processes status
    PHPSocketIO          socketIO://0.0.0.0:2021             1         [ok]
    
    Bash

    ThinkPHP 5.1下使用PHPSocket.IO实现websocket通讯
    这个输出表示PHPSocketIO已经成功在2021端口运行监听中。
    我们打开浏览器打开http://localhost/thinksocket/public/index.php/socketio/页面;
    可以看到页面会弹出‘链接成功’,同时可以看到服务端cmd终端上打印出new connection,同事浏览器控制台会输出connect success,代表已经成功与服务端连接上。
    测试发送消息
    在页面输入框内输入任意信息,服务端cmd终端将会打印信息,代表服务端收到信息,然后服务端控制台将会输出‘收到’+发送的信息。
    至此,我们的测试完成。

    温馨提示:对程序修改后需要重新启动服务端才能生效

    以上只是简单的利用ThinkPHP5.1的框架测试PHPSocket.IO通讯。

    源代码地址:https://github.com/hsu1943/thinksocketio
    供大家参考。

    update (代码以Github为准)

      • 2019/01/22:Github项目代码已经更新,加入了用户唯一表示记录以及向指定用户推送消息。详情看:ThinkPHP 5.1+PHPSocket.IO实现websocket搭建聊天室+私聊
      • 2019-06-19 增加在线人数统计,在线用户列表,修改昵称,添加系统主动推送接口(广播或私信);
  • 相关阅读:
    返回一个整数数组中最大子数组的和
    软件工程概论第五周学习进度
    软件工程概论第四周学习进度
    软件工程个人作业03
    软件工程概论第三周学习进度
    软件工程个人作业02
    软件工程概论学习进度第二周
    寻找水王
    第七周学习进度
    二维数组最大值
  • 原文地址:https://www.cnblogs.com/slqgenius/p/12187396.html
Copyright © 2011-2022 走看看