avatar

mdo

Hello

  • 首页
  • 知识库
  • 归档
  • 标签
  • 关于
主页 前端使用的不是socket.io客户端 ,如何实现握手
文章

前端使用的不是socket.io客户端 ,如何实现握手

发表于 2026-06-18 更新于 2026-06- 18
作者 mdo
21~27 分钟 阅读

如果你的前端不使用 socket.io-client,而是使用原生 WebSocket(new WebSocket())或其他普通的 WebSocket 客户端,那么你就不能在 think-swoole 的配置文件中继续使用 socketio 处理器。

因为 socketio 处理器强制要求遵循 Socket.IO 特有的握手(Engine.io)和数据包(Packet)编码协议(例如连接时必须先发送 40,心跳发送 2 和 3,消息带 42 等前缀)。

要使用原生 WebSocket 客户端,你需要切换到 think-swoole 专门提供的原生 WebSocket 模式。


🛠️ 解决方案:切换为原生 WebSocket 模式

1. 修改配置文件

打开 config/swoole.php,将 websocket.handler 改为系统内置的原生 WebSocket 处理器(不要使用 socketio):

php

use think\swoole\websocket\Handler; // 注意:这是原生的 Handler,不是 socketio 目录下的

return [
    // ... http 配置保持不变 ...
    'websocket'  => [
        'enable'        => true,
        'handler'       => Handler::class, // 关键:切换回原生处理器
        'ping_interval' => 25000,
        'ping_timeout'  => 60000,
        'listen'        => [
            // 原生模式下,所有接收到的文本消息都会触发这个监听类
            'message' => \app\listener\WebsocketMessage::class, 
        ],
        'subscribe'     => [],
    ],
];

请谨慎使用此类代码。

2. 创建原生消息监听类

使用命令行生成监听类:

bash

php think make:listener WebsocketMessage

请谨慎使用此类代码。

在 app\listener\WebsocketMessage.php 中编写逻辑。因为是原生模式,前端发送的是纯文本字符串,你需要自行定义通信格式(通常是 JSON):

php

namespace app\listener;

use think\swoole\Websocket;

class WebsocketMessage
{
    public function handle(Websocket $websocket, $data)
    {
        // $data 是前端通过 socket.send() 发送的原生字符串
        // 假设前端发送的是 JSON 字符串:{"event": "test", "data": {"name": "ThinkPHP"}}
        $payload = json_decode($data, true);
        
        if (!empty($payload['event'])) {
            switch ($payload['event']) {
                case 'test':
                    // 回复前端,原生模式下使用 push 发送纯文本
                    $reply = json_encode([
                        'event' => 'testcallback',
                        'data'  => ['status' => 'success', 'msg' => '收到原生数据']
                    ]);
                    $websocket->push($reply);
                    break;
                    
                // 你可以在这里根据 event 字段分发不同的业务逻辑
            }
        }
    }
}

请谨慎使用此类代码。

3. 前端原生客户端连接与握手

原生 WebSocket 的握手是标准的 HTTP Upgrade 协议,由浏览器和 Swoole 自动完成,不需要你手动编写任何握手代码。直接连接即可:

javascript

// 直接连接,不需要任何特殊参数
const ws = new WebSocket("ws://127.0.0.1:9501");

// 监听连接成功(自动完成握手)
ws.onopen = () => {
    console.log("WebSocket 连接成功!");
    
    // 发送符合约定的 JSON 字符串
    const msg = JSON.stringify({
        event: "test",
        data: { name: "ThinkPHP" }
    });
    ws.send(msg);
};

// 监听服务器返回的消息
ws.onmessage = (event) => {
    // event.data 是服务器 push 过来的纯文本
    const res = JSON.parse(event.data);
    console.log("接收到服务器消息:", res);
};

// 监听断开
ws.onclose = () => {
    console.log("连接已断开");
};

请谨慎使用此类代码。


💡 核心区别对比

功能特性

Socket.IO 模式 (socketio\Handler)

原生 WebSocket 模式 (Handler)

前端客户端

必须用 socket.io-client

任何支持 WebSocket 的工具(如 new WebSocket)

握手机制

复杂的自定义 HTTP 轮询/升级(含 sid 校验)

标准的 HTTP Upgrade(浏览器自动处理)

数据格式

内置事件机制(emit 路由,自带包前缀)

纯文本/二进制(需要自己 json_decode)

后端回复方法

$websocket->emit()

$websocket->push()

技术
许可协议:  CC BY 4.0
分享

相关文章

10月 2, 2026

iOS 侧载(Sideloading)工具

AltStore 和 Sideloadly 都是目前最流行的 iOS 侧载(Sideloading)工具。 简单来说,它们的作用就是让你绕过苹果的官方 App Store,直接把第三方的 IPA 安装包(也就是 iOS 的应用安装文件)安装到你的 iPhone 或 iPad 上。 通过这两个工具,你

9月 28, 2026

注册 Chat Participant

将当前服务接入 VS Code 的 AI 聊天窗口是完全可行的。VS Code 在近期的版本中正式推出了 Chat Extensions API(github.copilot.chat),允许第三方扩展将自定义的 LLM 服务或工具注册到 Copilot Chat 面板中。 结合当前 code_ge

9月 23, 2026

php intelephense 设置 if 空格

在 VS Code 中,如果你使用的是 PHP Intelephense 插件,控制 if 关键字后面是否加空格的设置是由其内置的格式化引擎(基于 PSR-12 标准)决定的。 你可以通过修改 VS Code 的 settings.json 来配置这个行为: 1. 开启 if 后面的空格(默认/推荐

下一篇

ubuntu 自定义指令 执行脚本

上一篇

在原生 WebSocket 模式下,增加握手验证逻辑

最近更新

  • 比尔盖茨的智慧:想多赚钱,就每天循环做这3件事
  • iOS 侧载(Sideloading)工具
  • 程序员越想创业,越不要急着动手
  • 注册 Chat Participant
  • 中秋给在外游子的一封信

热门标签

API CodeGeex Coding Cursor DeepSeek Docker Gitkraken Harness Laravel Management

目录

©2026 mdo. 保留部分权利。