10 行代码就能搞定!用 Workerman 在本地搭一个「多人聊天室」|0 基础也能看懂

【封面文案】
“再也不用拉群,浏览器秒开即聊”


👀 你有没有想过——
• 临时开个线上会议,却不想装 Zoom?
• 内网培训,老师一句话学生全看到?
• 产品经理一句话,后端、前端、测试同时收到?

今天就教你 3 分钟 搭一个零依赖、零配置的「多人聊天室」。
只要 一个 PHP 文件 + 一个 HTML 文件,就能让全公司/全班/全寝室一起在线聊天!


🧰 技术选型

  • 后端:Workerman(纯 PHP,无需 Nginx、Apache)
  • 前端:原生 HTML + Layui + WebSocket
  • 环境:PHP ≥ 7.0(带 pcntl、posix 扩展)

🚀 动手开干

Step 1|安装 Workerman

1
composer require workerman/workerman

Step 2|后端 20 行代码(chat.php)

把下面代码保存为 chat.php,双击 php chat.php start 就能跑!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';

$ws = new Worker("websocket://0.0.0.0:2000");

$global_uid = 0;
$ws->onConnect = function($conn) use (&$global_uid){
$conn->uid = ++$global_uid; // 分配用户 ID
$conn->avatarRam = mt_rand(0,5); // 随机头像
};

$ws->onMessage = function($conn, $data) use ($ws){
$msg = json_decode($data, true);
$msg['uid'] = $conn->uid;
$msg['avatarRam'] = $conn->avatarRam;
// 广播给所有人(除自己)
foreach($ws->connections as $c){
if($c->uid != $conn->uid){
$c->send(json_encode($msg));
}
}
};

Worker::runAll();

本地跑起来后,终端出现 Workerman[chat.php] start in DEBUG mode 就成功了!


Step 3|前端 1 个文件(index.html)

把下面代码保存为 index.html,双击浏览器打开即可聊天。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>多人聊天室</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/layui@2/dist/css/layui.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@3/dist/css/adminlte.min.css">
</head>
<body style="padding:20px">
<!-- 消息区 -->
<div class="direct-chat-messages" id="box" style="height:60vh;overflow-y:auto"></div>
<hr>
<!-- 输入框 -->
<div class="msg-send" contenteditable="true" id="input" style="min-height:100px;border:1px solid #ddd;padding:10px"></div>
<button class="layui-btn layui-btn-normal" onclick="send()" style="margin-top:10px">发送</button>

<script src="https://cdn.jsdelivr.net/npm/layui@2/dist/layui.js"></script>
<script>
layui.use('layer', () => {
const ws = new WebSocket('ws://127.0.0.1:2000');
ws.onmessage = e => showMsg(JSON.parse(e.data), false);

window.send = () => {
const msg = document.getElementById('input').innerHTML.trim();
if(!msg) return layer.msg('不能发空消息');
ws.send(JSON.stringify({msg}));
showMsg({uid:'我', msg}, true);
document.getElementById('input').innerHTML='';
};

function showMsg(data, isMe){
const box = document.getElementById('box');
const side = isMe ? 'right' : '';
const html = `
<div class="direct-chat-msg ${side}">
<img class="direct-chat-img" src="https://cdn.jsdelivr.net/npm/admin-lte@3/dist/img/avatar${isMe?'5':data.avatarRam}.png">
<div class="direct-chat-text">${data.msg}</div>
<small class="direct-chat-timestamp">${new Date().toLocaleTimeString()}</small>
</div>`;
box.insertAdjacentHTML('beforeend', html);
box.scrollTop = box.scrollHeight;
}
});
</script>
</body>
</html>

🎉 效果演示

  1. 打开 3 个浏览器窗口或手机扫码
  2. 随便输入一句话,所有人实时同步
  3. 随机头像 + 时间戳,体验不输微信!

(动图演示,公众号可插入)


🛠️ 进阶玩法

  1. 增加昵称
    onConnect 里让前端先发一次 {type:'login', name:'张三'},后端存起来即可。

  2. 房间分组
    $conn->room = 'A' 区分不同群聊,广播时只发给同房间。

  3. HTTPS / 域名
    websocket://0.0.0.0:2000 换成 websocket://yourdomain.com/wss,再用 nginx 反代即可。

  4. Docker 一键部署
    后续文章教你把聊天室打包成镜像,一条命令跑在服务器上。


📦 源码仓库

关注公众号「无法直视众平台」,回复关键词 聊天室


🙋‍♂️ 常见问题

问题 解决
启动报错 pcntl 扩展缺失 apt install php-pcntl
公司内网只能 80/443 端口 用 nginx 反向代理
手机浏览器打不开 确保电脑和手机在同一局域网,把 127.0.0.1 换成电脑局域网 IP

🎁 彩蛋

chat.php 里加三行,就能实现「机器人自动欢迎」:

1
2
3
4
5
$ws->onConnect = function($conn) use ($ws){
foreach($ws->connections as $c){
$c->send(json_encode(['uid'=>0,'msg'=>'🎉 新伙伴加入聊天室!']));
}
};

👍 觉得有用就点个「在看」
留言说说你还想实现什么功能,下期安排!