Closed shulard closed 9 years ago
Hello :-),
Really good idea and interesting project! Thanks to bet on Hoa!
So, let's talk about the actor. Slack is the server and Hoa\Websocket
is the client.
To connect to Slack, you read a wss://
URI from the Real Time Message API. Good. But Hoa\Socket
expects a udp://
or tcp://
scheme because wss://
is too high-level :smile:. For WebSocket, we use TCP. So all you have to do is to extract the hostname or IP address from the wss://
URI and prefix it by tcp://
(here, you will have tcp://ms177.slack-msgs.com
). The rest of the wss://
URI is the end-point. You need to pass this as an argument of the Hoa\Websocket\Client
class (here /websocket/GEjhTU7tHl3C90SwJuKaF71Orb8F9HZgdv-HIwf4HxIMygveAW9xc2X_bZb_LtDXLVAapy7nTJ7qh9Oz0zYnyrr7Gn2kD4635oihxNh3ZTM=
).
Oh, and since this is wss://
, you will have to enable encryption on the Hoa\Socket\Client
object.
To sum up:
$host = 'ms177.slack-msgs.com';
$socket = new Hoa\Socket\Client('tcp://' . $host);
$socket->enableEncryption(true);
$endpoint = '/websocket/GEjh…=';
$websocket = new Hoa\Websocket\Client($socket, $endpoint);
…
After that, the client is not responsible to broadcast the message, it is the responsability of the server. So you are safe on this one. However, what you are trying to do is to: Read new messages from Slack and send one message to Slack when your user sent one. So here, basically, you have 2 things to do at the same time: Waiting on the server and waiting on the client (user). The problem with PHP is that we cannot do 2 things at the same time because this is synchronous :wink:. You have several possibilities thought (group of socket connections, threads…), it will depend how your receive/read the user message. Can you help me?
Maybe we should add a socket factory based on a ws://
or wss://
URI… I never thought it could be an issue but now I realize it can! Thoughts? If yes, please, open a new issue :smile:!
Thanks for your feedback, I think I need to learn a little more about socket here ;)
I've updated my code to cut the URL and give the right part to the right object.
<?php
require_once __DIR__.'/vendor/autoload.php';
$rtmStart = "https://slack.com/api/rtm.start?token=".$argv[1];
$content = json_decode(file_get_contents($rtmStart));
$url = parse_url($content->url);
$socket = new Hoa\Socket\Client(
'tcp://'.$url['host'].(isset($url['port'])?':'.$url['port']:''),
5
);
$socket->enableEncryption(true);
$client = new Hoa\Websocket\Client( $socket, $url['path'] );
$client->connect();
The socket connection can't be established... I always received the error :
Fatal error: Uncaught Hoa\Socket\Client::_open(): (0) Client cannot join tcp://ms177.slack-msgs.com
Do you think it can be possible that Slack client is not compatible with the RFC "Rfc6455" ? I did not find any details in the documentation to help me resolve that issue... The connection works with JavaScript (I tried here: https://www.websocket.org/echo.html).
I think the factory can be a nice thing for that case. I think I'm going to make a PR for that, it'll help me go deeper in the implementation.
If port is absent, use 80
. What happen with this?
Good news for the PR! I already started one but I will be very glad to help you instead, it's better for you!
I've used 80
for the port I've got another error :
Fatal error: Uncaught Hoa\Socket\Client::_open(): (1) Client returns an error (number 60): Operation timed out while trying to join tcp://ms177.slack-msgs.com:80
I can't figure if Slack refuse the connection or if it's a network problem...
What about 8080 (because of HTTPS)?hoaproject/Websocket wrote:I've used 80 for the port I've got another error :
Fatal error: Uncaught Hoa\Socket\Client::_open(): (1) Client returns an error (number 60): Operation timed out while trying to join tcp://ms177.slack-msgs.com:80
I can't figure if Slack refuse the connection or if it's a network problem...
—Reply to this email directly or view it on GitHub.
Sent Using Firefox OS
Same error with 8080
...
I also tried with 443
, which is given here as the default port for TLS communication... I receive an empty response...
When I passed 443
, I received first an error about undefined host :
Fatal error: Uncaught Hoa\Websocket\Client::doHandshake(): (0) Host name is null. Please, use the Hoa\Websocket\Client::setHost() method.
If I use the setHost
method, I received another error because of the empty response :
Fatal error: Uncaught Hoa\Http\Response\Response::parse(): (0) HTTP status is not well-formed: .
Slack documentation is not really verbose on the edge case around websockets... I've asked details but no answer for the moment...
Yes 443... Ok so... Let me try today pr tonight something. /cc @CircleCode can help too.hoaproject/Websocket wrote:Same error with 8080...
I also tried with 443, which is given here as the default port for TLS communication... I receive an empty response...
—Reply to this email directly or view it on GitHub.
Sent Using Firefox OS
Sorry, I am late. I have some other stuff to do but you are definitively on my to do list. Give me few more days please :-).
Don't worry, take your time ;)
I opened an issue at slack too to ask them about the problem... They tell me that there is nothing wrong from their part...
They try Hoa to connect to another websocket : echo.websocket.org and they get the same errors :
Client cannot join
HTTP status is not well formed
(empty response)I hope this can help investigate...
Thank you. It's really strange. Gonna test really really soon (today or tomorrow :-)).
First:
$socket = new Hoa\Socket\Client('tcp://echo.websocket.org:80');
$socket->connect(); // works
Second:
$socket = new Socket\Client('tcp://echo.websocket.org:443');
$socket->connect(); // works
So it's good. However, echo.websocket.org
does something really strange. I cannot ping the server. So when I try to connect with Hoa\Websocket\Client
, I have a 404. Let's focus on one problem: Slack. I will try to take a look at it today (during lunch break probably).
Ok it works.
use Hoa\Socket;
use Hoa\Websocket;
use Hoa\Core;
// Crappy but we need to read the temp. URL ;-).
$token = $argv[1];
$url = json_decode(
file_get_contents(
'https://slack.com/api/rtm.start?token=' . $token
)
)->url;
var_dump($url);
// Parse the URL.
$parts = parse_url($url);
print_r($parts);
// Because this is wss://, it is secured.
// And because the first request is made over HTTP, here it is over HTTPS, so port 443 (and in TCP, as usual).
$socket = new Socket\Client('tcp://' . $parts['host'] . ':443');
// We pass the socket client and the endpoint (path) to the websocket client.
$websocket = new Websocket\Client(
$socket,
$parts['path']
);
// We must specify a host for the first HTTP request.
// Since we are running it in CLI, we don't have a host, so we provide one.
$websocket->setHost('hoa-project.net');
// Just print the response from Slack.
$websocket->on('message', function (Core\Event\Bucket $bucket) {
$data = $bucket->getData();
echo 'Received message: ', $data['message'], "\n";
return;
});
// Here we go.
$websocket->run();
This script works perfectly well. Just call it this way:
$ php Client.php <slack-api-token>
# enjoy
I always did it this way, but you're right, we must provide a socket factory because… I lied a little bit. I edited the Hoa\Websocket\Client::doHandshake
method to run $connection->enableEncryption(true, $connection::ENCRYPTION_TLS);
after connecting the client.
Ok. Let me open an issue and develop a PR. You will get it in few days normally.
Also, an example of responses I got from Slack:
Received message: {"type":"hello"}
Received message: {"reply_to":82,"type":"message","channel":"C026B05BQ","user":"U074D6GUR","text":"<https://fr.wikipedia.org/wiki/Gulo_gulo> pour tout ceux qui pensaient que ça n'était qu'un mythe ;-).","ts":"1437564314.000007"}
…
@shulard Go check #44 :-].
@Hywan thanks for your detailed answer ! It works with the Hoa\Websocket\Client::doHandshake
update ;)
I'll follow the #44 to view how it will be implemented, maybe I can help ?
@shulard If you want to make a PR, I would be glad :-). If you think you are able to do so, feel free! Just tell me because I will start in few hours.
Ok so let me try, I'm starting in the afternoon ! Maybe I'll request reviews but I'll be happy to help ;)
@shulard I guess you will start on Hoa\Socket
?
Yep ! I'll submit PR for review
Excellent :-]!
I am closing this issue since the issue has been answered.
Hi Hywan,
I have used the exact code you have used
use Hoa\Socket; use Hoa\Websocket; use Hoa\Core;
// Crappy but we need to read the temp. URL ;-). $token = $argv[1]; $url = json_decode( file_get_contents( 'https://slack.com/api/rtm.start?token=' . $token ) )->url; var_dump($url);
// Parse the URL. $parts = parse_url($url); print_r($parts);
// Because this is wss://, it is secured. // And because the first request is made over HTTP, here it is over HTTPS, so port 443 (and in TCP, as usual). $socket = new Socket\Client('tcp://' . $parts['host'] . ':443');
// We pass the socket client and the endpoint (path) to the websocket client. $websocket = new Websocket\Client( $socket, $parts['path'] );
// We must specify a host for the first HTTP request. // Since we are running it in CLI, we don't have a host, so we provide one. $websocket->setHost('hoa-project.net');
// Just print the response from Slack. $websocket->on('message', function (Core\Event\Bucket $bucket) { $data = $bucket->getData(); echo 'Received message: ', $data['message'], "\n";
return;
});
// Here we go. $websocket->run();
But i am receiving the error PHP Fatal error: Uncaught Hoa\Http\Response\Response::parse(): (0) HTTP status is not well-formed: .
Hello, since this issue is now closed, I encourage you to open a new one because it seems that the problem is not directly related to the one solved here.
Also, we have now introduced a new way to interact with Websocket URLs by handling ws
and wss
transport natively.
You can write directly something like :
$websocket = new Websocket\Client('wss://yourslackurlhere');
$websocket->setHost('hoa-project.net');
All the specific wss
security features are now handled directly by the wss
transport implementation (you can take a look at (official documentation)[https://hoa-project.net/En/Literature/Hack/Websocket.html] or #47 PR for more details).
If you still have the problem, maybe you can provide the Hoa\Http\Response\Response
body to help debugging...
Hello,
I'm currently trying to implement slack bot stuff using PHP. I found that there is an awesome Real Time Messaging API which using websockets (https://api.slack.com/rtm).
I tried to implement a method which can follow the given steps :
I found that Hoaproject as an awesome WebSocket client/server but I can't find a way to do that...
A websocket URL given by Slack API (they have a lifetime of 30sec):
wss://ms177.slack-msgs.com/websocket/GEjhTU7tHl3C90SwJuKaF71Orb8F9HZgdv-HIwf4HxIMygveAW9xc2X_bZb_LtDXLVAapy7nTJ7qh9Oz0zYnyrr7Gn2kD4635oihxNh3ZTM=.
Here the code I used to do that :
Thanks :)