导读:本期聚焦于小伙伴创作的《Workerman 5.0实战:PHP实现WebSocket一对一即时聊天系统》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Workerman 5.0实战:PHP实现WebSocket一对一即时聊天系统》有用,将其分享出去将是对创作者最好的鼓励。

Workerman 5.0实战:PHP实现WebSocket一对一即时聊天系统

PHP调用Workerman 5.0实现一对一聊天实战指南

在即时通讯场景中,一对一聊天是最基础且核心的功能。Workerman是一款高性能的PHP Socket框架,其5.0版本对PHP8有了更好的支持。本文将详细讲解如何使用PHP结合Workerman 5.0实现一个稳定、高效的WebSocket一对一聊天系统。

一、环境要求与安装

Workerman 5.0要求PHP版本大于等于8.0。首先,通过Composer安装Workerman:

composer require workerman/workerman ^5.0

安装完成后,我们就可以开始编写服务端代码。

二、服务端核心逻辑实现

一对一聊天的核心在于将用户的唯一标识(UID)与对应的WebSocket连接进行绑定。当用户A向用户B发送消息时,服务端通过B的UID找到对应的连接,并将消息推送过去。

创建服务端文件chat.php,具体代码如下:

<?php
use WorkermanWorker;
require_once __DIR__ . '/vendor/autoload.php';

// 全局数组,保存uid到connection的映射
$uidConnectionMap = [];

$ws_worker = new Worker("websocket://0.0.0.0:8282");
// 设置进程数,单进程方便演示映射关系,生产环境建议多进程配合Redis共享
$ws_worker->count = 1;

$ws_worker->onMessage = function ($connection, $data) use (&$uidConnectionMap) {
    $msg = json_decode($data, true);
    if (!$msg) {
        return;
    }

    switch ($msg['type']) {
        case 'login':
            // 绑定uid与connection
            $uid = $msg['uid'];
            $connection->uid = $uid;
            $uidConnectionMap[$uid] = $connection;
            $connection->send(json_encode(['type' => 'login', 'status' => 'success']));
            break;
        case 'chat':
            $toUid = $msg['to_uid'];
            $content = $msg['content'];
            if (isset($uidConnectionMap[$toUid])) {
                // 目标用户在线,直接推送
                $uidConnectionMap[$toUid]->send(json_encode([
                    'type' => 'chat',
                    'from_uid' => $connection->uid,
                    'content' => $content
                ]));
            } else {
                // 目标用户不在线
                $connection->send(json_encode(['type' => 'error', 'msg' => '对方不在线']));
            }
            break;
    }
};

$ws_worker->onClose = function ($connection) use (&$uidConnectionMap) {
    // 连接断开时清除映射
    if (isset($connection->uid)) {
        unset($uidConnectionMap[$connection->uid]);
    }
};

Worker::runAll();

在上述代码中,我们使用全局变量$uidConnectionMap来维护用户ID与连接的映射。客户端在连接后需要先发送login类型的消息进行身份绑定,随后即可通过指定to_uid发送chat类型的消息。

三、客户端前端实现

客户端需要实现WebSocket的连接、登录绑定以及消息的发送与接收。前端代码实现如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Workerman一对一聊天</title>
</head>
<body>
    <input type="text" id="uid" placeholder="我的ID">
    <button onclick="login()">登录</button><br><br>
    <input type="text" id="to_uid" placeholder="对方ID">
    <input type="text" id="msg" placeholder="消息内容">
    <button onclick="send()">发送</button>
    <div id="chat-box" style="margin-top:20px; border:1px solid #ccc; height:300px; overflow-y:auto;"></div>

    <script>
    // 替换为实际的WebSocket服务地址
    var ws = new WebSocket("ws://www.ipipp.com:8282");
    var chatBox = document.getElementById('chat-box');

    ws.onopen = function() {
        chatBox.innerHTML += '<p>连接服务器成功</p>';
    };

    ws.onmessage = function(e) {
        var data = JSON.parse(e.data);
        if (data.type === 'chat') {
            chatBox.innerHTML += '<p>来自 ' + data.from_uid + ': ' + data.content + '</p>';
        } else if (data.type === 'login') {
            chatBox.innerHTML += '<p>登录成功</p>';
        } else if (data.type === 'error') {
            chatBox.innerHTML += '<p style="color:red;">系统: ' + data.msg + '</p>';
        }
    };

    function login() {
        var uid = document.getElementById('uid').value;
        if (!uid) return alert('请输入ID');
        ws.send(JSON.stringify({type: 'login', uid: uid}));
    }

    function send() {
        var toUid = document.getElementById('to_uid').value;
        var msg = document.getElementById('msg').value;
        if (!toUid || !msg) return alert('请填写对方ID和消息');
        ws.send(JSON.stringify({type: 'chat', to_uid: toUid, content: msg}));
        chatBox.innerHTML += '<p style="text-align:right;">我: ' + msg + '</p>';
    }
    </script>
</body>
</html>

客户端通过原生的WebSocket API与服务端通信。用户输入自己的ID进行登录绑定,然后输入对方的ID和消息内容进行发送。服务端会将消息路由到指定的UID连接上。

四、运行与测试

在命令行中启动Workerman服务:

php chat.php start

打开两个浏览器窗口,分别访问前端页面。一个窗口登录UID为1,另一个登录UID为2。在UID为1的窗口中,对方ID输入2,填写消息发送,即可在UID为2的窗口中看到收到的消息。

五、生产环境注意事项

本文示例为了直观展示一对一通信原理,使用了PHP变量$uidConnectionMap来存储映射关系,且设置了单进程运行。在生产环境中,Workerman通常会开启多进程以充分利用多核CPU。此时,内存中的变量无法跨进程共享,必须使用Redis等存储组件来维护UID到进程的映射关系,结合Workerman的Channel组件实现跨进程消息推送。此外,还需补充心跳机制定时清理僵尸连接,保证服务长期稳定运行。

PHPWorkermanWebSocket即时通讯一对一聊天

免责声明:已尽一切努力确保本网站所含信息的准确性。网站部分内容来源于网络或由用户自行发表,内容观点不代表本站立场。本站是个人网站免费分享,内容仅供个人学习、研究或参考使用,如内容中引用了第三方作品,其版权归原作者所有。若内容触犯了您的权益,请联系我们进行处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。前端、网络、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握网站开发与运维所需的核心技术栈。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端逻辑,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。