/
MessageListener.php
87 lines (72 loc) 路 2.49 KB
/
MessageListener.php
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<?php declare(strict_types=1);
namespace Swoft\WebSocket\Server\Swoole;
use Swoft;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Bean\BeanFactory;
use Swoft\Context\Context;
use Swoft\Server\Contract\MessageInterface;
use Swoft\Session\Session;
use Swoft\SwoftEvent;
use Swoft\WebSocket\Server\Context\WsMessageContext;
use Swoft\WebSocket\Server\Message\Request;
use Swoft\WebSocket\Server\Message\Response;
use Swoft\WebSocket\Server\WsErrorDispatcher;
use Swoft\WebSocket\Server\WsMessageDispatcher;
use Swoft\WebSocket\Server\WsServerEvent;
use Swoole\Websocket\Frame;
use Swoole\Websocket\Server;
use Throwable;
use function server;
/**
* Class MessageListener
*
* @Bean()
*
* @since 2.0
*/
class MessageListener implements MessageInterface
{
/**
* @param Server $server
* @param Frame $frame
*
* @throws Throwable
*/
public function onMessage(Server $server, Frame $frame): void
{
$fd = $frame->fd;
$sid = (string)$fd;
server()->log("Message: conn#{$fd} received message: {$frame->data}", [], 'debug');
$request = Request::new($frame);
$response = Response::new($fd);
/** @var WsMessageContext $ctx */
$ctx = WsMessageContext::new($request, $response);
// Storage context
Context::set($ctx);
// Bind cid => sid(fd)
Session::bindCo($sid);
/** @var WsMessageDispatcher $dispatcher */
$dispatcher = BeanFactory::getSingleton('wsMsgDispatcher');
try {
// Trigger message before event
Swoft::trigger(WsServerEvent::MESSAGE_RECEIVE, $fd, $server, $frame);
// Parse and dispatch message
$dispatcher->dispatch($server, $request, $response);
// Trigger message after event
Swoft::trigger(WsServerEvent::MESSAGE_AFTER, $fd, $server, $frame);
} catch (Throwable $e) {
Swoft::trigger(WsServerEvent::MESSAGE_ERROR, $e, $frame);
server()->log("Message: conn#{$fd} error: " . $e->getMessage(), [], 'error');
/** @var WsErrorDispatcher $errDispatcher */
$errDispatcher = BeanFactory::getSingleton(WsErrorDispatcher::class);
$errDispatcher->messageError($e, $frame);
} finally {
// Defer event
Swoft::trigger(SwoftEvent::COROUTINE_DEFER);
// Destroy event
Swoft::trigger(SwoftEvent::COROUTINE_COMPLETE);
// Unbind cid => sid(fd)
Session::unbindCo();
}
}
}