|
5 | 5 | <h1 align="center">Bloatless PHP WebSockets</h1>
|
6 | 6 |
|
7 | 7 | <p align="center">
|
8 |
| - Simple WebSocket server and client implemented in PHP. |
| 8 | + Simple WebSocket server implemented in PHP. |
9 | 9 | </p>
|
10 | 10 |
|
11 |
| -## About |
12 |
| - |
13 |
| -This application is an extremely simple implementation of the [WebSocket Protocol](https://tools.ietf.org/html/rfc6455) |
14 |
| -in PHP. It includes a server as well as a client. This implementation is optimal to get started with WebSockets and |
15 |
| -learn something. As soon as you want to create a full featured websocket based application you might want to switch |
16 |
| -to more sophisticated solution. |
| 11 | +- [Installation](#installation) |
| 12 | + - [Requirements](#requirements) |
| 13 | + - [Installation procedure](#installation-procedure) |
| 14 | +- [Usage](#usage) |
| 15 | + - [Server](#server) |
| 16 | + - [Applications](#applications) |
| 17 | + - [Timers](#timers) |
| 18 | + - [Push-Client (IPC)](#push-client-ipc) |
| 19 | + - [Client (Browser/JS)](#client-browserjs) |
| 20 | +- [Intended use and limitations](#intended-use-and-limitations) |
| 21 | +- [Alternatives](#alternatives) |
| 22 | +- [License](#license) |
17 | 23 |
|
18 | 24 | ## Installation
|
19 | 25 |
|
| 26 | +### Requirements |
| 27 | + |
| 28 | +* PHP >= 7.4 |
| 29 | +* ext-json |
| 30 | +* ext-sockets |
| 31 | + |
| 32 | +### Installation procedure |
| 33 | + |
20 | 34 | Clone or download the repository to your server. The package is also installable via composer running the following
|
21 | 35 | command:
|
22 | 36 |
|
23 | 37 | `composer require bloatless/php-websocket`
|
24 | 38 |
|
25 |
| -### Requirements |
| 39 | +## Usage |
26 | 40 |
|
27 |
| -* PHP >= 7.2 |
| 41 | +### Server |
28 | 42 |
|
29 |
| -Hint: You can use version 1.0 if you're still on PHP5. |
| 43 | +After downloading the sourcecode to your machine, you need some code to actually put your websocket server together. |
| 44 | +Here is a basic exmaple: |
| 45 | +```php |
| 46 | +<?php |
30 | 47 |
|
| 48 | +// require necessary files here |
31 | 49 |
|
32 |
| -## Usage |
| 50 | +// create new server instance |
| 51 | +$server = new \Bloatless\WebSocket\Server('127.0.0.1', 8000, '/tmp/phpwss.sock'); |
| 52 | + |
| 53 | +// server settings |
| 54 | +$server->setMaxClients(100); |
| 55 | +$server->setCheckOrigin(false); |
| 56 | +$server->setAllowedOrigin('example.com'); |
| 57 | +$server->setMaxConnectionsPerIp(20); |
33 | 58 |
|
34 |
| -* Adjust `cli/server.php` to your requirements. |
35 |
| -* Run: `php cli/server.php` |
| 59 | +// add your applications |
| 60 | +$server->registerApplication('status', \Bloatless\WebSocket\Application\StatusApplication::getInstance()); |
| 61 | +$server->registerApplication('chat', \Bloatless\WebSocket\Examples\Application\Chat::getInstance()); |
| 62 | + |
| 63 | +// start the server |
| 64 | +$server->run(); |
| 65 | +``` |
| 66 | + |
| 67 | +Assuming this code is in a file called `server.php` you can than start your server with the following command: |
| 68 | + |
| 69 | +```shell |
| 70 | +php server.php |
| 71 | +``` |
| 72 | + |
| 73 | +The websocket server will than listen for new connection on the provided host and port. By default, this will be |
| 74 | +`localhost:8000`. |
36 | 75 |
|
37 |
| -This will start a websocket server. (By default on localhost:8000) |
| 76 | +This repositoy also includes a working example in [examples/server.php](examples/server.php) |
38 | 77 |
|
39 |
| -### Server example |
| 78 | +### Applications |
40 | 79 |
|
41 |
| -This will create a websocket server listening on port 8000. |
| 80 | +The websocket server itself handles connections but is pretty useless without any addional logic. This logic is added |
| 81 | +by applications. In the example above two applications are added to the server: `status` and `chat`. |
42 | 82 |
|
43 |
| -There a two applications registred to the server. The demo application will be available at `ws://localhost:8000/demo` |
44 |
| -and the status application will be available at `ws://localhost:8000/status`. |
| 83 | +The most important methods in your application will be: |
45 | 84 |
|
46 | 85 | ```php
|
47 |
| -// Require neccessary files here... |
| 86 | +interface ApplicationInterface |
| 87 | +{ |
| 88 | + public function onConnect(Connection $connection): void; |
48 | 89 |
|
49 |
| -$server = new \Bloatless\WebSocket\Server('127.0.0.1', 8000); |
| 90 | + public function onDisconnect(Connection $connection): void; |
50 | 91 |
|
51 |
| -// Server settings: |
52 |
| -$server->setMaxClients(100); |
53 |
| -$server->setCheckOrigin(false); |
54 |
| -$server->setAllowedOrigin('foo.lh'); |
55 |
| -$server->setMaxConnectionsPerIp(100); |
| 92 | + public function onData(string $data, Connection $client): void; |
56 | 93 |
|
57 |
| -// Add your applications here: |
58 |
| -$server->registerApplication('status', \Bloatless\WebSocket\Application\StatusApplication::getInstance()); |
59 |
| -$server->registerApplication('demo', \Bloatless\WebSocket\Application\DemoApplication::getInstance()); |
| 94 | + public function onIPCData(array $data): void; |
| 95 | +} |
| 96 | +``` |
60 | 97 |
|
61 |
| -$server->run(); |
| 98 | +`onConnet` and `onDisconnect` can be used to keep track of all the clients connected to your application. `onData` will |
| 99 | +be called whenever the websocket server receives new data from one of the clients connect to the application. |
| 100 | +`onIPCData` will be called if data is provided by another process on your machine. (See [Push-Client (IPC)](#push-client-ipc)) |
| 101 | + |
| 102 | +A working example of an application can be found in [examples/Application/Chat.php](examples/Application/Chat.php) |
| 103 | + |
| 104 | +### Timers |
62 | 105 |
|
| 106 | +A common requirement to long-running processes such as a websocket server is to execute tasks periodically. This can |
| 107 | +be done using timers. Timers can execute methods within your server or application periodically. Here is an example: |
| 108 | + |
| 109 | +```php |
| 110 | +$server = new \Bloatless\WebSocket\Server('127.0.0.1', 8000, '/tmp/phpwss.sock'); |
| 111 | +$chat = \Bloatless\WebSocket\Examples\Application\Chat::getInstance(); |
| 112 | +$server->addTimer(5000, function () use ($chat) { |
| 113 | + $chat->someMethod(); |
| 114 | +}); |
| 115 | +$server->registerApplication('chat', $chat); |
63 | 116 | ```
|
64 | 117 |
|
65 |
| -### Client example |
| 118 | +This example would call the method `someMethod` within your chat application every 5 seconds. |
| 119 | + |
| 120 | +### Push-Client (IPC) |
66 | 121 |
|
67 |
| -This creates a WebSocket cliente, connects to a server and sends a message to the server: |
| 122 | +It is often required to push data into the websocket-server process from another application. Let's assume you run a |
| 123 | +website containg a chat and an area containing news or a blog. Now every time a new article is published in your blog |
| 124 | +you want to notify all users currently in your chat. To achieve this you somehow need to push data from your blog |
| 125 | +logic into the websocket server. This is where the Push-Client comes into play. |
| 126 | + |
| 127 | +When starting the websocket server, it opens a unix-domain-socket and listens for new messages. The Push-Client can |
| 128 | +than be used to send these messages. Here is an example: |
68 | 129 |
|
69 | 130 | ```php
|
70 |
| -$client = new \Bloatless\WebSocket\Client; |
71 |
| -$client->connect('127.0.0.1', 8000, '/demo', 'foo.lh'); |
72 |
| -$client->sendData([ |
| 131 | +$pushClient = new \Bloatless\WebSocket\PushClient('//tmp/phpwss.sock'); |
| 132 | +$pushClient->sendToApplication('chat', [ |
73 | 133 | 'action' => 'echo',
|
74 |
| - 'data' => 'Hello Wolrd!' |
| 134 | + 'data' => 'New blog post was published!', |
75 | 135 | ]);
|
76 | 136 | ```
|
77 | 137 |
|
78 |
| -### Browser example |
| 138 | +This code pushes data into your running websocket-server process. In this case the `echo` Method within the |
| 139 | +chat-application is called and sends the provided message to all connected clients. |
| 140 | + |
| 141 | +You can find the full working example in: [examples/push.php](examples/push.php) |
| 142 | + |
| 143 | +**Important Hint:** Push messages can be not larger than 64kb! |
| 144 | + |
| 145 | +### Client (Browser/JS) |
| 146 | + |
| 147 | +Everything above this point was related to the server-side of things. But how to connect to the server from your |
| 148 | +browser? |
| 149 | + |
| 150 | +Here is a simple example: |
| 151 | + |
| 152 | +```html |
| 153 | +<script> |
| 154 | + // connect to chat application on server |
| 155 | +let serverUrl = 'ws://127.0.0.1:8000/chat'; |
| 156 | +let socket = new WebSocket(serverUrl); |
| 157 | +
|
| 158 | +// log new messages to console |
| 159 | +socket.onmessage = (msg) => { |
| 160 | + let response = JSON.parse(msg.data); |
| 161 | + console.log(response.data); |
| 162 | +}; |
| 163 | +</script> |
| 164 | +``` |
| 165 | + |
| 166 | +This javascript connects to the chat application on your server and prints all incoming messages into the console. |
| 167 | + |
| 168 | +A better example of the chat client can be found in: [examples/public/chat.html](examples/public/chat.html) |
| 169 | + |
| 170 | +## Intended use and limitations |
| 171 | + |
| 172 | +This project was mainly build for educational purposes. The code is relatively simple and easy to understand. This |
| 173 | +server was **not tested in production**, so I strongly recommand to not use it on a live project. It should be totally |
| 174 | +fine for small educational projects or internal tools, but most probably will not handle huge amounts of traffic or |
| 175 | +connections very well. |
| 176 | + |
| 177 | +Also, some "features" are missing by design: |
| 178 | + |
| 179 | +* SSL is not supported. If required, you can use a reverse proxy like nginx. |
| 180 | +* Binary messages are not supported. |
| 181 | +* A lot of other stuff I did not even realize ;) |
| 182 | + |
| 183 | +In case you need a more "robust" websocket server written in PHP, please have a look at the excellent alternatives |
| 184 | +listed below. |
| 185 | + |
| 186 | +## Alternatives |
| 187 | + |
| 188 | +* [Ratchet](https://github.com/ratchetphp/Ratchet) |
| 189 | +* [Wrench](https://github.com/varspool/Wrench) |
79 | 190 |
|
80 |
| -The repository contains two demo-pages to call in your browser. You can find them in the `public` folder. |
81 |
| -The `index.html` is a simple application which you can use to send messages to the server. |
| 191 | +## License |
82 | 192 |
|
83 |
| -The `status.html` will display various server information. |
| 193 | +MIT |
0 commit comments