2021-09-07

tp5.0配置workerman实现简单聊天功能

compopser安装workerman

composer require topthink/think-worker=1.0.*

Windows系统需要

composer require workerman/workerman-for-win

2021-09-07
出现以上界面代表应该安装成功了

在项目目录下新建server.php

#!/usr/bin/env php
<?php
define('APP_PATH', __DIR__ . '/application/');
define('BIND_MODULE','push/Worker');
// 加载框架引导文件
require __DIR__ . '/thinkphp/start.php';

新建worker类

<?php
namespace app\push\controller;

use think\worker\Server;

class Worker extends Server
{
    protected $socket = 'websocket://push.app:2346';

    /**
     * 收到信息
     * @param $connection
     * @param $data
     */
    public function onMessage($connection, $data)
    {
        $connection->send('我收到你的信息了');
    }

    /**
     * 当连接建立时触发的回调函数
     * @param $connection
     */
    public function onConnect($connection)
    {

    }

    /**
     * 当连接断开时触发的回调函数
     * @param $connection
     */
    public function onClose($connection)
    {
        
    }

    /**
     * 当客户端的连接上发生错误时触发
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function one rror($connection, $code, $msg)
    {
        echo "error $code $msg\n";
    }

    /**
     * 每个进程启动
     * @param $worker
     */
    public function onWorkerStart($worker)
    {

    }
}

项目根目录cmd,输入php server.php

2021-09-07
测试
浏览器下F12输入

ws = new WebSocket(“ws://push.app:2346”);
ws.onopen = function() {
alert(“连接成功”);
ws.send(‘tom’);
alert(“给服务端发送一个字符串:tom”);
};
ws.onmessage = function(e) {
alert(“收到服务端的消息:” + e.data);
};

继续测试

ws.send(‘保持连接,发第二次信息,查看服务器回应’);

实现简单聊天功能

1、新建woker控制器

<?php

namespace app\push\controller;

use think\worker\Server;
use Workerman\Worker as Work;
class Worker extends Server
{
    protected $socket = 'websocket://www.tp5.0.com:2346';
    protected $processes = 1;
    protected $uidConnections = array();
    static $count  = 0;

    /**
     * 收到信息
     * @param $connection
     * @param $data
     */
    public function onMessage($connection, $data)
    {
        // 判断当前客户端是否已经验证,既是否设置了uid,设置了直接发送消息,未设置第一次为设置uid
        if(!isset($connection->uid))
        {
            // 没验证的话把第一个包当做uid(这里为了方便演示,没做真正的验证)
            $connection->uid = $data;
            /* 保存uid到connection的映射,这样可以方便的通过uid查找connection,
             * 实现针对特定uid推送数据
             */
            $this->uidConnections[$connection->uid] = $connection;
            $data = '用户 '.$connection->uid.'加入房间 ||'.self::$count;
            $this->broadcast($data);
            return;
        }else{
            $data = '用户 '.$connection->uid.':'.$data.'||'.self::$count;
            $this->broadcast($data);
        }
    }

    /**
     * 当连接建立时触发的回调函数
     * @param $connection
     */
    public function onConnect($connection)
    {
        self::$count++;

    }

    /**
     * 当连接断开时触发的回调函数
     * @param $connection
     */
    public function onClose($connection)
    {
        self::$count--;
        if(isset($connection->uid))
        {
            // 连接断开时删除映射
            $data = '用户 '.$connection->uid.'退出房间 ||'.self::$count;
            $this->broadcast($data);
            unset($this->uidConnections[$connection->uid]);
        }
    }

    /**
     * 当客户端的连接上发生错误时触发
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function one rror($connection, $code, $msg)
    {
        echo "error $code $msg\n";
    }

    /**
     * 每个进程启动
     * @param $worker
     */
    public function onWorkerStart($socket)
    {

    }

// 向所有验证的用户推送数据
    function broadcast($message)
    {
        foreach($this->uidConnections as $connection)
        {
            $connection->send($message);
        }
    }

// 针对uid推送数据
    function sendMessageByUid($uid, $message)
    {
        if(isset($this->uidConnections[$uid]))
        {
            $connection = $this->uidConnections[$uid];
            $connection->send($message);
            return true;
        }
        return false;
    }
}

2、Index控制器

<?php
namespace app\index\controller;
use think\Controller;

class Index extends Controller
{
    public function index(){
        $name=$_GET['name'];
        $this->assign('name',$name);
        return $this->fetch();
    }
}

3、index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>聊天室</title>
</head>
<body>
<div class="title" style="display: inline-block">当前聊天室<span id="count">0</span>人</div>
<hr/>
<div id="aaa" class="conten title"></div>
<div class="fasong title">
    <textarea id="textxinxi" class="xinxi"></textarea>
    <input type="button" value="发送" class="fasongbtn" onclick="fasong()">
</div>


<script>
    var name = "{$name}";
    ws = new WebSocket("ws://www.tp5.com:2346");
    ws.onopen = function() {
        var uid = name;
        ws.send(uid);

    };
    ws.onmessage = function(e) {
        var aaa = document.getElementById('aaa');
        var count = document.getElementById('count');
        var data = e.data.split('||')[0];//根据||截取字符串,前面为放内容,后面为当前聊天室人数
        var count1 = e.data.split('||')[1];
        aaa.innerHTML += data + '<br/>';// 插入新的两天内容
        count.innerHTML = count1;// 修改聊天室人数
    };

    function fasong() {
        let textxinxi = document.getElementById('textxinxi').value;
        let text = '';
        document.getElementById('textxinxi').value = text;//发送新内容
        ws.send(textxinxi);
    }


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

不同浏览器访问

2021-09-07

上一篇:一个使用Room库的实例


下一篇:2021-09-20