bloatless / php-websocket Goto Github PK
View Code? Open in Web Editor NEWSimple WebSocket server implemented in PHP.
Home Page: https://bloatless.org
License: MIT License
Simple WebSocket server implemented in PHP.
Home Page: https://bloatless.org
License: MIT License
Is there any possibility to close a websocket server instance gracefully? \Bloatless\WebSocket\Server
has no method or command to end the while(true)
in \Bloatless\WebSocket\Server::run
.
The commit cc7d6d8 fixes a fatal error in which I ran as-well.
As it is the only change on master since v3.0.1
could we get a quick hotfix release?
Best Regards
Mario
Hey,
I am trying to replicate the example given in Readme.
But I am stuck up with this error.
Type: ErrorException
Message: socket_create(): Unable to create socket [10047]: An address incompatible with the requested protocol was used
I haven't changed anything in the library.
Using PHP 8.0.1
OS: Windows 10
Help is appreciated.
When several messages are sent at once (say 10 'echo' commands) the server responds only to some of them.
The problem is with Connection::hybi10decode()
function: once a frame is successfully decoded, all remaining data from Connection::$dataBuffer
is dropped. A quick fix is to add
$this->dataBuffer = substr($data, $dataLength)
at the end of the function and then process Connection::handle()
inside Connection::onData
in a loop until false
is returned (together with some extra checks on the size of $this->dataBuffer
while decoding).
This is my error:
Typed property Bloatless\WebSocket\Server::$timers must not be accessed before initialization
$server = new \Bloatless\WebSocket\Server(env('WS_IP'), (int) env('WS_PORT'));
// add a PSR-3 compatible logger (optional)
$server->setLogger(new \Bloatless\WebSocket\Logger\StdOutLogger());
// server settings:
$server->setMaxClients(50);
$server->setCheckOrigin(false);
$server->setAllowedOrigin('foo.lh');
$server->setMaxConnectionsPerIp(100);
$server->setIPCOwner('foo');
$server->setIPCGroup('www-data');
$server->setIPCMode(0755);
$webSocket = WebSocketController::getInstance();
// timers
$server->addTimer(250, function () use ($webSocket) {
$webSocket->socketJobsTimer();
});
$server->addTimer(250, function () use ($webSocket) {
$webSocket->socketBotJobsTimer();
});
$server->addTimer(500, function () use ($webSocket) {
$webSocket->gameEngineTimer();
});
$server->addTimer(250, function () use ($webSocket) {
$webSocket->calculateUsersBetTimer();
});
/*$server->addTimer(2500, function () use ($webSocket) {
$webSocket->updateBalanceTimer();
});*/
// Hint: Status application should not be removed as it displays usefull server informations:
$server->registerApplication('connect', $webSocket);
$server->run();
return 1;
Hi, are you intend to publish this over packagist ?
Where is the option to creat a websocket client? That is keep getting data from a certain ws:// url from php?
Hi.
When the server is behind a HaProxy, the HTTP headers come in "lowercase"
diff --git a/src/Connection.php b/src/Connection.php
index 98ea406..e9269c2 100644
--- a/src/Connection.php
+++ b/src/Connection.php
@@ -109,13 +109,13 @@ class Connection
foreach ($lines as $line) {
$line = chop($line);
if (preg_match('/\A(\S+): (.*)\z/', $line, $matches)) {
- $headers[$matches[1]] = $matches[2];
+ $headers[ strtolower( $matches[1] )] = $matches[2];
}
}
// check for supported websocket version:
- if (!isset($headers['Sec-WebSocket-Version']) || $headers['Sec-WebSocket-Version'] < 6) {
- $this->log('Unsupported websocket version.');
+ if (!isset($headers['sec-websocket-version']) || $headers['sec-websocket-version'] < 6) {
+ $this->log('Unsupported websocket version.'.print_r( $headers, true ) );
$this->sendHttpResponse(501);
stream_socket_shutdown($this->socket, STREAM_SHUT_RDWR);
$this->server->removeClientOnError($this);
@@ -124,8 +124,8 @@ class Connection
// check origin:
if ($this->server->getCheckOrigin() === true) {
- $origin = (isset($headers['Sec-WebSocket-Origin'])) ? $headers['Sec-WebSocket-Origin'] : '';
- $origin = (isset($headers['Origin'])) ? $headers['Origin'] : $origin;
+ $origin = (isset($headers['sec-websocket-origin'])) ? $headers['sec-websocket-origin'] : '';
+ $origin = (isset($headers['origin'])) ? $headers['origin'] : $origin;
if (empty($origin)) {
$this->log('No origin provided.');
$this->sendHttpResponse(401);
@@ -144,13 +144,13 @@ class Connection
}
// do handyshake: (hybi-10)
- $secKey = $headers['Sec-WebSocket-Key'];
+ $secKey = $headers['sec-websocket-key'];
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
$response = "HTTP/1.1 101 Switching Protocols\r\n";
$response .= "Upgrade: websocket\r\n";
$response .= "Connection: Upgrade\r\n";
$response .= "Sec-WebSocket-Accept: " . $secAccept . "\r\n";
- if (isset($headers['Sec-WebSocket-Protocol']) && !empty($headers['Sec-WebSocket-Protocol'])) {
+ if (isset($headers['sec-websocket-protocol']) && !empty($headers['sec-websocket-protocol'])) {
$response .= "Sec-WebSocket-Protocol: " . substr($path, 1) . "\r\n";
}
$response .= "\r\n";
In your client example you provided a example on how to send a message with $client->sendData
. I've checked the Client.php but could not find a way to listen for a new Message from the Server.php. Do you support bi-directional communication? You already have a function to send a message from server to the client.
I'm using php websocket Bloatless V2.0, because my framework (Zend) only supports php 7.2. I've been able to send messages through the web socket, but messages can be received by all connected clients (Broadcast). How can you do private messages between the server and only one client, so that messages sent by the server are not received by other connected clients?
It is out of connected beyond 14s.
the serverClients array store client connections by port, thus if another client ( with different IP ) is connecting with the same port as a previous one -> the first client is lost !
this patch solve the problem :
-------------------- src/Application/StatusApplication.php --------------------
index 6469453..7400d94 100644
@@ -97,7 +97,7 @@ class StatusApplication extends Application
*/
public function clientConnected(string $ip, int $port): void
{
$this->serverClients[$port] = $ip;
$this->serverClients[$ip.":".$port] = date("U");
$this->serverClientCount++;
$this->statusMsg('Client connected: ' . $ip . ':' . $port);
$data = [
@@ -118,10 +118,10 @@ class StatusApplication extends Application
*/
public function clientDisconnected(string $ip, int $port): void
{
if (!isset($this->serverClients[$port])) {
if (!isset($this->serverClients[$ip.":".$port])) {
return;
}
unset($this->serverClients[$port]);
unset($this->serverClients[$ip.":".$port]);
$this->serverClientCount--;
$this->statusMsg('Client disconnected: ' . $ip . ':' . $port);
$data = [
Server.php -> openIPCSocket() -> socket_bind -> creates a file in /tmp but www-data has no permissions to use it. This happened when i tried to send IPC data from an action of a website to the WebSocket server. This change did the trick:
FROM
if (socket_bind($this->icpSocket, $ipcSocketPath) === false) {
throw new \RuntimeException('Could not bind to ipc socket.');
}
TO
if (socket_bind($this->icpSocket, $ipcSocketPath) === false) {
throw new \RuntimeException('Could not bind to ipc socket.');
} else {
chown($ipcSocketPath, 'www-data');
}
how to send cert connect wss://
I want a demo?
In Server.php line 212
'maxRequetsPerMinute' => $this->maxRequestsPerMinute,
left side Requets without 's' befor 't'
I want to be able to make this server connect the client to the server via a webrtc stream how would i do this??
is this even possible?
i need to be able to encode the stream from the client directly to the server in some way FFmpeg??
When initializing the example...
PHP Warning: Private methods cannot be final as they are never overridden by other classes in .../vendor/bloatless/php-websocket/src/Application/Application.php on line 19
App do not accept new connections after running for a while.
These connections which are already established - exchange with messages happens successfully, but after disconnect - it is not possible to connect anymore to server
this part is still alive:
public function run(): void
{
while (true) {
echo count($this->allsockets)."|";
$changed_sockets = $this->allsockets;
....
I have this issue with almost default example script: https://github.com/bloatless/php-websocket/blob/master/examples/server.php
Initially thought it is Raspberry Pi memory issue, but the same was tested with MacBook - and issue is the same.
After restart - works again +/- 1h (test was done with 5 messages per sec approx.)
Hello,
Maybe this is a composer.json
problem,
Chat.php
is available in respective location, but my application could not recognize that.
On the other hand, Bloatless\WebSocket\Application\StatusApplication
is found and working fine.
Error
Class "Bloatless\WebSocket\Examples\Application\Chat" not found
at F:\Server\app\Console\Commands\webSocket.php:53
49▕ $server->setMaxConnectionsPerIp(20);
50▕
51▕ // add your applications
52▕ $server->registerApplication('status', StatusApplication::getInstance());
➜ 53▕ $server->registerApplication('chat', Chat::getInstance());
54▕
55▕ // start the server
56▕ $server->run();
Tnanks in advance.
Hello
How can i use version 1.0 for php 5.
Thanks
I'm using php websocket Bloatless V2.0, because my framework (Zend) only supports php 7.2.
i want to implement private chat like the example in StatusAplication to DemoAplication.
"The Status-Application includes an example for this: https://github.com/bloatless/php-websocket/blob/release/2.1.0/src/Application/StatusApplication.php#L49
Just use the $client->send() Method to send data to a specific client."
Private Chat in StatusAplication
` public function onConnect(Connection $client): void
{
$id = $client->getClientId();
$this->clients[$id] = $client;
$this->sendServerinfo($client);
}
private function sendServerinfo(Connection $client): void
{
if (count($this->clients) < 1) {
return;
}
$currentServerInfo = $this->serverInfo;
$currentServerInfo['clientCount'] = count($this->serverClients);
$currentServerInfo['clients'] = $this->serverClients;
$encodedData = $this->encodeData('serverInfo', $currentServerInfo);
$client->send($encodedData);
}
`
Send Chat in DemoAplikation
`
public function onConnect(Connection $client): void
{
$id = $client->getClientId();
$this->clients[$id] = $client;
}
private function actionEcho(string $text): void
{
$encodedData = $this->encodeData('echo', $text);
foreach ($this->clients as $sendto) {
$sendto->send($encodedData);
}
}
`
if my actionEcho input 2 parameters to be (string $tex, , Connection $client) like the example in sendServerinfo, the socket will error.
How can I add $client->send() in DemoAplication ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.