Ratchet实现PHP WebSocket多人聊天功能的示例

这篇具有很好参考价值的文章主要介绍了Ratchet实现PHP WebSocket多人聊天功能的示例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  

  • composer 安装ratchet
    composer require cboden/ratchet
  • 使用PDO连接数据库,创建mysql命令如下
    CREATE TABLE messages (
        id INT AUTO_INCREMENT PRIMARY KEY,
        message TEXT NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );
  • 使用Redis存储消息列表

这个示例代码中,PHP代码使用Ratchet来创建WebSocket服务器,并实现了简单的聊天功能。HTML代码使用JavaScript来建立WebSocket连接,并处理消息传输和用户输入。要运行此代码,请确保已安装Ratchet并在终端中运行PHP文件。然后,通过打开浏览器并访问HTML代码所在的地址,就可以开始聊天了。

 在onMessage方法中,我们首先将接收到的消息存入Redis列表中。然后,如果Redis中的消息数量超过1000,则将所有消息取出并依次存入MySQL中。请注意,在MySQL中执行多个INSERT语句时,最好使用事务(即BEGIN、COMMIT语句)来确保数据的完整性。

 WebSocket服务端代码:

<?php

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

require_once __DIR__ . '/vendor/autoload.php';

class Chat implements MessageComponentInterface
{
    protected $clients;
    protected $pdo;
    protected $redis;

    public function __construct()
    {
        $this->clients = new \SplObjectStorage;

        // 连接到数据库
        $dsn = 'mysql:host=localhost;dbname=chat';
        $username = 'root';
        $password = '';
        $options = [
            \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
            \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC
        ];
        $this->pdo = new \PDO($dsn, $username, $password, $options);

        // 连接到 Redis
        $this->redis = new \Redis();
        $this->redis->connect('localhost', 6379);
    }

    public function onOpen(ConnectionInterface $conn)
    {
        $this->clients->attach($conn);
        echo "New connection! ({$conn->resourceId})\n";
    }

    public function onMessage(ConnectionInterface $from, $msg)
    {
        foreach ($this->clients as $client) {
            if ($from !== $client) {
                $client->send($msg);
            }
        }

        // 将消息存入 Redis
        $this->redis->rpush('messages', $msg);

        // 如果 Redis 中的消息数量超过 1000,则将消息存入数据库
        if ($this->redis->llen('messages') > 1000) {
            $messages = $this->redis->lrange('messages', 0, -1);

            // 开始事务
            $this->pdo->beginTransaction();

            foreach ($messages as $message) {
                // 将消息存入数据库
                $stmt = $this->pdo->prepare('INSERT INTO messages (message) VALUES (?)');
                $stmt->execute([$message]);

                // 从 Redis 中删除已经存入数据库的消息
                $this->redis->lpop('messages');
            }

            // 提交事务
            $this->pdo->commit();
        }
    }

    public function onClose(ConnectionInterface $conn)
    {
        $this->clients->detach($conn);
        echo "Connection {$conn->resourceId} has disconnected\n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e)
    {
        echo "An error has occurred: {$e->getMessage()}\n";
        $conn->close();
    }
}

$webSocketServer = new \Ratchet\WebSocket\WsServer(new Chat());
$server = \Ratchet\Server\IoServer::factory(
    new \Ratchet\Http\HttpServer($webSocketServer),
    8080
);

$server->run();

 开启socket服务命令,假设php文件名为socket.php

php ./socket.php

 HTML代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>WebSocket Chat</title>
</head>
<body>
    <div id="messages"></div>
    <form>
        <input type="text" id="message" placeholder="Enter message">
        <button type="submit">Send</button>
    </form>
    
    <script>
        var conn;
        var connect = function() {
            conn = new WebSocket('ws://localhost:8080');
            
            conn.onopen = function(e) {
                console.log("Connection established!");
            };
            
            conn.onmessage = function(e) {
                var messages = document.getElementById("messages");
                var message = document.createElement("div");
                message.innerHTML = e.data;
                messages.appendChild(message);
            };
            
            conn.onclose = function(e) {
                console.log("Connection closed, attempting to reconnect...");
                setTimeout(connect, 1000);
            };
        };
        
        connect();
        
        var form = document.querySelector("form");
        var input = document.querySelector("#message");
        
        form.addEventListener("submit", function(e) {
            e.preventDefault();
            
            conn.send(input.value);
            input.value = "";
        });
    </script>
</body>
</html>

保证WebSocket服务一直开启,可以使用一个常驻进程管理工具supervisor,使用supervisor的示例配置链接。文章来源地址https://www.toymoban.com/news/detail-678742.html

到了这里,关于Ratchet实现PHP WebSocket多人聊天功能的示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 53、springboot对websocket的支持有两种方式-------1、基于注解开发 WebSocket ,简洁实现多人聊天界面

    –注解就是: @OnOpen、 @OnClose 、 @OnMessage 、@OnError这些 ▲ Spring Boot为WebSocket提供了两种开发方式: 基于spring-boot-starter-websocket.jar开发WebSocket 基于Spring WebFlux开发WebSocket 两种方式对比: springboot API Socket:套接字。 插座。 在通信的两端分别建立虚拟的Socket(插座),网络协议

    2024年02月09日
    浏览(27)
  • 【Unity】Socket网络通信(TCP) - 实现简单的多人聊天功能

    多客户端连接服务器其原理是在服务端保存客户端连入后与客户端通信的socket,由于等待客户端连接会阻塞主线程,所以结合多线程就能实现多客户端连入功能。多人聊天只需要将A客户端发来的消息,转发给除A客户端外的其他客户端,即可实现。如果你还不怎么熟悉服务端

    2024年02月03日
    浏览(51)
  • 使用WebSocket实现聊天功能

    使用WebSocket实现一对一的聊天功能与未读消息功能 会话表 字段名 字段类型 长度 注释 conversation_id int 11 会话ID create_time datetime 创建时间 conversation_type int 1 会话类型 消息表 字段名 字段类型 长度 注释 message_id int 11 消息ID conversation_id int 11 会话ID sender_id int 11 发送者ID receiver

    2024年02月11日
    浏览(31)
  • WebSocket实现聊天功能

    使用SpringBoot + WebSocket 实现模拟QQ聊天功能 源码地址:https://gitee.com/mmolu/ws-chat 登录界面展示 登录界面模仿QQ登录操作,支持拖动、最小化和关闭 聊天界面展示 登录后的右侧显示在线用户,右下方显示在线用户的登录日志 窗口支持拖动、关闭操作 发送消息界面展示 在线用户实

    2024年02月03日
    浏览(25)
  • php - 超详细 thinkphp + redis 实现商品秒杀抢购功能,提供完整流程详细讲解及企业级功能示例源代码,环境准备、数据库表设计、并发压力测试等(新手小白一看就懂!)

    很多文章都已经过时了,而且还不讲原理,本文一次性说清楚。 很多电商系统几乎都有秒杀功能,那么用 tp+redis 怎么实现呢? 本文详细讲解商品秒杀功能的实现,提供详细的代码及注释,包括环境准备、环境搭建教程(已搭建的跳过即可)、数据库表设计、压力测试、示例

    2023年04月08日
    浏览(36)
  • 应用实战|微信小程序开发示例--多人聊天互动空间

    “超能力”数据库 ~拿来即用,应用开发人员再也不用为撰写API而发愁。MemFire Cloud 为开发者提供了简单易用的云数据库(表编辑器、自动生成API、SQL编辑器、备份恢复、托管运维),很大地降低开发者的使用门槛。 本示例是一个可以实现多人互动的角色扮演聊天室的微信小

    2024年02月09日
    浏览(51)
  • Vue+Websocket<简单实现聊天功能>

    此篇文章是针对 Websocket 的简单了解和应用,利用 Nodejs 简单搭建一个服务器加以实现。 首先创建一个 vue 项目,会vue的我就不必多说了; 然后再创建一个 server 文件夹,在终端上打开该文件夹,输入 vue init (一直敲 \\\"回车\\\" 键),最后再建一个 server.js 文件,如下图 代码如下

    2023年04月22日
    浏览(33)
  • django websocket实现聊天室功能

    注意事项channel版本 django2.x 需要匹配安装 channels 2 django3.x 需要匹配安装 channels 3 Django 3.2.4 channels 3.0.3 Django 3.2.* channels 3.0.2 Django4.2 channles==3.0.5 是因为最新版channels默认不带daphne服务器 直接用命令 python manage.py runsever 默认运行的是wsgi ,修改,删除settings中的wsgi,都不能正确运

    2024年01月22日
    浏览(35)
  • SpringBoot集成WebSocket实现及时通讯聊天功能!!!

    注意:   至此,后端代码就集成完了,集成完之后,记得重启你的Springboot项目 前端Vue 1:新建Vue 页面  路由: 代码:路由根据你项目的实际情况写 在用户登录的时候,需要将你的用户名存储到本地Session 中  效果图:  用户甲:   用户乙:   注:网上学习来源 SpringBoot集

    2024年02月01日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包