Skip to content

Commit dfa977c

Browse files
committed
Init Push
1 parent 99f2177 commit dfa977c

File tree

6 files changed

+839
-0
lines changed

6 files changed

+839
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ application/logs/*
1515
!application/logs/index.html
1616
!application/logs/.htaccess
1717
/vendor/
18+
19+
#composer
20+
composer.lock

README.md

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
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+
![First_launch.png](https://user-images.githubusercontent.com/14097222/40981263-d568413a-68da-11e8-9ab2-7b3f7224526e.PNG)
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+
![User_204](https://user-images.githubusercontent.com/14097222/40725234-2d7ea6aa-6423-11e8-975e-4372125c889d.PNG)
170+
171+
You can try is by typing and sending something in each page (see cmd for more logs).
172+
173+
![Cmd_list.png](https://user-images.githubusercontent.com/14097222/40981966-819da07a-68dc-11e8-9717-b0135a107318.PNG)
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)

composer.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "takielias/codeigniter-websocket",
3+
"keywords": [
4+
"php7",
5+
"php-library",
6+
"codeigniter websocket",
7+
"codeigniter",
8+
"websocket",
9+
"realtime",
10+
"Ratchet"
11+
],
12+
"description": "CodeIgniter Websocket using Ratchet Websocket technology. Inspired by https://github.com/romainrg/ratchet_client",
13+
"homepage": "https://github.com/takielias/codeigniter-websocket",
14+
"license": "MIT",
15+
"type": "library",
16+
"authors": [{
17+
"name": "Taki Elias",
18+
"email": "taki.elias@gmail.com",
19+
"homepage": "http://www.cheapapp.net",
20+
"role": "Software Engineer"
21+
}],
22+
"require": {
23+
"php": ">=5.4.0",
24+
"cboden/ratchet": "^0.4.1",
25+
"textalk/websocket": "^1.2"
26+
},
27+
"extra": {
28+
"installer-name": "codeigniter-websocket"
29+
},
30+
"support": {
31+
"email": "taki.elias@gmail.com"
32+
}
33+
}

config/codeigniter_websocket.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
defined('BASEPATH') OR exit('No direct script access allowed');
3+
4+
/**
5+
* Ratchet Websocket Library: config file
6+
* @author Romain GALLIEN <romaingallien.rg@gmail.com>
7+
* @var array
8+
*/
9+
$config['codeigniter_websocket'] = array(
10+
'host' => '0.0.0.0',
11+
'port' => 8282,
12+
'timer_enabled' => false,
13+
'timer_interval' => 1, //1 means 1 seconds
14+
'auth' => true,
15+
'debug' => true
16+
);
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
defined('BASEPATH') or exit('No direct script access allowed');
3+
4+
/**
5+
* Ratchet Websocket Library: helper file
6+
* @author Romain GALLIEN <romaingallien.rg@gmail.com>
7+
*/
8+
if (!function_exists('valid_json')) {
9+
10+
/**
11+
* Check JSON validity
12+
* @method valid_json
13+
* @author Romain GALLIEN <romaingallien.rg@gmail.com>
14+
* @param mixed $var Variable to check
15+
* @return bool
16+
*/
17+
function valid_json($var)
18+
{
19+
return (is_string($var)) && (is_array(json_decode($var,
20+
true))) && (json_last_error() == JSON_ERROR_NONE) ? true : false;
21+
}
22+
}
23+
24+
if (!function_exists('valid_jwt')) {
25+
26+
/**
27+
* Check JWT validity
28+
* @method valid_jwt
29+
* @param mixed $token Variable to check
30+
* @return Object/false
31+
*/
32+
function valid_jwt($token)
33+
{
34+
return AUTHORIZATION::validateToken($token);
35+
}
36+
}
37+
38+
/**
39+
* Ratchet Websocket Library: helper file
40+
* @author Romain GALLIEN <romaingallien.rg@gmail.com>
41+
*/
42+
if (!function_exists('output')) {
43+
44+
/**
45+
* Output valid or invalid logs
46+
* @method output
47+
* @author Romain GALLIEN <romaingallien.rg@gmail.com>
48+
* @param string $type Log type
49+
* @param string $var String
50+
* @return string
51+
*/
52+
function output($type = 'success', $output = null)
53+
{
54+
if ($type == 'success') {
55+
echo "\033[32m" . $output . "\033[0m" . PHP_EOL;
56+
} elseif ($type == 'error') {
57+
echo "\033[31m" . $output . "\033[0m" . PHP_EOL;
58+
} elseif ($type == 'fatal') {
59+
echo "\033[31m" . $output . "\033[0m" . PHP_EOL;
60+
exit(EXIT_ERROR);
61+
} else {
62+
echo $output . PHP_EOL;
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)