-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
226 lines (195 loc) · 7.35 KB
/
index.html
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
---
layout: base
title: Websockets powered by PHP and Symfony
---
<div class="jumbotron jumbotron-fluid">
<div class="container">
<h1>Sandstone</h1>
<p>Build a real time RestApi.</p>
<div class="jumbo-links">
<a href="{{ site.baseurl }}/get-started" class="btn btn-lg btn-primary">
<i class="fa fa-book" aria-hidden="true"></i>
Get started
</a>
<a href="https://github.com/eole-io/sandstone" class="btn btn-lg btn-primary btn-github">
<i class="fa fa-github" aria-hidden="true"></i>
Github
</a>
</div>
</div>
</div>
<div class="container home-content">
<div class="row">
<div class="col-sm-10 offset-sm-1">
<p class="lead text-center">
Sandstone is a PHP microframework designed to build a RestApi
working together with a websocket server.
</p>
</div>
</div>
<h2>What can I do with Sandstone</h2>
<p>
<i>Microframework</i> means you can declare
RestApi endpoints and websocket topics in a minimalist way.
</p>
<p>
<i>Working together</i> means you can send push notifications to web client
even from RestApi controllers.
</p>
<p>
So you can mount real time RestApi, then:
</p>
<ul>
<li>Notify all web clients that a new article has just been created through the RestApi</li>
<li>Create a chat working with your RestApi</li>
<li>For a game server, broadcasting players moves as soon as someone played</li>
</ul>
<h2>Live examples</h2>
<h3>Create a simple chat topic</h3>
<pre><code class="language-php">$app->topic('chat/demo', function ($topicPattern) {
return new class ($topicPattern) extends Topic
{
public function onPublish(WampConnection $conn, $topic, $event)
{
$this->broadcast([
'message' => $event,
]);
}
};
});</code></pre>
<div class="input-group input-group-chat">
<div class="input-group-prepend d-none d-md-flex">
<span class="input-group-text"><code>session.publish('chat/demo', '</code></span>
</div>
<input type="text" class="form-control chat-input" value="Hello world!">
<div class="input-group-append">
<span class="input-group-text d-none d-md-flex"><code>');</code></span>
<button class="btn btn-success" type="button">Send</button>
</div>
</div>
<div class="card bg-secondary text-white">
<div class="card-body">
<div class="live-output chat-output">
</div>
</div>
</div>
<h3>Dispatch push event on Rest API call</h3>
<p>
It is possible to dispatch an event from Rest Api controller,
and listen to it from a websocket topic for i.e broadcast it.
</p>
<p>See that live example of a simple Push event:</p>
<p class="file">RestApi stack</p>
<div class="language-php">
<pre class="highlight language-php"><code class="language-php">/**
* Dispatch push event on Rest API call
*/
$app->post('api/hello/{name}', function ($name) use ($app) {
$event = new HelloEvent();
$event->name = $name;
$app['dispatcher']->dispatch('event.hello', $event);
return new JsonResponse(['hello' => $name]);
})->value('name', 'world');
// Forward event to websocket process
$app->forwardEventToPushServer('event.hello');</code></pre>
</div>
<p class="file">Websocket stack</p>
<div class="language-php">
<pre class="highlight language-php"><code class="language-php">/**
* Topic that broadcast push event
*/
$app->topic('push/demo', function ($topicPattern) {
return new class ($topicPattern) extends Topic implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
'event.hello' => 'onHelloEvent',
];
}
public function onHelloEvent(HelloEvent $event)
{
$this->broadcast([
'message' => "Someone called Rest Api /api/hello. Hello $event->name !",
]);
}
};
});</code></pre>
</div>
<button class="btn btn-success push-button post-api-hello" type="button">POST /api/hello</button>
<button class="btn btn-success push-button post-api-hello-sandstone" type="button">POST /api/hello/sandstone</button>
<div class="card bg-secondary text-white">
<div class="card-body">
<div class="live-output push-output">
</div>
</div>
</div>
<h2>How to get started</h2>
<div class="row">
<div class="col-md-6">
<h3>Using microframework</h3>
<p>
If you're familiar with microframeworks (i.e expressJS, Python Flask, or PHP Silex),
You can build a Sandstone application with only a few PHP files.
See <a href="{{ site.baseurl }}/examples/full">this full example</a>.
</p>
<p>
This way, you can create a fully customizable application.
</p>
</div>
<div class="col-md-6">
<h3>Using Sandstone edition</h3>
<p>
To create an application with already installed
a database, Symfony web profiler... in a Docker environment,
You may be insterested in the edition.
</p>
<p>
This way, you can quickly bootstrap a Sandstone application,
then be guided by the <a href="{{ site.baseurl }}/edition/cookbook">cookbook</a>
to add endpoints, topics...
</p>
</div>
</div>
<div class="row">
<div class="col-md-6">
<p class="text-center">
<a href="{{ site.baseurl }}/get-started" class="btn btn-block btn-lg btn-primary">
<i class="fa fa-book" aria-hidden="true"></i>
Get started
</a>
</p>
</div>
<div class="col-md-6">
<p class="text-center">
<a href="{{ site.baseurl }}/edition/get-started" class="btn btn-block btn-lg btn-primary">
<i class="fa fa-book" aria-hidden="true"></i>
Get started with edition
</a>
</p>
</div>
</div>
<h2>Working examples</h2>
<p>
<i class="fa fa-code" aria-hidden="true"></i>
<a href="{{ site.baseurl }}/examples/full">Full example</a>
</p>
<p>
<i class="fa fa-code" aria-hidden="true"></i>
<a href="{{ site.baseurl }}/examples/multichannel-chat">Chat example</a>
</p>
<p>
<i class="fa fa-code" aria-hidden="true"></i>
<a href="{{ site.baseurl }}/authentication">Authenticated application</a>
</p>
<p>
<i class="fa fa-github" aria-hidden="true"></i>
<a href="https://github.com/eole-io/sandstone-doc-live/tree/master/src/chat">Chat demo of this page</a>
</p>
<p>
<i class="fa fa-github" aria-hidden="true"></i>
<a href="https://github.com/eole-io/sandstone-doc-live/tree/master/src/push">Push demo of this page</a>
</p>
</div>
<script src="{{ site.baseurl }}/js/autobahn.min.js"></script>
<script src="{{ site.baseurl }}/js/live-examples.js"></script>