「IM系列」WebSocket教程:响应格式规范与异常处理

2023-12-04 09:58:14 浏览数 (2)

俗话说无规矩不成方圆,一个接口一种数据响应格式,一个开发人员一种开发格式,导致代码不规范,数据解析复杂化,维护更是难上加难。——开源技术小栈

数据格式

数据格式约定

  1. 必须返回统一的数据结构
  2. 查询不到数据时, 即空数据的情况下返回给客户端统一的数据结构格式
  3. 服务端和客户端都需要保证JSON格式的合法性

状态码规范

状态码

英文名称

描述

200

OK

请求成功

400

Bad Request

业务错误,语义有误,当前请求无法被服务器理解

401

Unauthorized

认证失败,当前请求需要用户验证

403

Forbidden

无权限调用,服务器已经理解请求,但是拒绝执行它

404

Not Found

暂无数据

500

Internal Server Error

服务器内部错误,无法完成请求

常见数据格式

基础响应格式
代码语言:javascript复制
{
    "code":200,
    "msg":"success",
    "data":{}
}
对象格式
代码语言:javascript复制
{
    "code":200,
    "msg":"success",
    "data":{
        "id":10086,
        "name":"Tinywan",
        "age":20,
        "sex":1
    }
}
数组格式
代码语言:javascript复制
{
    "code":200,
    "msg":"ok",
    "data":[{
       "id":1,
       "name":"poppy",
       "age":20
     },{
       "id":2,
       "name":"thorn",
       "age":18
     }]
}
分页列表格式
代码语言:javascript复制
{
    "code":200,
    "msg":"ok",
    "data":{
        "total":10,
        "list":[
            {
                "id":1,
                "name":"poppy",
                "age":20
            },
            {
                "id":2,
                "name":"thorn",
                "age":18
            }
        ]
    }
}
文件拖格式
代码语言:javascript复制
{
    "code":200,
    "msg":"ok",
    "data":[
        "https://tinywan.com/file/upliad/20172514.jpg",
        "https://tinywan.com/file/upliad/20172515.jpg"
    ]
}

封装一个统一函数

代码语言:javascript复制
/**
 * @desc: 消息广播json数据
 * @param int $code
 * @param string $msg
 * @param array $data
 * @return false|string
 * @author Tinywan(ShaoBo Wan)
 */
function broadcast_json(int $code = 0, string $msg = 'success', array $data = [])
{
    return json_encode(['code' => $code, 'msg' => $msg, 'data' => $data], JSON_UNESCAPED_UNICODE);
}

上一章代码优化

代码语言:javascript复制
/**
 * @desc onMessage
 * @param string $clientId
 * @param string $message
 * @return false
 * @author Tinywan(ShaoBo Wan)
 */
public static function onMessage(string $clientId, string $message): bool
{
    $originMessage = json_decode($message, true);
    if (json_last_error() != JSON_ERROR_NONE) {
        Gateway::closeClient($clientId, json_encode([
            'code' => 500,
            'msg' => '无效的json数据'
        ], JSON_UNESCAPED_UNICODE));
        return false;
    }
    return Gateway::sendToClient($clientId, json_encode([
        'code' => 200,
        'msg' => '请求发送成功',
        'data' => $originMessage
    ], JSON_UNESCAPED_UNICODE));
}

使用 broadcast_json 行数优化后代码

代码语言:javascript复制
/**
 * @desc onMessage
 * @param string $clientId
 * @param string $message
 * @return false
 * @author Tinywan(ShaoBo Wan)
 */
public static function onMessage(string $clientId, string $message): bool
{
    $originMessage = json_decode($message, true);
    if (json_last_error() != JSON_ERROR_NONE) {
        Gateway::closeClient($clientId, broadcast_json(400, '无效的json数据'));
        return false;
    }
    return Gateway::sendToClient($clientId, broadcast_json(400, '请求成功', $originMessage));
}

测试请求响应

异常处理

异常是什么?

PHP中的异常的独特性,即PHP中的异常不同于主流语言C 、java中的异常。在Java中,异常是唯一的错误报告方式,而在PHP中却不是这样,而是把所有不正常的情况都视作了错误进行处理。这两种语言对异常和错误的界定存在分歧。什么是异常什么是错误,两种语言的设计者存在不同的观点。

这里使用set_error_handler(error_function, error_type)函数设置自定义错误处理函数,接管原错误处理函数。

set_error_handler — 设置用户自定义的错误处理函数,本函数可用于在运行时定义自定义错误处理程序,例如,在应用程序中发生严重错误,或者在特定条件下触发了错误(使用 trigger_error()),应用程序需要执行文件/数据清理。

自定义错误处理函数

修改pluginwebmangatewayEvents.php业务处理事件onWorkerStart()方法,设置自定义错误处理函数,接管原错误处理函数。

代码语言:javascript复制
/**
 * @desc: 当客户端连接上gateway完成websocket握手时触发
 * @param Worker $worker
 * @throws ErrorException
 * @author Tinywan(ShaoBo Wan)
 */
public static function onWorkerStart(Worker $worker)
{
    set_error_handler(function ($severity, $message, $file, $line) use ($worker) {
        if (!(error_reporting() & $severity)) {
            return;
        }
        throw new ErrorException($message, 0, E_ERROR, $file, $line);
    });
}

修改pluginwebmangatewayEvents.php业务处理事件onMessage()方法,抛出一个异常。

代码语言:javascript复制
/**
 * @desc: 当客户端连接上gateway完成websocket握手时触发
 * @param Worker $worker
 * @throws ErrorException
 * @author Tinywan(ShaoBo Wan)
 */
public static function onMessage(string $clientId, string $message): bool
{
    try {
        $originMessage = json_decode($message, true);
        if (json_last_error() != JSON_ERROR_NONE) {
            Gateway::closeClient($clientId, broadcast_json(400, '无效的json数据'));
            return false;
        }
        // 被除数为0的异常
        $aa = 1/0;
        var_dump($aa);
    } catch (Throwable $throwable) {
        return Gateway::sendToClient($clientId, broadcast_json(500, $throwable->getMessage()));
    }
    return Gateway::sendToClient($clientId, broadcast_json(200, '请求成功', $originMessage));
}

console 控制台

网络发送和接受情况

这样子可以保证进程不会被退出

源码

文章相关源码地址:https://github.com/Tinywan/webman-admin

0 人点赞