构建多人实时协作白板:WebSocket、Canvas与Webman的完美结合

在现代Web应用中,实时协作功能越来越受到重视。本文将介绍如何利用WebSocket、Canvas、Webman和HTML5 CSS等技术,实现一个支持多人实时协作的共享白板。该白板具备无限大小、任意缩放的特点,并能实时同步绘画和涂鸦数据。

技术栈概览

  • WebSocket:用于实现客户端与服务器之间的双向通信,确保数据的实时同步。
  • Canvas:用于渲染画板和生成涂鸦数据。
  • Webman:作为WebSocket消息订阅发布服务器,负责处理客户端的连接和消息传递。
  • HTML5 & CSS:用于构建用户界面和样式。

实现步骤

1. 安装与配置

首先,我们需要安装并配置一些必要的组件。

安装Think-Template

使用Composer安装Think-Template:

composer require topthink/think-template

修改配置文件config/view.php

<?php
use support\view\ThinkPHP;

return [
    'handler' => ThinkPHP::class,
];

2. 创建HTTP服务

接下来,我们创建一个HTTP控制器来处理画板的请求。

创建控制器

新建文件app/controller/DemoController.php

<?php
declare(strict_types=1);

namespace app\controller;

use support\Request;
use support\Response;

class DemoController
{
    public function canvas(Request $request): Response
    {
        return view('demo/canvas');
    }
}

创建视图文件

新建文件app/view/demo/canvas.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>开源技术小栈 WebSocket+Canvas: 实战构建多人互动画板</title>
</head>
<body>
<canvas id="canvas" height="600" width="600" style="border:1px solid #000000;">你的浏览器不支持canvas,请升级浏览器</canvas>
<script src="/static/js/index.js"></script>
</body>
</html>

3. 实现WebSocket通信

为了实现多人实时协作,我们需要通过WebSocket进行数据同步。

创建WebSocket服务

新建文件process/CanvasWebsocket.php

<?php
declare(strict_types=1);

namespace process;

use Workerman\Connection\TcpConnection;

class CanvasWebsocket
{
    public function onConnect(TcpConnection $connection)
    {
        echo "onConnect\n";
    }

    public function onWebSocketConnect(TcpConnection $connection, $http_buffer)
    {
        echo "onWebSocketConnect\n";
    }

    public function onMessage(TcpConnection $connection, $data)
    {
        foreach ($connection->worker->connections as $_connection) {
            if($connection != $_connection){
                $_connection->send($data);
            }
        }
    }

    public function onClose(TcpConnection $connection)
    {
        echo "onClose\n";
    }
}

配置WebSocket进程

config/process.php中添加如下配置:

return [
    // ... 其它进程配置省略 ...

    'canvas_websocket' => [
        'handler' => \process\CanvasWebsocket::class,
        'listen'  => 'websocket://0.0.0.0:8788',
        'count'   => 1,
    ],
];

4. 前端实现

最后,我们在前端实现画板的绘制和WebSocket通信。

创建JavaScript文件

新建文件/static/js/index.js

var el = document.getElementById('canvas');
el.width = document.body.clientWidth;
el.height = document.body.clientHeight;
var ctx = el.getContext('2d');
var isDrawing;
var point = {};

ctx.strokeStyle = '#fffff';

var ws = new WebSocket('ws://192.168.13.168:8788');
console.log(ws);

ws.onopen = function () {
    el.onmousedown = function (e) {
        isDrawing = true;
        ctx.moveTo(e.clientX, e.clientY);
        sendPoint(e, 1);
    }

    el.onmousemove = function (e) {
        if (isDrawing) {
            ctx.lineTo(e.clientX, e.clientY);
            ctx.stroke();
            sendPoint(e, 2);
        }
    }

    el.onmouseup = function (e) {
        isDrawing = false;
    }
}

ws.onmessage = function (e) {
    var data = JSON.parse(e.data);
    if (data.type == 1) {
        ctx.moveTo(data.x, data.y);
    } else if (data.type == 2) {
        ctx.lineTo(data.x, data.y);
        ctx.stroke();
    }
}

function sendPoint(e, type) {
    point = {
        type: type,
        x: e.clientX,
        y: e.clientY,
    }
    ws.send(JSON.stringify(point));
}

启动Webman

完成上述步骤后,启动Webman服务器:

php webman start

现在,你可以在多个浏览器中打开画板页面,开始实时协作绘图了!

标签: PHP

相关文章

Memcached如何配置分布式使用 并附PHP示例

Memcached是一种高性能的分布式内存对象缓存系统,广泛用于加速动态Web应用程序。通过将数据存储在内存中,Memcached能够显著减少数据库负载,提高应用的响应速度Memcached分布...

使用PHP打造轻量级单文件SQLite数据库管理工具

先声明一下,这是我自己内网使用的一个简单的管理工具,所以安全性方面我肯定是没有测试的~ 如果你要放在公网,请添加相关的权限认证及sql防注入等处理在开发过程中,我们经常需要一个简单易用的数据库管...

PHP 中的 declare 指令

在 PHP 编程中,declare 指令是一个强大的工具,用于控制代码的执行行为。它不仅可以启用严格类型模式,还可以用于其他一些高级功能,如性能监控和字符编码。本文将深入探讨 declare 指...

如何在PHP框架Workerman中实现异步任务处理

在现代Web应用中,处理繁重的业务逻辑时,避免主业务流程被长时间阻塞是非常重要的。Workerman是一个高性能的PHP Socket框架,支持异步任务处理,可以有效地解决这一问题。本文将详细介...

PHP中使用CURL下载远程超大文件的方法

在使用PHP进行开发时,我们经常需要从远程服务器下载文件。当文件体积较大时,普通的文件操作和cURL方法可能会因为内存限制或执行时间限制而失败。本文将介绍如何使用PHP中的cURL扩展来高效地下...

图片Base64编码

CSR生成

图片无损放大

图片占位符

Excel拆分文件