webapi控制器怎么接收json_swoft2 -Websocket消息控制器

swoft 提供了灵活的 websocket 使用,支持自定义和由框架托管处理消息两种方式。

如果你在 ws 模块类没有添加 @OnMessage 处理方法,框架将会自动托管这个阶段,解析消息并根据路由分发到不同的方法执行 如果你在 ws 模块类里面绑定了 @OnMessage 处理方法,swoft 就认为你想自己处理这个阶段,框架就不会处理了

定义 ws 模块

<?php declare(strict_types=1);

namespace AppWebSocket;

use AppWebSocketChatHomeController;
use SwoftHttpMessageRequest;
use SwoftWebSocketServerAnnotationMappingOnOpen;
use SwoftWebSocketServerAnnotationMappingWsModule;
use SwoftWebSocketServerMessageParserJsonParser;
use function server;

/**
 * Class ChatModule
 *
 * @WsModule(
 *     "/chat",
 *     messageParser=JsonParser::class,
 *     controllers={HomeController::class}
 * )
 */
class ChatModule
{
 /**
     * @OnOpen()
     * @param Request $request
     * @param int     $fd
     */
 public function onOpen(Request $request, int $fd): void
 {
        server()->push($request->getFd(), "Opened, welcome!(FD: $fd)");
 }
}

上面代码注解增加了 messageParser 和 controllers 将消息处理转发给控制器处理

消息解析器

不同的使用者或者使用场景,用于 ws 通信的数据格式可能是不一样的。因此,在编写 ws 模块时,需要你绑定消息解析器。

内置解析器

  • SwoftWebSocketServerMessageParserRawTextParser 简单的字符串
  • SwoftWebSocketServerMessageParserTokenTextParser 简单的 token 字符串协议(方便测试使用的)
  • SwoftWebSocketServerMessageParserJsonParser 简单的 JSON 数据协议
推荐使用JSON的解析格式

JSON 协议通信数据结构:

{
 "cmd": "home.index", // type: string,
 "data": "我是要发送的数据", // type: mixed(array|string|int)
 "ext": {"ip": "127.0.0.1", "os": "mac"}, // optional, type: array
}

说明

  • cmd 控制器的前缀和路由的名称组合,中间通过点连接,必须这样写,不然解析不到具体的控制器中.
  • data 客户端发送给服务器的数据 通过$req = context()->getRequest(); $msg=$req->getMessage();$msg->getData()可以获取到数据
  • ext 客户端发送的额外信息 通过 $req = context()->getRequest();$req->getExt(); 可以得到数据

客户端调用代码示例

const wsUrl = 'ws://127.0.0.1:18308/chat'

let ws = new WebSocket(wsUrl)

const req={cmd:"home.index",data:"我是客户端数据",ext:[]}

ws.send(JSON.stringify(req))

获取数据

use SwoftWebSocketServerMessageRequest;

$req = context()->getRequest();

$msg = $req->getMessage();
$data = $msg->getData();

$fd = $req-getFd();

$ext = $req->getExt();

控制器定义

<?php declare(strict_types=1);

namespace AppWebSocketChat;

use SwoftSessionSession;
use SwoftWebSocketServerAnnotationMappingMessageMapping;
use SwoftWebSocketServerAnnotationMappingWsController;

/**
 * Class HomeController
 *
 * @WsController(prefix="home")
 */
class HomeController
{
 /**
     * Message command is: 'home.index'
     *
     * @return void
     * @MessageMapping(command="index")
     */
 public function index(): void
 {
 Session::mustGet()->push('hi, this is home.index');
 }

}

代码详解

注解

@WsController 注解

websocket 消息控制器注解 @WsController

类似于 http 中的 controller

注解类:SwoftWebSocketServerAnnotationMappingWsController

作用范围:CLASS

拥有属性:

  • prefix string 消息路由前缀

@MessageMapping 注解

方法注解 @MessageMapping 标记具体的消息处理方法,类似于 http 控制器里的 action。

类似于 http 中的 RequestMapping

注解类:SwoftWebSocketServerAnnotationMappingMessageMapping

作用范围:METHOD

拥有属性:

command string 消息命令名称

完整的消息路由 path 是 上面的 preifx 和 command 由点拼接而成 PREFIX.COMMAND

推荐显示的指定 @WsController 注解的 prefix 和 @MessageMapping 注解的 command

消息发送 API

注意下面的方法都在类:SwoftWebSocketServerWebSocketServer

发送给某个客户端

public function sendTo(int $receiver, string $data, int $sender = 0): int

参数说明:

  • $receiver int 接收者的 fd
  • $data string 要发送的消息数据
  • $sender int 发送者的 fd。 可选的

示例

server()->sendTo($fd, 'hi, 你好啊!');

发送给指定的一些客户端

public function sendToSome(string $data, array $receivers = [], array $excluded = [], int $sender = 0, int $pageSize = 50): int

参数说明:

  • $data string 要发送的消息数据
  • $receivers int[] 指定的接收者 fd 列表
  • $excluded int[] 排除的接收者 fd 列表
  • $sender int 发送者的 fd。 可选的

方法说明:

  • 当 $receivers 有数据时,将会忽略 $excluded。 此时就是将消息指定的发给这些接收者
  • 当 $receivers 为空时
  • 若 $excluded 有值,将会给除了这些人之外的发送消息
  • 若 $excluded 为空,相当于给所有人发消息

示例

server()->sendToSome('hi, 你们好啊!', [$fd0, $fd1, ...]);

广播消息

public function sendToAll(string $data, int $sender = 0, int $pageSize = 50): int

发送消息给所有客户端,相当于进行全员广播。使用分页方式发送,每 50 个一页,直到全部发送完毕。

参数说明:

  • $data string 要发送的消息数据
  • $sender int 发送者的 fd。 可选的

示例

server()->sendToAll('hi, 大家好啊!');

断开连接

 server()->disconnect($fd);

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要

PHP进阶架构师>>>视频、面试文档免费获取​shimo.im
d25343a15b85d473161236a3308bbd67.png

或 者关注咱们下面的知乎专栏

PHP架构师圈子​zhuanlan.zhihu.com
33c2d1faf43f29cc929b1e98f2d5cbc7.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值