├── .gitignore
├── LICENSE
├── README.md
├── composer.json
├── public
├── .gitkeep
└── js
│ └── WebSocketClient.js
└── src
└── Freestream
└── WebSocket
├── WebSocketServiceProvider.php
├── command
└── WebSocketCommand.php
├── helper
├── .gitkeep
└── Evaluate.php
└── model
├── .gitkeep
├── WebSocketConnectionWrapper.php
├── WebSocketEventListener.php
├── WebSocketResponse.php
└── WebSocketServer.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | composer.phar
3 | composer.lock
4 | .DS_Store
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Anton Samuelsson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Laravel WebSocket server
2 |
3 | > WebSocket server based on Ratchet. Built to be completely event driven so it can used in several different project without having to manipulate the base code.
4 |
5 | ## Installation
6 |
7 | Add `require` and `repositories` information in the projects `composer.json` file:
8 |
9 | ```json
10 | "require": {
11 | ...
12 | "freestream/websocket": "1.*"
13 | ...
14 | },
15 | "repositories": [
16 | ...
17 | {
18 | "type": "vcs",
19 | "url": "git@github.com:freestream/laravel-websocket.git"
20 | }
21 | ...
22 | ],
23 | ```
24 |
25 | Now it's time to run `composer update` in your terminal.
26 |
27 | After the update is complete the service provider needs to be registered in `app/config/app.php` inside the `providers` array:
28 |
29 | ```php
30 | 'Freestream\WebSocket\WebSocketServiceProvider',
31 | ```
32 |
33 | ## Server side configuration
34 | Run the following command in the project root folder to startup the WebSocket server. By default the server will be run on port 8080 but by adding `--port=[number]` at the end of the command it is possible to change to any desired port.
35 |
36 | ```php
37 | php artisan websocket:start
38 | ```
39 |
40 | This will startup a daemon service that will estsblish the WebSocket server. To make sure that command is constantly running it is recommended to use [Supervisord](http://supervisord.org/) to run the process.
41 |
42 | ## Client side listener
43 |
44 | This service comes included with the necsesary JavaScript. To include these into the project assets folder run the following command.
45 |
46 | ```php
47 | php artisan asset:publish freestream/web-socket
48 | ```
49 |
50 | After that add this line into the template file.
51 |
52 | ```php
53 |
54 | ```
55 |
56 | To estalish a WebSocket client add the following code.
57 |
58 | ```JavaScript
59 |
66 | ```
67 |
68 | The availible configurations are:
69 |
70 | ```JavaScript
71 | debug boolean Enabled debug messages in browser console. Default is false.
72 | prefix string Event firing prefix. Default 'Laravel.Freestream.WebSocket'
73 | server string WebSocket server address. Default 'localhost'
74 | port integer WebSocket server port. Default 8080
75 | sessionId string Session ID for the opened WebSocket. Default random integer.
76 | reconnect boolean Should reconnect automatically if losing connection. Default true.
77 | ```
78 |
79 | Messages can be sent through the socket as soon as the connection is established. The first parameter is an event name that will be sent to the backend as a tracing event for easier filtering. The second parameter is the message and can contain a string or JSON.
80 |
81 | ```JavaScript
82 |
85 | ```
86 |
87 | Messages that are sent back from the server to the client contains JSON with two elements, `origData` and `data`. OrigData contains any data that was sent as a message and the server has responded to, and data contains the reponse data from the server.
88 |
89 | ```JSON
90 | {
91 | origData: {
92 | ...
93 | },
94 | data: {
95 | ...
96 | },
97 | }
98 | ```
99 |
100 | Add Event Listensers to respond/listen to anything that happens in the WebSocket.
101 |
102 | ```JavaScript
103 | document.addEventListener('Laravel.Freestream.WebSocket.Message.Received', function(event) {});
104 | ```
105 |
106 | Events that will be fired is:
107 |
108 | ```JavaScript
109 | [PREFIX].Error
110 | [PREFIX].Message.Received
111 | [PREFIX].Connection.Established
112 | [PREFIX].Connection.Closed
113 | ```
114 |
115 | ## Server side listener
116 |
117 | The server needs to be able to respond to any new connections or messages that are sent by the client. This is done by Laravel's event listener. This can be setup in different ways. The recommended way is to use `events.php`.
118 |
119 | If `events.php` is not already in the 'app/' folder create the file and after that open up 'app/start/global.php' and make sure the follwoing line is in the end of the file.
120 |
121 | ```php
122 | require app_path().'/events.php';
123 | ```
124 |
125 | All events that will be handled by the server should now be placed inside `events.php`:
126 |
127 | ```php
128 | =5.4.0",
13 | "cboden/Ratchet": "0.3.*"
14 | },
15 | "autoload": {
16 | "classmap": [
17 | "src/Freestream/WebSocket/helper",
18 | "src/Freestream/WebSocket/model",
19 | "src/Freestream/WebSocket/command"
20 | ],
21 | "psr-0": {
22 | "Freestream\\WebSocket\\": "src/"
23 | }
24 | },
25 | "minimum-stability": "stable"
26 | }
27 |
--------------------------------------------------------------------------------
/public/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freestream/laravel-websocket/b8755a993e56e4a27dbe9b578d26fab8f0d39134/public/.gitkeep
--------------------------------------------------------------------------------
/public/js/WebSocketClient.js:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Anton Samuelsson
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | /**
26 | * Custom Event constructor pollyfill
27 | */
28 | (function () {
29 | function CustomEvent (event, params) {
30 | params = params || { bubbles: false, cancelable: false, detail: undefined };
31 | var evt = document.createEvent( 'CustomEvent' );
32 | evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
33 | return evt;
34 | };
35 |
36 | CustomEvent.prototype = window.Event.prototype;
37 |
38 | window.CustomEvent = CustomEvent;
39 | })();
40 |
41 |
42 | /**
43 | * Establishes a WebSocket connection and broadcasts the events.
44 | *
45 | * @param {Object} options
46 | */
47 | var WebSocketClient = function(options) {
48 | this.options = {
49 | debug: options.debug || 0,
50 | prefix: options.prefix ||'Laravel.Freestream.WebSocket',
51 | server: options.server || 'localhost',
52 | port: options.port || '8080',
53 | sessionId: options.sessionId || Math.floor((Math.random()*1000)+1),
54 | reconnect: options.reconnect || true,
55 | };
56 |
57 | this.queue = [];
58 | this.isOpen = false;
59 | this.tryReconnect = options.reconnect;
60 |
61 | this.init();
62 | };
63 |
64 | /**
65 | * Initial configuration.
66 | */
67 | WebSocketClient.prototype.init = function() {
68 | this.connection = this.setConnection(new WebSocket('ws://' + this.options.server + ':' + this.options.port));
69 |
70 | this.connection.WebSocketClient = this;
71 | };
72 |
73 | /**
74 | * Modifies the established WebSocket connection.
75 | *
76 | * @param {WebSocket} connection
77 | */
78 | WebSocketClient.prototype.setConnection = function(connection) {
79 | var that = this;
80 | var prefix = this.options.prefix;
81 |
82 | /**
83 | * React to any connection error.
84 | *
85 | * @param {String} error
86 | */
87 | connection.onerror = function(error) {
88 | if (that.options.debug) {
89 | console.log('Caused error');
90 | console.log(error);
91 | }
92 |
93 | document.dispatchEvent(new CustomEvent(prefix + '.Error', {
94 | detail: {
95 | error: error,
96 | webSocketClient: that,
97 | connection: this,
98 | },
99 | bubbles: true,
100 | cancelable: false
101 | }));
102 | };
103 |
104 | /**
105 | * React on any message.
106 | *
107 | * @param {[Object]} message
108 | */
109 | connection.onmessage = function(message) {
110 | if (that.options.debug) {
111 | console.log('Received message');
112 | console.log(message);
113 | }
114 |
115 | document.dispatchEvent(new CustomEvent(prefix + '.Message.Received', {
116 | detail: {
117 | message: message,
118 | webSocketClient: that,
119 | connection: this,
120 | },
121 | bubbles: true,
122 | cancelable: false
123 | }));
124 | };
125 |
126 | /**
127 | * React when the connection is established.
128 | */
129 | connection.onopen = function() {
130 | if (that.options.debug) {
131 | console.log('Connection open!');
132 | }
133 |
134 | that.isOpen = true;
135 |
136 | document.dispatchEvent(new CustomEvent(prefix + '.Connection.Established', {
137 | detail: {
138 | webSocketClient: that,
139 | connection: this,
140 | },
141 | bubbles: true,
142 | cancelable: false
143 | }));
144 |
145 | that.sendQueue();
146 | };
147 |
148 | /**
149 | * React when the connection is closed.
150 | */
151 | connection.onclose = function() {
152 | if (that.options.debug) {
153 | console.log('Connection closed!');
154 | }
155 |
156 | that.isOpen = false;
157 | that.tryReconnect = true;
158 |
159 | document.dispatchEvent(new CustomEvent(prefix + '.Connection.Closed', {
160 | detail: {
161 | webSocketClient: that,
162 | connection: this,
163 | },
164 | bubbles: true,
165 | cancelable: false
166 | }));
167 |
168 | if (that.tryReconnect === true) {
169 | setTimeout(function() {
170 | that.init();
171 | }, 5000);
172 | }
173 | };
174 |
175 | return connection;
176 | };
177 |
178 | /**
179 | * Checks if the current object is from the server.
180 | *
181 | * @param {Object} object
182 | *
183 | * @return {Boolean}
184 | */
185 | WebSocketClient.prototype.isServerResponse = function(object) {
186 | return (object.server && object.server.event);
187 | };
188 |
189 | /**
190 | * After connection is established any stored queue data can be processed.
191 | */
192 | WebSocketClient.prototype.sendQueue = function() {
193 | if (!this.isOpen) {
194 | return false;
195 | }
196 |
197 | var that = this;
198 |
199 | this.queue.forEach(function(queue){
200 | that.message(queue.event, queue.data);
201 | });
202 | }
203 |
204 | /**
205 | * Sends a message through the WebSocket connection.
206 | *
207 | * @param {String} event
208 | * @param {Object} data
209 | */
210 | WebSocketClient.prototype.message = function(event, data) {
211 | if (!this.isOpen) {
212 | this.queue.push({event: event, data: data});
213 | } else {
214 | var json = {
215 | event: event,
216 | sessionID: this.options.sessionId,
217 | message: data || [],
218 | };
219 |
220 | console.log(json);
221 |
222 | this.connection.send(JSON.stringify(json));
223 | }
224 | };
225 |
--------------------------------------------------------------------------------
/src/Freestream/WebSocket/WebSocketServiceProvider.php:
--------------------------------------------------------------------------------
1 |
26 |
35 | */
36 | class WebSocketServiceProvider
37 | extends ServiceProvider {
38 |
39 | /**
40 | * Internal service prefix.
41 | *
42 | * @var string
43 | */
44 | const SERVICE_PREFIX = 'Laravel.Freestream.WebSocket';
45 |
46 | /**
47 | * Indicates if loading of the provider is deferred.
48 | *
49 | * @var boolean
50 | */
51 | protected $defer = false;
52 |
53 | /**
54 | * Bootstrap the application events.
55 | */
56 | public function boot()
57 | {
58 | $this->package('freestream/websocket');
59 | }
60 |
61 | /**
62 | * Register the service provider.
63 | */
64 | public function register()
65 | {
66 | $this->app['command.websocket:start'] = $this->app->share(function($app)
67 | {
68 | return new WebSocketCommand();
69 | });
70 |
71 | $this->commands('command.websocket:start');
72 | }
73 |
74 | /**
75 | * Get the services provided by the provider.
76 | *
77 | * @return array
78 | */
79 | public function provides()
80 | {
81 | return array('freestream_websocket','command.websocket:start');
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/src/Freestream/WebSocket/command/WebSocketCommand.php:
--------------------------------------------------------------------------------
1 |
26 |
38 | */
39 | class WebSocketCommand
40 | extends Command
41 | {
42 | /**
43 | * Default WebSocket port.
44 | *
45 | * @var integer
46 | */
47 | const DEFAULT_WEBSOCKET_PORT = 8080;
48 |
49 | /**
50 | * The console command name.
51 | *
52 | * @var string
53 | */
54 | protected $name = 'websocket:start';
55 |
56 | /**
57 | * The console command description.
58 | *
59 | * @var string
60 | */
61 | protected $description = 'Starts WebSocket server and runs event-driven applications with Laravel.';
62 |
63 | /**
64 | * Create a new command instance.
65 | */
66 | public function __construct()
67 | {
68 | parent::__construct();
69 | }
70 |
71 | /**
72 | * Execute the console command.
73 | */
74 | public function fire()
75 | {
76 | $port = $this->option('port');
77 |
78 | try {
79 | $server = new WebSocketServer();
80 | $server->start($port);
81 | $this->info("WebSocket server started on port: {$port}");
82 | $server->run();
83 | } catch (Exception $e) {
84 | Log::error('Something went wrong:', $e);
85 | $this->error('Unable to establish a WebSocket server. Review the log for more information.');
86 | }
87 | }
88 |
89 | /**
90 | * Get the console command options.
91 | *
92 | * @return array
93 | */
94 | protected function getOptions()
95 | {
96 | return array(
97 | array(
98 | 'port', null, InputOption::VALUE_OPTIONAL,
99 | "The port that the WebSocket server will run on (default: {self::DEFAULT_WEBSOCKET_PORT})",
100 | self::DEFAULT_WEBSOCKET_PORT
101 | ),
102 | );
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/src/Freestream/WebSocket/helper/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freestream/laravel-websocket/b8755a993e56e4a27dbe9b578d26fab8f0d39134/src/Freestream/WebSocket/helper/.gitkeep
--------------------------------------------------------------------------------
/src/Freestream/WebSocket/helper/Evaluate.php:
--------------------------------------------------------------------------------
1 |
26 |
33 | */
34 | class Evaluate
35 | {
36 | /**
37 | * Checks if the input string is a JSON.
38 | *
39 | * @param string $string
40 | *
41 | * @return boolean
42 | */
43 | public static function isJson($string)
44 | {
45 | json_decode($string);
46 | return (json_last_error() == JSON_ERROR_NONE);
47 | }
48 |
49 | /**
50 | * Returns a PHP standard object from a JSON string.
51 | *
52 | * @return stdClass
53 | */
54 | public static function jsonDecodeString($string)
55 | {
56 | return ((Evaluate::isJson($string))) ? (array) json_decode($string, true): [];
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Freestream/WebSocket/model/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freestream/laravel-websocket/b8755a993e56e4a27dbe9b578d26fab8f0d39134/src/Freestream/WebSocket/model/.gitkeep
--------------------------------------------------------------------------------
/src/Freestream/WebSocket/model/WebSocketConnectionWrapper.php:
--------------------------------------------------------------------------------
1 |
26 |
36 | */
37 | class WebSocketConnectionWrapper
38 | {
39 | /**
40 | * Connection interface for the established connection.
41 | *
42 | * @var Ratchet\ConnectionInterface
43 | */
44 | protected $_connection;
45 |
46 | /**
47 | * Response container.
48 | *
49 | * @var Freestream\WebSocket\WebSocketResponse
50 | */
51 | protected $_response;
52 |
53 | /**
54 | * Initial configuration.
55 | *
56 | * @param ConnectionInterface $connection
57 | * @param string $message
58 | */
59 | public function __construct(ConnectionInterface $connection, $message = '')
60 | {
61 | $this->_connection = $connection;
62 | $this->_response = $this->_getMessageObject($message);
63 | }
64 |
65 | /**
66 | * Extension of class function to make sure data is correctly formatted.
67 | *
68 | * @param string $string
69 | */
70 | public function send($string = '')
71 | {
72 | $this->_response->setMessage($string);
73 |
74 | $this->_connection->send(
75 | $this->_response->composeMessage()
76 | );
77 | }
78 |
79 | /**
80 | * Sets the response session ID.
81 | *
82 | * @param string $string
83 | *
84 | * @return Freestream\WebSocket\WebSocketConnectionWrapper
85 | */
86 | public function setSessionId($string = '')
87 | {
88 | $this->_response->setSessionId($string);
89 |
90 | return $this;
91 | }
92 |
93 | /**
94 | * Sets the response event name.
95 | *
96 | * @param string $string
97 | *
98 | * @return Freestream\WebSocket\WebSocketConnectionWrapper
99 | */
100 | public function setEvent($string = '')
101 | {
102 | $this->_response->setEvent($string);
103 |
104 | return $this;
105 | }
106 |
107 | /**
108 | * Apprehend every method call that is not present and send it directly to
109 | * the origin connection.
110 | *
111 | * @param string $method
112 | * @param array $args
113 | *
114 | * @return mixed
115 | */
116 | public function __call($method, $args)
117 | {
118 | return call_user_func_array(array($this->_connection, $method), $args);
119 | }
120 |
121 | /**
122 | * Validates and converts JSON object into a array and generates and returns
123 | * a response container.
124 | *
125 | * @param string $message
126 | *
127 | * @return Freestream\WebSocket\WebSocketResponse
128 | */
129 | protected function _getMessageObject($message = '')
130 | {
131 | $message = Evaluate::jsonDecodeString($message);
132 | return new WebSocketResponse($message);
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/Freestream/WebSocket/model/WebSocketEventListener.php:
--------------------------------------------------------------------------------
1 |
26 |
37 | */
38 | class WebSocketEventListener
39 | implements MessageComponentInterface
40 | {
41 | /**
42 | * Used event prefix.
43 | *
44 | * @var string
45 | */
46 | protected $_prefix;
47 |
48 | /**
49 | * Map from objects.
50 | *
51 | * @var \SplObjectStorage
52 | */
53 | protected $_clients;
54 |
55 | /**
56 | * Initial configuration.
57 | */
58 | public function __construct()
59 | {
60 | $this->_prefix = WebSocketServiceProvider::SERVICE_PREFIX;
61 | $this->_clients = new \SplObjectStorage;
62 | }
63 |
64 | /**
65 | * Fire a event when a new connection has been opened.
66 | *
67 | * @param ConnectionInterface $conn
68 | */
69 | public function onOpen(ConnectionInterface $conn)
70 | {
71 | $connection = new WebSocketConnectionWrapper($conn);
72 |
73 | $event = Event::fire(
74 | "{$this->_prefix}.Listener.Open",
75 | array(
76 | 'connection' => $connection,
77 | 'clients' => $this->_clients,
78 | 'listener' => $this,
79 | )
80 | );
81 |
82 | if ($event) {
83 | echo "Connection Established! \n";
84 | $this->_clients->attach($conn);
85 |
86 | Event::fire(
87 | "{$this->_prefix}.Listener.Open.After",
88 | array(
89 | 'connection' => $connection,
90 | 'clients' => $this->_clients,
91 | 'listener' => $this,
92 | )
93 | );
94 | }
95 | }
96 |
97 | /**
98 | * Fire a event when a message has been received through the tunnel.
99 | *
100 | * @param ConnectionInterface $from
101 | * @param string $msg
102 | */
103 | public function onMessage(ConnectionInterface $from, $msg)
104 | {
105 | $connection = new WebSocketConnectionWrapper($from, $msg);
106 |
107 | Event::fire(
108 | "{$this->_prefix}.Listener.Message",
109 | [
110 | 'from' => $connection,
111 | 'raw' => $msg,
112 | 'clients' => $this->_clients,
113 | 'listener' => $this,
114 | ]
115 | );
116 | }
117 |
118 | /**
119 | * Fire a event when a connection has been closed.
120 | *
121 | * @param ConnectionInterface $conn
122 | */
123 | public function onClose(ConnectionInterface $conn)
124 | {
125 | $connection = new WebSocketConnectionWrapper($conn);
126 |
127 | $event = Event::fire(
128 | "{$this->_prefix}.Listener.Close",
129 | [
130 | 'connection' => $connection,
131 | 'clients' => $this->_clients,
132 | 'listener' => $this,
133 | ]
134 | );
135 |
136 | if ($event) {
137 | $this->clients->detach($conn);
138 | echo "Connection {$conn->resourceId} has disconnected\n";
139 | }
140 | }
141 |
142 | /**
143 | * Fire a event when a error has occurred.
144 | *
145 | * @param ConnectionInterface $conn
146 | * @param \Exception $exception
147 | */
148 | public function onError(ConnectionInterface $conn, \Exception $exception)
149 | {
150 | $connection = new WebSocketConnectionWrapper($conn);
151 |
152 | Event::fire(
153 | "{$this->_prefix}.Listener.Error",
154 | [
155 | 'connection' => $connection,
156 | 'clients' => $this->_clients,
157 | 'listener' => $this,
158 | 'exception' => $exception,
159 | ]
160 | );
161 |
162 | echo "An error has occurred: {$exception->getMessage()}\n";
163 | $conn->close();
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/src/Freestream/WebSocket/model/WebSocketResponse.php:
--------------------------------------------------------------------------------
1 |
26 |
33 | */
34 | class WebSocketResponse
35 | {
36 | /**
37 | * Data values.
38 | *
39 | * @var array
40 | */
41 | protected $_data = [];
42 |
43 | /**
44 | * Original data values.
45 | *
46 | * @var array
47 | */
48 | protected $_origData = [];
49 |
50 | /**
51 | * Initial configuration.
52 | *
53 | * @param array $values
54 | */
55 | public function __construct(array $values)
56 | {
57 | $this->_setData($values);
58 | }
59 |
60 | /**
61 | * Magic data setter based on array of data.
62 | * Will only set data witch are compatible with a existing function.
63 | *
64 | * @param array $values
65 | *
66 | * @return Freestream\WebSocket\WebSocketResponse
67 | */
68 | protected function _setData(array $values)
69 | {
70 | foreach ((array) $values as $key => $value) {
71 | $method = 'set' . ucfirst($key);
72 | if (method_exists($this, $method)) {
73 | call_user_func_array([$this, $method], [$value]);
74 | }
75 | }
76 |
77 | $this->_origData = $this->_data;
78 | $this->_data = [];
79 |
80 | return $this;
81 | }
82 |
83 | /**
84 | * Sets value to message data.
85 | *
86 | * @param string $value
87 | *
88 | * @return Freestream\WebSocket\WebSocketResponse
89 | */
90 | public function setMessage($value)
91 | {
92 | if (!is_object($value)) {
93 | $this->_setValue($value, 'message');
94 | }
95 |
96 | return $this;
97 | }
98 |
99 | /**
100 | * Sets value to sessionId data.
101 | *
102 | * @param string $value
103 | *
104 | * @return Freestream\WebSocket\WebSocketResponse
105 | */
106 | public function setSessionId($value)
107 | {
108 | if (!is_object($value)) {
109 | $this->_setValue($value, 'sessionId');
110 | }
111 |
112 | return $this;
113 | }
114 |
115 | /**
116 | * Sets value to event data.
117 | *
118 | * @param string $value
119 | *
120 | * @return Freestream\WebSocket\WebSocketResponse
121 | */
122 | public function setEvent($value)
123 | {
124 | if (!is_object($value)) {
125 | $this->_setValue($value, 'event');
126 | }
127 |
128 | return $this;
129 | }
130 |
131 | /**
132 | * Sets value to data array.
133 | *
134 | * @param string $value
135 | *
136 | * @return Freestream\WebSocket\WebSocketResponse
137 | */
138 | protected function _setValue($value, $key)
139 | {
140 | $this->_data[$key] = $value;
141 |
142 | return $this;
143 | }
144 |
145 | /**
146 | * Returns message value.
147 | *
148 | * @return string
149 | */
150 | public function getMessage($orignData = false)
151 | {
152 | return $this->_getValue('message', $orignData);
153 | }
154 |
155 | /**
156 | * Returns sessionId value.
157 | *
158 | * @return string
159 | */
160 | public function getSessionId($orignData = false)
161 | {
162 | return $this->_getValue('sessionId', $orignData);
163 | }
164 |
165 | /**
166 | * Returns event value.
167 | *
168 | * @return string
169 | */
170 | public function getEvent($orignData = false)
171 | {
172 | return $this->_getValue('event', $orignData);
173 | }
174 |
175 | /**
176 | * Retrieves message from data or origin array.
177 | *
178 | * @param string $value
179 | */
180 | protected function _getValue($key, $fromOrigin = false)
181 | {
182 | $data = ($fromOrigin) ? $this->_origData : $this->_data;
183 |
184 | if (array_key_exists($key, $data)) {
185 | return $data[$key];
186 | }
187 |
188 | return '';
189 | }
190 |
191 | /**
192 | * Composes the JSON formated message.
193 | *
194 | * @return string
195 | */
196 | public function composeMessage()
197 | {
198 | return json_encode([
199 | 'origData' => [
200 | 'event' => $this->getEvent(true),
201 | 'sessionId' => $this->getSessionId(true),
202 | 'message' => $this->getMessage(true),
203 | ],
204 | 'data' => [
205 | 'event' => $this->getEvent(),
206 | 'sessionId' => $this->getSessionId(),
207 | 'message' => $this->getMessage(),
208 | ],
209 | ]);
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/src/Freestream/WebSocket/model/WebSocketServer.php:
--------------------------------------------------------------------------------
1 |
26 |
37 | */
38 | class WebSocketServer
39 | {
40 | /**
41 | * Ratchet WebSocket server.
42 | *
43 | * @var Ratchet\Server\IoServer
44 | */
45 | protected $server;
46 |
47 | /**
48 | * Prepares a new WebSocket server on a specified port.
49 | *
50 | * @param integer $port
51 | *
52 | * @return Freestream\WebSocket\WebSocketServer
53 | */
54 | public function start($port)
55 | {
56 | $this->server = IoServer::factory(new HttpServer(new WsServer(
57 | new WebSocketEventListener()
58 | )), $port);
59 |
60 | return $this;
61 | }
62 |
63 | /**
64 | * Starts the prepared server.
65 | *
66 | * @return Freestream\WebSocket\WebSocketServer
67 | */
68 | public function run()
69 | {
70 | $this->server->run();
71 |
72 | return $this;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------