Closed long-blade closed 6 months ago
Hi @long-blade
As of v2.2
there is a follow-redirect middleware that might help you.
https://github.com/sirn-se/websocket-php/blob/v2.2-main/docs/Middleware/FollowRedirect.md
Note that redirects are unspecified by WebSocket protocol, so there are no expected behavior specified anywhere.
Hey @sirn-se
for some reason is left-handing wen I start the script
can you see anything wrong?
@sirn-se does redirection take into consideration the possibility of response header cookies?
@long-blade
No, it only handles headers defined as part of websocket protocol. Any application specific logic has to be handled by implementing code.
The log partial you posted look fine to me (ignore the "Error" row). You can see it disconnecting the initial connection (as it gets a redirect) and then initializing a new one. Whatever goes wrong happen after your log post.
Only odd thing in your code snippet is that you immediately wait for server to transmit messages. Most cases I 've seen the client is expected to send an initial message to the server (identification, configuration, etc) before the server starts delivering things. But you need to check what the service provider expects.
Hey @sirn-se,
Yes you are right most of the time in order to start the streaming process you initialise the connection with a message, however in this case the server accepts the connection and then expects a special message (heartbeat) every 30 seconds, also the subscription is done by specific message which didn't implement yet.
So in other words, this server accepts connection with 101 response and then expects you to send messages
In postman when I click connect it connects. And then I send messages.
Also in response headers I see 3 set of cookie headers
Should I implement a custom redirect middleware that adds the response headers to the next requests?
So, The while loop in the pull method in the HttpHandler.php is forever looping with the buffer variable to be NULL.
So I don't understand why the buffer is returning null, under what circumstances this is happening?
In the old package, i was able to get the set-cookies headers but I don't see them now.
Just to clarify when I use postman I just click connect and it does connect without any payload, just specific headers which I have included in my script.
With the redirect solved, I'm not sure what issue you're experiencing.
What you normally do is something like;
$client
// add middlewares here
->onText(function (Client $client, Connection $connection, Message $message) {
// This is called when a message is received from server
});
// Initial message to server - configuration, authorization, similar
$client->text("Hello");
// Start listening to messages received by server, will call the onText method
$client->start();
With your code snippet, you will never send a message to server unless the server have sent a message first.
Cookies doesn't make much sense in a websocket service, but if you do need them then I would recommend extending the FollowRedirect
middleware or possibly use the Callback
middleware.
yes I used the code above with the redirect middleware, and it is stuck on a never-ending loop, in the pull method, because the buffer is null.
Even if i send a message first i get the same problem.
That's weird. It means that fgets return false
, which indicates there's nothing to read on the stream.
You could try to remove all the addHeader()
add setPersistent()
calls. The headers you've added are part of the websocket protocol, and are added by the client.
From what I can see in your masked screenshots, the redirects from server appear somewhat inconsistent.
Do you have a link to documentation of the API you're trying to connect to? So I can investigate a bit on my own.
I can't find any information on how to use websockets with that api.
yes, I can't either...
Facts:
Problems:
If you like me to give you some extra internal data (headers) we can do this in private (you will also need a VPN because is country-based only). I will be very happy to work with you to solve this issue
Also, do you think is wise to add this line of code? For example, in my case the URL has a path, shouldend we include this in the new $host_uri
? Should I open an MR for it or is wrong?
Client.php connect()
method
No, $host_uri
is for socket initialization and must only contain scheme:host:port.
Path and other parts of URI are to be used on HTTP handshake request.
let me know what do you think of the prev comment
So I tried connecting to the service. And I do get a proper response, although a 400 Bad Request, but it does read from the stream.
try {
$client = new \WebSocket\Client('ws://external-api.xtremepush.com/websock/');
$client
->addMiddleware(new \WebSocket\Middleware\CloseHandler())
->addMiddleware(new \WebSocket\Middleware\PingResponder())
->addMiddleware(new \WebSocket\Middleware\FollowRedirect())
->onText(function ($client, $connection, $message) {
echo "> Received '{$message->getContent()}' [opcode: {$message->getOpcode()}]\n";
})
->onConnect(function ($client, $connection, $message) {
echo "> Connect - $message\n";
})
->onDisconnect(function ($client, $connection) {
echo "> Disconnect\n";
})
;
$client->setLogger(new \WebSocket\Test\EchoLog());
$client->start();
} catch (\Throwable $e) {
echo "# ERROR: {$e->getMessage()} [{$e->getCode()}]\n";
}
So I wonder if it might be a SSL issue on the computer you're running on?
For some reason Postman connects over http
, but the redirect we get is https
.
If you run the code above, do you get "Invalid status code 400" as well?
No, as I said before you need to include custom headers in order for the request to be properly routed! Also is country-related so we will need a VPN from a specific country!
The custom headers are Origin
, Host
and Sec-WebSocket-Protocol
!
Yes, the above code gets me 400 as it is not a correctly formed request! The server expects specific headers and the request to be a specific country related!
I can give you that info but i will need you to do this in private for obvious reasons.
My point is that this code takes you further than before. You don't get stuck with an empty stream as before. The server response is received properly (error or not).
So if you start with this, and add the custom headers one by one, you should be able to narrow the issue down. If you add something and end up in the null read loop again, we will know what caused it.
Ok, I tried that but nothing to be changed, I am getting 404 until all headers are put on! The headers are not the problem, I think the problem is in the request final form.
When I use the correct host
header then the request is 301 and forever looping.
** The same headers are used in Postman @sirn-se
I did find an issue, where a redirect from ws
to https
ended up using tcp
instead of ssl
.
This may relate to the problem you're experiencing.
Fix available in v2.2.2
.
@sirn-se Perfect !!!! works very well! Thank you for all your help!
Solved, closing.
When I try to connect to a websocket using Postman everything is working fine but when I use this library I get "Invalid status code 301." Have in mind that this is an external websocket provider that is working with internal redirecting when you use customer headers
Is there any way to resolve this? or it need to be added as a feature?