2
2
3
3
namespace Rx \Websocket ;
4
4
5
- use GuzzleHttp \Psr7 \Uri ;
5
+ use GuzzleHttp \Psr7 \Request ;
6
+ use Psr \Http \Message \ServerRequestInterface ;
6
7
use Ratchet \RFC6455 \Handshake \RequestVerifier ;
7
8
use Ratchet \RFC6455 \Handshake \ServerNegotiator ;
8
9
use React \EventLoop \LoopInterface ;
9
- use React \Http \Request ;
10
10
use React \Http \Response ;
11
+ use React \Http \Server as HttpServer ;
12
+ use React \Socket \Server as SocketServer ;
13
+ use React \Stream \CompositeStream ;
14
+ use React \Stream \ReadableStreamInterface ;
15
+ use React \Stream \ThroughStream ;
11
16
use Rx \Disposable \CallbackDisposable ;
12
17
use Rx \DisposableInterface ;
13
18
use Rx \Observable ;
@@ -23,53 +28,56 @@ class Server extends Observable
23
28
private $ subProtocols ;
24
29
private $ loop ;
25
30
26
- public function __construct (string $ bindAddress , int $ port , bool $ useMessageObject = false , array $ subProtocols = [], LoopInterface $ loop = null )
31
+ public function __construct (string $ bindAddressOrPort , bool $ useMessageObject = false , array $ subProtocols = [], LoopInterface $ loop = null )
27
32
{
28
- $ this ->bindAddress = $ bindAddress ;
29
- $ this ->port = $ port ;
33
+ $ this ->bindAddress = $ bindAddressOrPort ;
30
34
$ this ->useMessageObject = $ useMessageObject ;
31
35
$ this ->subProtocols = $ subProtocols ;
32
36
$ this ->loop = $ loop ?: \EventLoop \getLoop ();
33
37
}
34
38
35
39
public function _subscribe (ObserverInterface $ observer ): DisposableInterface
36
40
{
37
- $ socket = new \ React \ Socket \ Server ( $ this ->loop );
41
+ $ socket = new SocketServer ( $ this -> bindAddress , $ this ->loop );
38
42
39
43
$ negotiator = new ServerNegotiator (new RequestVerifier ());
40
44
if (!empty ($ this ->subProtocols )) {
41
45
$ negotiator ->setSupportedSubProtocols ($ this ->subProtocols );
42
46
}
43
47
44
- $ http = new \React \Http \Server ($ socket );
45
- $ http ->on ('request ' , function (Request $ request , Response $ response ) use ($ negotiator , $ observer , &$ outStream ) {
46
- $ uri = new Uri ($ request ->getPath ());
47
- if (count ($ request ->getQuery ()) > 0 ) {
48
- $ uri = $ uri ->withQuery (\GuzzleHttp \Psr7 \build_query ($ request ->getQuery ()));
49
- }
48
+ $ http = new HttpServer (function (ServerRequestInterface $ request ) use ($ negotiator , $ observer ) {
49
+ $ uri = $ request ->getUri ();
50
50
51
- $ psrRequest = new \ GuzzleHttp \ Psr7 \ Request (
51
+ $ psrRequest = new Request (
52
52
$ request ->getMethod (),
53
53
$ uri ,
54
54
$ request ->getHeaders ()
55
55
);
56
56
57
57
// cram the remote address into the header in our own X- header so
58
58
// the user will have access to it
59
- $ psrRequest = $ psrRequest ->withAddedHeader ('X-RxWebsocket-Remote-Address ' , $ request ->remoteAddress );
59
+ $ psrRequest = $ psrRequest ->withAddedHeader ('X-RxWebsocket-Remote-Address ' , $ request ->getServerParams ()[ ' REMOTE_ADDR ' ] ?? '' );
60
60
61
61
$ negotiatorResponse = $ negotiator ->handshake ($ psrRequest );
62
62
63
- $ response ->writeHead (
63
+ /** @var ReadableStreamInterface $requestStream */
64
+ $ requestStream = new ThroughStream ();
65
+ $ responseStream = new ThroughStream ();
66
+
67
+ $ response = new Response (
64
68
$ negotiatorResponse ->getStatusCode (),
65
69
array_merge (
66
- $ negotiatorResponse ->getHeaders (),
67
- ['Content-Length ' => '0 ' ]
70
+ $ negotiatorResponse ->getHeaders ()
71
+ ),
72
+ new CompositeStream (
73
+ $ responseStream ,
74
+ $ requestStream
68
75
)
69
76
);
70
77
78
+
71
79
if ($ negotiatorResponse ->getStatusCode () !== 101 ) {
72
- $ response ->end ();
80
+ $ responseStream ->end ();
73
81
return ;
74
82
}
75
83
@@ -78,38 +86,38 @@ public function _subscribe(ObserverInterface $observer): DisposableInterface
78
86
$ subProtocol = $ negotiatorResponse ->getHeader ('Sec-WebSocket-Protocol ' )[0 ];
79
87
}
80
88
81
- $ connection = new MessageSubject (
89
+ $ messageSubject = new MessageSubject (
82
90
new AnonymousObservable (
83
- function (ObserverInterface $ observer ) use ($ request ) {
84
- $ request ->on ('data ' , function ($ data ) use ($ observer ) {
91
+ function (ObserverInterface $ observer ) use ($ requestStream ) {
92
+ $ requestStream ->on ('data ' , function ($ data ) use ($ observer ) {
85
93
$ observer ->onNext ($ data );
86
94
});
87
- $ request ->on ('error ' , function ($ error ) use ($ observer ) {
95
+ $ requestStream ->on ('error ' , function ($ error ) use ($ observer ) {
88
96
$ observer ->onError ($ error );
89
97
});
90
- $ request ->on ('close ' , function () use ($ observer ) {
98
+ $ requestStream ->on ('close ' , function () use ($ observer ) {
91
99
$ observer ->onCompleted ();
92
100
});
93
- $ request ->on ('end ' , function () use ($ observer ) {
101
+ $ requestStream ->on ('end ' , function () use ($ observer ) {
94
102
$ observer ->onCompleted ();
95
103
});
96
104
97
105
return new CallbackDisposable (
98
- function () use ($ request ) {
99
- $ request ->close ();
106
+ function () use ($ requestStream ) {
107
+ $ requestStream ->close ();
100
108
}
101
109
);
102
110
}
103
111
),
104
112
new CallbackObserver (
105
- function ($ x ) use ($ response ) {
106
- $ response ->write ($ x );
113
+ function ($ x ) use ($ responseStream ) {
114
+ $ responseStream ->write ($ x );
107
115
},
108
- function ($ error ) use ($ response ) {
109
- $ response ->close ();
116
+ function ($ error ) use ($ responseStream ) {
117
+ $ responseStream ->close ();
110
118
},
111
- function () use ($ response ) {
112
- $ response ->end ();
119
+ function () use ($ responseStream ) {
120
+ $ responseStream ->end ();
113
121
}
114
122
),
115
123
false ,
@@ -119,13 +127,15 @@ function () use ($response) {
119
127
$ negotiatorResponse
120
128
);
121
129
122
- $ observer ->onNext ($ connection );
130
+ $ observer ->onNext ($ messageSubject );
131
+
132
+ return $ response ;
123
133
});
124
134
125
- $ socket ->listen ($ this -> port , $ this -> bindAddress );
135
+ $ http ->listen ($ socket );
126
136
127
137
return new CallbackDisposable (function () use ($ socket ) {
128
- $ socket ->shutdown ();
138
+ $ socket ->close ();
129
139
});
130
140
}
131
141
}
0 commit comments