This repository has been archived by the owner on Aug 25, 2022. It is now read-only.
Little patch for Socket 1.0.x - Working on my nRelay Project. #53
Closed
Closed
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
### Debug folder ### | ||
debug/ | ||
|
||
### Eclipse ### | ||
*.pydevproject | ||
.metadata | ||
.gradle | ||
bin/ | ||
tmp/ | ||
*.tmp | ||
*.bak | ||
*.swp | ||
*~.nib | ||
local.properties | ||
.settings/ | ||
.loadpath | ||
|
||
# External tool builders | ||
.externalToolBuilders/ | ||
|
||
# Locally stored "Eclipse launch configurations" | ||
*.launch | ||
|
||
# CDT-specific | ||
.cproject | ||
|
||
# PDT-specific | ||
.buildpath | ||
|
||
# sbteclipse plugin | ||
.target | ||
|
||
# TeXlipse plugin | ||
.texlipse | ||
|
||
|
||
### SublimeText ### | ||
# workspace files are user-specific | ||
*.sublime-workspace | ||
|
||
# project files should be checked into the repository, unless a significant | ||
# proportion of contributors will probably not be using SublimeText | ||
# *.sublime-project | ||
|
||
#sftp configuration file | ||
sftp-config.json | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,22 +2,31 @@ | |
|
||
namespace ElephantIO; | ||
|
||
require(__DIR__."/Payload.php"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This shouldn't be needed, as composer autoloads it. |
||
/** | ||
* ElephantIOClient is a rough implementation of socket.io protocol. | ||
* It should ease you dealing with a socket.io server. | ||
* | ||
* @author Ludovic Barreca <ludovic@balloonup.com> | ||
*/ | ||
class Client { | ||
const TYPE_DISCONNECT = 0; | ||
const TYPE_CONNECT = 1; | ||
const TYPE_HEARTBEAT = 2; | ||
const TYPE_MESSAGE = 3; | ||
const TYPE_JSON_MESSAGE = 4; | ||
const TYPE_EVENT = 5; | ||
const TYPE_ACK = 6; | ||
const TYPE_ERROR = 7; | ||
const TYPE_NOOP = 8; | ||
// Engine IO message types | ||
const EIO_OPEN = 0; | ||
const EIO_CLOSE = 1; | ||
const EIO_PING = 2; | ||
const EIO_PONG = 3; | ||
const EIO_MESSAGE = 4; | ||
const EIO_UPGRADE = 5; | ||
const EIO_NOOP = 6; | ||
|
||
// Socket IO message types | ||
const SIO_CONNECT = 0; | ||
const SIO_DISCONNECT = 1; | ||
const SIO_EVENT = 2; | ||
const SIO_ACK = 3; | ||
const SIO_ERROR = 4; | ||
const SIO_BINARY_EVENT = 5; | ||
const SIO_BINARY_ACK = 6; | ||
|
||
private $socketIOUrl; | ||
private $serverHost; | ||
|
@@ -34,7 +43,7 @@ class Client { | |
private $handshakeQuery = ''; | ||
|
||
public function __construct($socketIOUrl, $socketIOPath = 'socket.io', $protocol = 1, $read = true, $checkSslPeer = true, $debug = false) { | ||
$this->socketIOUrl = $socketIOUrl.'/'.$socketIOPath.'/'.(string)$protocol; | ||
$this->socketIOUrl = $socketIOUrl.'/'.$socketIOPath.'/?transport=polling&b64=1'; //.(string)$protocol; | ||
$this->read = $read; | ||
$this->debug = $debug; | ||
$this->parseUrl(); | ||
|
@@ -49,7 +58,6 @@ public function __construct($socketIOUrl, $socketIOPath = 'socket.io', $protocol | |
*/ | ||
public function setHandshakeQuery(array $query) { | ||
$this->handshakeQuery = '?' . http_build_query($query); | ||
|
||
return $this; | ||
} | ||
|
||
|
@@ -79,7 +87,7 @@ public function init($keepalive = false) { | |
public function keepAlive() { | ||
while (is_resource($this->fd)) { | ||
if ($this->session['heartbeat_timeout'] > 0 && $this->session['heartbeat_timeout']+$this->heartbeatStamp-5 < time()) { | ||
$this->send(self::TYPE_HEARTBEAT); | ||
$this->send(self::EIO_PING); | ||
$this->heartbeatStamp = time(); | ||
} | ||
|
||
|
@@ -90,7 +98,7 @@ public function keepAlive() { | |
|
||
$res = $this->read(); | ||
$sess = explode(':', $res); | ||
if ((int)$sess[0] === self::TYPE_EVENT) { | ||
if ((int)$sess[0] === self::EIO_MESSAGE) { | ||
unset($sess[0], $sess[1], $sess[2]); | ||
|
||
$response = json_decode(implode(':', $sess), true); | ||
|
@@ -175,31 +183,34 @@ public function on($event, $callback) { | |
* Send message to the websocket | ||
* | ||
* @access public | ||
* @param int $type | ||
* @param int $id | ||
* @param int $eioCode | ||
* @param int $sioCode | ||
* @param int $endpoint | ||
* @param string $message | ||
* @return ElephantIO\Client | ||
*/ | ||
public function send($type, $id = null, $endpoint = null, $message = null) { | ||
if (!is_int($type) || $type > 8) { | ||
public function send($eioCode, $sioCode = self::SIO_EVENT, $endpoint = null, $message = null) { | ||
if (!is_int($eioCode) || $eioCode > 8) { | ||
throw new \InvalidArgumentException('ElephantIOClient::send() type parameter must be an integer strictly inferior to 9.'); | ||
} | ||
|
||
$raw_message = $type.':'.$id.':'.$endpoint.':'.$message; | ||
$raw_message = $eioCode.$sioCode.$message; | ||
|
||
$payload = new Payload(); | ||
$payload->setOpcode(Payload::OPCODE_TEXT) | ||
->setMask(true) | ||
->setPayload($raw_message); | ||
->setMask(true) | ||
->setPayload($raw_message); | ||
$encoded = $payload->encodePayload(); | ||
|
||
fwrite($this->fd, $encoded); | ||
|
||
// wait 100ms before closing connexion | ||
usleep(100*1000); | ||
if ($this->read) { | ||
if ($this->read() != '1::') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think '1::' is socket.io v0.9 format. In my case, server responded "40" to client message "52". |
||
throw new \Exception('Socket.io did not send connect response. Aborting...'); | ||
} else { | ||
$this->stdout('info', 'Server report us as connected !'); | ||
} | ||
} | ||
|
||
$this->stdout('debug', 'Sent '.$raw_message); | ||
|
||
return $this; | ||
} | ||
|
||
|
@@ -214,11 +225,7 @@ public function send($type, $id = null, $endpoint = null, $message = null) { | |
* @todo work on callbacks | ||
*/ | ||
public function emit($event, $args, $endpoint = null, $callback = null) { | ||
return $this->send(self::TYPE_EVENT, null, $endpoint, json_encode(array( | ||
'name' => $event, | ||
'args' => $args, | ||
) | ||
)); | ||
return $this->send(self::EIO_MESSAGE, self::SIO_EVENT, $endpoint, '["'.$event.'",'.json_encode($args).']'); | ||
} | ||
|
||
/** | ||
|
@@ -229,7 +236,7 @@ public function emit($event, $args, $endpoint = null, $callback = null) { | |
public function close() | ||
{ | ||
if (is_resource($this->fd)) { | ||
$this->send(self::TYPE_DISCONNECT); | ||
$this->send(self::EIO_CLOSE); | ||
fclose($this->fd); | ||
|
||
return true; | ||
|
@@ -324,16 +331,17 @@ private function handshake() { | |
} | ||
|
||
$res = curl_exec($ch); | ||
|
||
if ($res === false || $res === '') { | ||
throw new \Exception(curl_error($ch)); | ||
} | ||
|
||
$sess = explode(':', $res); | ||
$this->session['sid'] = $sess[0]; | ||
$this->session['heartbeat_timeout'] = $sess[1]; | ||
$this->session['connection_timeout'] = $sess[2]; | ||
$this->session['supported_transports'] = array_flip(explode(',', $sess[3])); | ||
curl_close($ch); | ||
|
||
$sess = json_decode(substr($res, strpos($res,"{"), strrpos($res,"}"))); | ||
$this->session['sid'] = $sess->sid; | ||
$this->session['heartbeat_timeout'] = $sess->pingInterval; | ||
$this->session['connection_timeout'] = $sess->pingTimeout; | ||
$this->session['supported_transports'] = array_flip($sess->upgrades); | ||
|
||
if (!isset($this->session['supported_transports']['websocket'])) { | ||
throw new \Exception('This socket.io server do not support websocket protocol. Terminating connection...'); | ||
|
@@ -356,17 +364,14 @@ private function connect() { | |
} | ||
|
||
$key = $this->generateKey(); | ||
|
||
$out = "GET ".$this->serverPath."/websocket/".$this->session['sid']." HTTP/1.1\r\n"; | ||
$out = "GET ".$this->serverPath."?transport=websocket&sid=".$this->session['sid']." HTTP/1.1\r\n"; | ||
$out .= "Host: ".$this->serverHost."\r\n"; | ||
$out .= "Upgrade: WebSocket\r\n"; | ||
$out .= "Connection: Upgrade\r\n"; | ||
$out .= "Sec-WebSocket-Key: ".$key."\r\n"; | ||
$out .= "Sec-WebSocket-Version: 13\r\n"; | ||
$out .= "Origin: *\r\n\r\n"; | ||
|
||
fwrite($this->fd, $out); | ||
|
||
$res = fgets($this->fd); | ||
|
||
if ($res === false) { | ||
|
@@ -381,16 +386,7 @@ private function connect() { | |
$res = trim(fgets($this->fd)); | ||
if ($res === '') break; | ||
} | ||
|
||
if ($this->read) { | ||
if ($this->read() != '1::') { | ||
throw new \Exception('Socket.io did not send connect response. Aborting...'); | ||
} else { | ||
$this->stdout('info', 'Server report us as connected !'); | ||
} | ||
} | ||
|
||
// $this->send(self::TYPE_CONNECT); | ||
$this->send(self::EIO_UPGRADE); | ||
$this->heartbeatStamp = time(); | ||
} | ||
|
||
|
@@ -402,7 +398,6 @@ private function connect() { | |
*/ | ||
private function parseUrl() { | ||
$url = parse_url($this->socketIOUrl); | ||
|
||
$this->serverPath = $url['path']; | ||
$this->serverHost = $url['host']; | ||
$this->serverPort = isset($url['port']) ? $url['port'] : null; | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these have nothing to do in a
.gitignore
(project wise), it should be in your global.gitignore
. Otherwise, we should support everything... And I don't think that this is really possible. :D