在根据 SWOFT2 小白教程系列-WEBSOCKET 流程及配置配置 websocket 之后,就可以在 app/WebSocket 下创建需要的 websocket 模块来处理相关逻辑。
在每个模块里允许用户处理的几个事件有 handshake open message close。
简单示例
<?php
namespace AppWebSocket;
use SwoftHttpMessageRequest;
use SwoftHttpMessageResponse;
use SwoftWebSocketServerAnnotationMappingOnClose;
use SwoftWebSocketServerAnnotationMappingOnHandshake;
use SwoftWebSocketServerAnnotationMappingOnOpen;
use SwoftWebSocketServerAnnotationMappingWsModule;
use SwooleWebSocketFrame;
use SwooleWebSocketServer;
/**
* Class EchoModule
*
* @WsModule("/echo")
*/
class EchoModule
{
/**
* 在这里你可以验证握手的请求信息
* @OnHandshake()
* @param Request $request
* @param Response $response
* @return array [bool, $response]
*/
public function checkHandshake(Request $request, Response $response): array
{
return [true, $response];
}
/**
* On connection has open
*
* @OnOpen()
* @param Request $request
* @param int $fd
*/
public function onOpen(Request $request, int $fd): void
{
server()->push($fd, 'hello, welcome! :)'); //推送一条消息给客户端
}
/**
* @OnMessage()
* @param Server $server
* @param Frame $frame
*/
public function onMessage(Server $server, Frame $frame)
{
$server->push($frame->fd, 'I have received message: ' . $frame->data); //将收到的消息推送给客户端
}
/**
* On connection closed
* - you can do something. eg. record log
*
* @OnClose()
* @param Server $server
* @param int $fd
*/
public function onClose(Server $server, int $fd): void
{
// you can do something. eg. record log, unbind user...
}
}
客户端调用
// wsUrl = websocket host + module path
const wsUrl = 'ws://127.0.0.1:18308/echo'
let ws = new WebSocket(wsUrl)
ws.onerror = function (event){
console.log("error: " + event.data)
}
ws.onopen = function (event){
console.log("open: connection opened");
}
ws.onmessage = function (event){
console.log("message: " + event.data);
}
ws.onclose = function (event){
console.log("close: connection closed")
ws.close()
}
代码解析
类注解
@WsModule 注解
websocket 模块类注解 @WsModule。
注解类: SwoftWebSocketServerAnnotationMappingWsModule
作用范围: CLASS
拥有属性:
- path string 标明了允许ws连接的 URI path.
- controllers array 绑定到此模块的 消息控制器 类
- messageParser string 绑定到此模块的 消息解析器
- defaultOpcode integer 此模块默认的消息数据 opcode
这个注解一定要写,其中path定义的是websocket路径,上面代码定义的是echo,所以客户端访问 ws://127.0.0.1:18308/echo, ws是协议,127.0.0.1是ws启动的主机IP 18308是端口,/echo就是上面注解定义的path
方法注解
@OnHandshake 注解
这个功能基本用不到,大家了解就好
方法注解 @OnHandshake 标记处理握手的方法
注解类: SwoftWebSocketServerAnnotationMappingOnHandshake
作用范围: METHOD
这方法是可选的。如果没有特殊的需求,可以忽略它,框架会帮你握手并响应握手成功。
必须返回含有两个元素的 array
- bool 第一个元素的值来决定是否进行握手
- 第二个元素是 response 对象 - 可以在 response 设置一些自定义 header,body 等信息
@OnOpen 注解
这个功能例如在刚连接的时候给客户端输出一些信息,或者在刚连接的时候保存 客户端 $fd
在握手成功后,就会触发 open 事件。 方法注解 @OnOpen 标记对应方法。
此时开始你就可以给客户端发消息了 :)
注解类: SwoftWebSocketServerAnnotationMappingOnOpen
作用范围: METHOD
此方法也是可选的,可以没有
@OnMessage
通过的方法注解 @OnMessage 标记一个消息处理方法。
在此阶段你可以接收到客户端的消息和发送消息给对方.
注解类:SwoftWebSocketServerAnnotationMappingOnMessage
作用范围:METHOD
当你没有绑定消息控制器时,表明你想自己处理消息阶段的逻辑,此方法是必须存在的。
当你有绑定消息控制器时,框架会自动解析消息并路由到指定的消息处理方法
@OnClose
这个功能例如在刚断开的时候给客户端输出一些信息,或者在刚断开的时候移除指定客户端 $fd
通过的方法注解 @OnClose 标记一个关闭连接时的处理方法。
注意:触发此事件时连接已被关闭,不能再给对方发消息
当客户的关闭连接或者 server 在其他地方主动关闭连接时,就会触发此事件。
你可以在这里做一些连接关闭后的工作, 比如:记录日志,解绑用户等。
注解类:SwoftWebSocketServerAnnotationMappingOnClose
作用范围:METHOD
此方法也是可选的,可以没有
说明
一般复杂的 websocket 应用 应该使用控制器来处理消息,但如果你只是简单的接收和推送消息,就没必要使用ws控制器,这个时候你就需要监听 OnMessage 注解方法 在里面处理业务逻辑,如果是复杂的ws应用应该使用控制器,如果声明了控制器 ws模块只需要在注解中定义控制器,这样消息的处理根据规则就转发到控制器里处理.
来源:https://8code.net/index/index/article/id/50
以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要
PHP进阶架构师>>>视频、面试文档免费获取shimo.im或 者关注咱们下面的知乎专栏
PHP架构师圈子zhuanlan.zhihu.com