|
| 1 | +# CodeIgniter WebSocket Library |
| 2 | +CodeIgniter library realtime communication by using Websocket technology and Ratchet ([Socketo.me](http://socketo.me) & [ratchet_client](https://github.com/romainrg/ratchet_client)) |
| 3 | + |
| 4 | +## :books: Dependencies |
| 5 | + |
| 6 | +- PHP 5.4+ |
| 7 | +- CodeIgniter Framework (3.1.* recommanded) |
| 8 | +- Composer |
| 9 | +- PHP sockets extension enabled |
| 10 | + |
| 11 | +## :beginner: Installation |
| 12 | + |
| 13 | +### :arrow_right: Step 1 : Library installation by Composer |
| 14 | + |
| 15 | +Just by running following command in the folder of your project : |
| 16 | +```sh |
| 17 | +composer require takielias/codeigniter-websocket |
| 18 | +``` |
| 19 | +Or by adding following lines to your `composer.json` file : |
| 20 | +```json |
| 21 | +"require": { |
| 22 | + "takielias/codeigniter-websocket": "^1.0.0" |
| 23 | +}, |
| 24 | +``` |
| 25 | +Don't forget to include your autoload to CI config file : |
| 26 | +```php |
| 27 | +$config['composer_autoload'] = FCPATH.'vendor/autoload.php'; |
| 28 | +``` |
| 29 | +### :arrow_right: Step 2 : Create library config file in your project (Optional) |
| 30 | + |
| 31 | +You have to create in your CI config folder located in `./application/config/Codeigniter_websocket.php` or the library will take his own config file based on host `0.0.0.0:8282` |
| 32 | + |
| 33 | +```php |
| 34 | +<?php |
| 35 | +defined('BASEPATH') or exit('No direct script access allowed'); |
| 36 | + |
| 37 | +/** |
| 38 | + * Ratchet Websocket Library: config file |
| 39 | + * @author Romain GALLIEN <romaingallien.rg@gmail.com> |
| 40 | + * @var array |
| 41 | + */ |
| 42 | +$config['Codeigniter_websocket'] = array( |
| 43 | + 'host' => '0.0.0.0', // Default host |
| 44 | + 'port' => 8282, // Default port (be carrefull to set unused server port) |
| 45 | + 'auth' => true, // If authentication is mandatory |
| 46 | + 'debug' => true // Better to set as false in Production |
| 47 | +); |
| 48 | +``` |
| 49 | +### :arrow_right: Step 3 : Loading the library |
| 50 | + |
| 51 | +You can add the following lines direclty in your Controller file or your MY_Controller global file |
| 52 | + |
| 53 | +```php |
| 54 | +$this->load->add_package_path(FCPATH.'vendor/romainrg/codeigniter-ratchet-websocket'); |
| 55 | +$this->load->library('Codeigniter_websocket'); |
| 56 | +$this->load->remove_package_path(FCPATH.'vendor/romainrg/codeigniter-ratchet-websocket'); |
| 57 | +``` |
| 58 | + |
| 59 | +### You'r almost done :heavy_check_mark: |
| 60 | + |
| 61 | +## Examples of use |
| 62 | + |
| 63 | +#### :arrow_right: Create your first App |
| 64 | + |
| 65 | +It's not very difficult, the library will do your job and much more ! |
| 66 | +- Edit your CI controller `Welcome.php` with the following lines (this will be our server) |
| 67 | + |
| 68 | +```php |
| 69 | +class Welcome extends CI_Controller |
| 70 | +{ |
| 71 | + public function index() |
| 72 | + { |
| 73 | + // Load package path |
| 74 | + $this->load->add_package_path(FCPATH.'vendor/romainrg/codeigniter-ratchet-websocket'); |
| 75 | + $this->load->library('Codeigniter_websocket'); |
| 76 | + $this->load->remove_package_path(FCPATH.'vendor/romainrg/codeigniter-ratchet-websocket'); |
| 77 | + |
| 78 | + // Run server |
| 79 | + $this->Codeigniter_websocket->run(); |
| 80 | + } |
| 81 | +} |
| 82 | +``` |
| 83 | +- Create CI controller `User.php` and add following lines |
| 84 | +```php |
| 85 | +class User extends CI_Controller |
| 86 | +{ |
| 87 | + public function index($user_id = null) |
| 88 | + { |
| 89 | +// We load the CI welcome page with some lines of Javascript |
| 90 | + $this->load->view('welcome_message', array('user_id' => $user_id)); |
| 91 | + } |
| 92 | +} |
| 93 | +``` |
| 94 | +- Edit your CI view `welcome_message.php` with following lines (again :stuck_out_tongue_winking_eye:) |
| 95 | +```php |
| 96 | +<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?> |
| 97 | +<!DOCTYPE html> |
| 98 | +<html lang="en"> |
| 99 | +<head> |
| 100 | + <meta charset="utf-8"> |
| 101 | + <title>Welcome to CodeIgniter</title> |
| 102 | + <style type="text/css"> |
| 103 | + #container,code{border:1px solid #D0D0D0}::selection{background-color:#E13300;color:#fff}::-moz-selection{background-color:#E13300;color:#fff}body{background-color:#fff;margin:40px;font:13px/20px normal Helvetica,Arial,sans-serif;color:#4F5155}a,h1{background-color:transparent;font-weight:400}a{color:#039}h1{color:#444;border-bottom:1px solid #D0D0D0;font-size:19px;margin:0 0 14px;padding:14px 15px 10px}code{font-family:Consolas,Monaco,Courier New,Courier,monospace;font-size:12px;background-color:#f9f9f9;color:#002166;display:block;margin:14px 0;padding:12px 10px}#body{margin:0 15px}p.footer{text-align:right;font-size:11px;border-top:1px solid #D0D0D0;line-height:32px;padding:0 10px;margin:20px 0 0}#container{margin:10px;box-shadow:0 0 8px #D0D0D0} |
| 104 | + </style> |
| 105 | +</head> |
| 106 | +<body> |
| 107 | + <div id="container"> |
| 108 | + <h1>Welcome to CodeIgniter!</h1> |
| 109 | + <div id="body"> |
| 110 | + <div id="messages"></div> |
| 111 | + <input type="text" id="text" placeholder="Message .."> |
| 112 | + <input type="text" id="recipient_id" placeholder="Recipient id .."> |
| 113 | + <button id="submit" value="POST">Send</button> |
| 114 | + </div> |
| 115 | + <p class="footer">Page rendered in <strong>{elapsed_time}</strong> seconds. <?php echo (ENVIRONMENT === 'development') ? 'CodeIgniter Version <strong>' . CI_VERSION . '</strong>' : '' ?></p> |
| 116 | + </div> |
| 117 | + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> |
| 118 | + <script> |
| 119 | + var conn = new WebSocket('ws://localhost:8282'); |
| 120 | + var client = { |
| 121 | + user_id: <?php echo $user_id; ?>, |
| 122 | + recipient_id: null, |
| 123 | + message: null |
| 124 | + }; |
| 125 | +
|
| 126 | + conn.onopen = function(e) { |
| 127 | + conn.send(JSON.stringify(client)); |
| 128 | + $('#messages').append('<font color="green">Successfully connected as user '+ client.user_id +'</font><br>'); |
| 129 | + }; |
| 130 | +
|
| 131 | + conn.onmessage = function(e) { |
| 132 | + var data = JSON.parse(e.data); |
| 133 | + if (data.message) { |
| 134 | + $('#messages').append(data.user_id + ' : ' + data.message + '<br>'); |
| 135 | + } |
| 136 | + }; |
| 137 | +
|
| 138 | + $('#submit').click(function() { |
| 139 | + client.message = $('#text').val(); |
| 140 | + if ($('#recipient_id').val()) { |
| 141 | + client.recipient_id = $('#recipient_id').val(); |
| 142 | + } |
| 143 | + conn.send(JSON.stringify(client)); |
| 144 | + }); |
| 145 | + </script> |
| 146 | +</body> |
| 147 | +</html> |
| 148 | +``` |
| 149 | +**Ok you just created your first app !** :heavy_check_mark: (easy with CTRL+C and CTRL+V) |
| 150 | +#### :arrow_right: Run the Websocket server |
| 151 | +If you wan't to check you'r work, you have to run the server. |
| 152 | +Open you'r command prompt then type the command bellow in you'r project folder : |
| 153 | +```sh |
| 154 | +php index.php welcome index |
| 155 | +``` |
| 156 | +If you see the message the message bellow, you are done (don't close your cmd) ! |
| 157 | + |
| 158 | + |
| 159 | +#### :arrow_right: Test the App |
| 160 | +Open three pages of your project on following url with different IDs : |
| 161 | +`http://localhost/myproject/user/index/204` |
| 162 | +`http://localhost/myproject/user/index/402` |
| 163 | +`http://localhost/myproject/user/index/604` |
| 164 | + |
| 165 | +:heavy_exclamation_mark: In my example, **recipient_id** is defined by **user_id**, as you can see, it's the **auth callback** who defines recipient ids. |
| 166 | + |
| 167 | +If you have something like that, everything is ok for you: |
| 168 | + |
| 169 | + |
| 170 | + |
| 171 | +You can try is by typing and sending something in each page (see cmd for more logs). |
| 172 | + |
| 173 | + |
| 174 | + |
| 175 | +## Broadcast messages with your php App :boom: ! |
| 176 | +If you want to broadcast message with php script or something else you can use library like [textalk/websocket](https://github.com/Textalk/websocket-php) ***(who is included in my composer.json as required library)*** |
| 177 | + |
| 178 | +> *Note : The first message is mandatory and always here to perform authentication* |
| 179 | +
|
| 180 | +```php |
| 181 | +$client = new Client('ws://0.0.0.0:8282'); |
| 182 | + |
| 183 | +$client->send(json_encode(array('user_id' => 1, 'message' => null))); |
| 184 | +$client->send(json_encode(array('user_id' => 1, 'message' => 'Super cool message to myself!'))); |
| 185 | +``` |
| 186 | +## Authentication & callbacks :recycle: |
| 187 | +The library allow you to define some callbacks, here's an example : |
| 188 | +```php |
| 189 | +class Welcome extends CI_Controller |
| 190 | +{ |
| 191 | + public function index() |
| 192 | + { |
| 193 | + // Load package path |
| 194 | + $this->load->add_package_path(FCPATH.'vendor/romainrg/codeigniter-ratchet-websocket'); |
| 195 | + $this->load->library('Codeigniter_websocket'); |
| 196 | + $this->load->remove_package_path(FCPATH.'vendor/romainrg/codeigniter-ratchet-websocket'); |
| 197 | + |
| 198 | + // Run server |
| 199 | + $this->Codeigniter_websocket->set_callback('auth', array($this, '_auth')); |
| 200 | + $this->Codeigniter_websocket->set_callback('event', array($this, '_event')); |
| 201 | + $this->Codeigniter_websocket->run(); |
| 202 | + } |
| 203 | + |
| 204 | + public function _auth($datas = null) |
| 205 | + { |
| 206 | + // Here you can verify everything you want to perform user login. |
| 207 | + // However, method must return integer (client ID) if auth succedeed and false if not. |
| 208 | + return (!empty($datas->user_id)) ? $datas->user_id : false; |
| 209 | + } |
| 210 | + |
| 211 | + public function _event($datas = null) |
| 212 | + { |
| 213 | + // Here you can do everyting you want, each time message is received |
| 214 | + echo 'Hey ! I\'m an EVENT callback'.PHP_EOL; |
| 215 | + } |
| 216 | +} |
| 217 | +``` |
| 218 | + |
| 219 | + - **Auth** type callback is called at first message posted from client. |
| 220 | + - **Event** type callback is called on every message posted. |
| 221 | + |
| 222 | +## What about Docker :whale: ? |
| 223 | + |
| 224 | +Easy to start with this command (php 7.1 used) |
| 225 | +```sh |
| 226 | +docker run -ti -v C:\Users\my_user\path_to_my_project\:/app -p 8282:8282 -w /app php:7.1-cli sh -c "php index.php welcome index" |
| 227 | +``` |
| 228 | +## Bugs :bug: or feature :muscle: |
| 229 | +Be free to open an issue or send pull request |
| 230 | + |
| 231 | +## To do :construction: |
| 232 | + - Origin check |
| 233 | + - WSS support |
| 234 | + - Add app routing fonctionnality |
| 235 | + - Websocket native library |
| 236 | +## For more CodeIgniter libraries, give me a :beer::grin: |
| 237 | +[> Beer road](https://www.paypal.me/romaingallien) |
| 238 | + |
| 239 | +## :lock: License |
| 240 | +[MIT License](http://opensource.org/licenses/MIT) |
0 commit comments