Skip to content
This repository was archived by the owner on Mar 24, 2025. It is now read-only.

Commit 7c8076d

Browse files
authored
Merge pull request #14 from swooletw/develop
Develop
2 parents 7652b1c + 3186d7c commit 7c8076d

19 files changed

+602
-130
lines changed

config/swoole_websocket.php

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99
*/
1010
'handler' => SwooleTW\Http\Websocket\SocketIO\WebsocketHandler::class,
1111

12+
/*
13+
|--------------------------------------------------------------------------
14+
| Default frame parser
15+
| Replace it if you want to customize your websocket payload
16+
|--------------------------------------------------------------------------
17+
*/
18+
'parser' => SwooleTW\Http\Websocket\SocketIO\SocketIOParser::class,
19+
1220
/*
1321
|--------------------------------------------------------------------------
1422
| Websocket route file path
@@ -18,18 +26,21 @@
1826

1927
/*
2028
|--------------------------------------------------------------------------
21-
| Default websocket driver
29+
| Default middleware for on connect request
2230
|--------------------------------------------------------------------------
2331
*/
24-
'default' => 'table',
32+
'middleware' => [
33+
// SwooleTW\Http\Websocket\Middleware\DecryptCookies::class,
34+
// SwooleTW\Http\Websocket\Middleware\StartSession::class,
35+
// SwooleTW\Http\Websocket\Middleware\Authenticate::class,
36+
],
2537

2638
/*
2739
|--------------------------------------------------------------------------
28-
| Default frame parser
29-
| Replace it if you want to customize your websocket payload
40+
| Default websocket driver
3041
|--------------------------------------------------------------------------
3142
*/
32-
'parser' => SwooleTW\Http\Websocket\SocketIO\SocketIOParser::class,
43+
'default' => 'table',
3344

3445
/*
3546
|--------------------------------------------------------------------------

routes/websocket.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22

3+
use Illuminate\Http\Request
34
use SwooleTW\Http\Websocket\Facades\Websocket;
45

56
/*
@@ -11,6 +12,14 @@
1112
|
1213
*/
1314

15+
Websocket::on('connect', function ($websocket, Request $request) {
16+
// called while socket on connect
17+
});
18+
19+
Websocket::on('close', function ($websocket) {
20+
// called while socket on close
21+
});
22+
1423
Websocket::on('example', function ($websocket, $data) {
1524
$websocket->emit('message', $data);
1625
});

src/Server/Application.php

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class Application
6969
*/
7070
protected $resolves = [
7171
'view', 'files', 'session', 'session.store', 'routes',
72-
'db', 'db.factory', 'cache', 'cache.store', 'config',
72+
'db', 'db.factory', 'cache', 'cache.store', 'config', 'cookie',
7373
'encrypter', 'hash', 'router', 'translator', 'url', 'log'
7474
];
7575

@@ -247,22 +247,27 @@ public function getFramework()
247247
*/
248248
public function run(Request $request)
249249
{
250-
ob_start();
250+
$shouldUseOb = $this->application['config']->get('swoole_http.ob_output', true);
251+
252+
if ($shouldUseOb) {
253+
ob_start();
254+
}
251255

252256
// handle request with laravel or lumen
253257
$method = sprintf('run%s', ucfirst($this->framework));
254258
$response = $this->$method($request);
255259

256260
// prepare content for ob
257261
$content = '';
258-
$shouldUseOb = $this->application['config']->get('swoole_http.ob_output', true);
259-
if ($response instanceof StreamedResponse ||
260-
$response instanceof BinaryFileResponse) {
261-
$shouldUseOb = false;
262-
} elseif ($response instanceof SymfonyResponse) {
263-
$content = $response->getContent();
264-
} else {
265-
$content = (string) $response;
262+
if ($shouldUseOb) {
263+
if ($response instanceof StreamedResponse ||
264+
$response instanceof BinaryFileResponse) {
265+
$shouldUseOb = false;
266+
} elseif ($response instanceof SymfonyResponse) {
267+
$content = $response->getContent();
268+
} else {
269+
$content = (string) $response;
270+
}
266271
}
267272

268273
// process terminating logics
@@ -273,7 +278,9 @@ public function run(Request $request)
273278
$response->setContent(ob_get_contents());
274279
}
275280

276-
ob_end_clean();
281+
if ($shouldUseOb) {
282+
ob_end_clean();
283+
}
277284

278285
return $response;
279286
}
@@ -372,11 +379,7 @@ protected function terminateLaravel(Request $request, $response)
372379
// clean laravel session
373380
if ($request->hasSession()) {
374381
$session = $request->getSession();
375-
if (method_exists($session, 'clear')) {
376-
$session->clear();
377-
} elseif (method_exists($session, 'flush')) {
378-
$session->flush();
379-
}
382+
$session->flush();
380383
}
381384

382385
// clean laravel cookie queue

src/Server/Manager.php

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ public function onWorkerStart(HttpServer $server)
217217
$this->bindToLaravelApp();
218218

219219
// set application to sandbox environment
220-
if ($this->isSandbox) {
220+
if ($this->isSandbox || $this->isWebsocket) {
221221
$this->sandbox = Sandbox::make($this->getApplication());
222222
}
223223

@@ -466,16 +466,6 @@ protected function setProcessName($process)
466466
*/
467467
protected function logServerError(Exception $e)
468468
{
469-
$logFile = $this->container['config']->get('swoole_http.server.options.log_file');
470-
471-
try {
472-
$output = fopen($logFile ,'w');
473-
} catch (Exception $e) {
474-
$output = STDOUT;
475-
}
476-
477-
$prefix = sprintf("[%s #%d *%d]\tERROR\t", date('Y-m-d H:i:s'), $this->server->master_pid, $this->server->worker_id);
478-
479-
fwrite($output, sprintf('%s%s(%d): %s', $prefix, $e->getFile(), $e->getLine(), $e->getMessage()) . PHP_EOL);
469+
$this->app[ExceptionHandler::class]->report($e);
480470
}
481471
}

src/Websocket/CanWebsocket.php

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
use Exception;
66
use Swoole\Websocket\Frame;
77
use Swoole\Websocket\Server;
8+
use Illuminate\Pipeline\Pipeline;
89
use SwooleTW\Http\Server\Request;
910
use SwooleTW\Http\Websocket\Parser;
11+
use Illuminate\Support\Facades\Facade;
1012
use SwooleTW\Http\Websocket\Websocket;
1113
use SwooleTW\Http\Websocket\HandlerContract;
1214
use SwooleTW\Http\Websocket\Rooms\RoomContract;
@@ -57,12 +59,13 @@ public function onOpen(Server $server, $swooleRequest)
5759

5860
try {
5961
// check if socket.io connection established
60-
if ($this->websocketHandler->onOpen($swooleRequest->fd, $illuminateRequest)) {
61-
$this->websocket->reset(true)->setSender($swooleRequest->fd);
62-
// trigger 'connect' websocket event
63-
if ($this->websocket->eventExists('connect')) {
64-
$this->websocket->call('connect', $illuminateRequest);
65-
}
62+
if (! $this->websocketHandler->onOpen($swooleRequest->fd, $illuminateRequest)) {
63+
return;
64+
}
65+
$this->websocket->reset(true)->setSender($swooleRequest->fd);
66+
// trigger 'connect' websocket event
67+
if ($this->websocket->eventExists('connect')) {
68+
$this->callOnConnect($illuminateRequest);
6669
}
6770
} catch (Exception $e) {
6871
$this->logServerError($e);
@@ -80,16 +83,17 @@ public function onMessage(Server $server, Frame $frame)
8083
$data = $frame->data;
8184

8285
try {
83-
$skip = $this->parser->execute($server, $frame);
84-
85-
if ($skip) {
86+
// execute parser strategies and skip non-message packet
87+
if ($this->parser->execute($server, $frame)) {
8688
return;
8789
}
8890

91+
// decode raw message via parser
8992
$payload = $this->parser->decode($frame);
9093

9194
$this->websocket->reset(true)->setSender($frame->fd);
9295

96+
// dispatch message to registered event callback
9397
if ($this->websocket->eventExists($payload['event'])) {
9498
$this->websocket->call($payload['event'], $payload['data']);
9599
} else {
@@ -241,7 +245,7 @@ protected function bindRoom()
241245
protected function bindWebsocket()
242246
{
243247
$this->app->singleton(Websocket::class, function ($app) {
244-
return $this->websocket = new Websocket($app['swoole.room']);
248+
return $this->websocket = new Websocket($app['swoole.room'], new Pipeline);
245249
});
246250
$this->app->alias(Websocket::class, 'swoole.websocket');
247251
}
@@ -275,4 +279,27 @@ protected function normalizePushData(array $data)
275279

276280
return [$opcode, $sender, $fds, $broadcast, $assigned, $event, $message];
277281
}
282+
283+
/**
284+
* Call on connect event callback .
285+
*/
286+
protected function callOnConnect($illuminateRequest)
287+
{
288+
$application = $this->sandbox->getLaravelApp();
289+
290+
// bind illuminate request to laravel/lumen
291+
$application->instance('request', $illuminateRequest);
292+
Facade::clearResolvedInstance('request');
293+
294+
// reset session
295+
if (isset($application['session'])) {
296+
$application['session']->flush();
297+
}
298+
299+
// set sandbox container to websocket pipeline
300+
$this->websocket->setContainer($application);
301+
$this->sandbox->enable();
302+
$this->websocket->call('connect', $illuminateRequest);
303+
$this->sandbox->disable();
304+
}
278305
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace SwooleTW\Http\Websocket\Middleware;
4+
5+
use Closure;
6+
use Illuminate\Auth\AuthenticationException;
7+
use Illuminate\Contracts\Auth\Factory as Auth;
8+
9+
class Authenticate
10+
{
11+
/**
12+
* The authentication factory instance.
13+
*
14+
* @var \Illuminate\Contracts\Auth\Factory
15+
*/
16+
protected $auth;
17+
18+
/**
19+
* Create a new middleware instance.
20+
*
21+
* @param \Illuminate\Contracts\Auth\Factory $auth
22+
* @return void
23+
*/
24+
public function __construct(Auth $auth)
25+
{
26+
$this->auth = $auth;
27+
}
28+
29+
/**
30+
* Handle an incoming request.
31+
*
32+
* @param \Illuminate\Http\Request $request
33+
* @param \Closure $next
34+
* @return mixed
35+
*
36+
* @throws \Illuminate\Auth\AuthenticationException
37+
*/
38+
public function handle($request, Closure $next)
39+
{
40+
try {
41+
if ($user = $this->auth->authenticate()) {
42+
$request->setUserResolver(function () use ($user) {
43+
return $user;
44+
});
45+
}
46+
} catch (AuthenticationException $e) {
47+
// do nothing
48+
}
49+
50+
return $next($request);
51+
}
52+
}

0 commit comments

Comments
 (0)