I'm new with websocket things. I tried to make a simple chat application, and i've followed ratchet hello world tutorial. I ran it locally with
'ws://localhost:8080'
It's works perfectly fine. I can chat via javascript console like the tutorials said. Now, i try to put it on my webserver https://some.domain.co/websocket. I've tried to do the same thing like
'ws://some.domain.co:8080'
'ws://some.domain.co:8080/websocket'
'ws://some.domain.co/websocket:8080'
'wss://some.domain.co:8080'
'wss://some.domain.co:8080/websocket'
'wss://some.domain.co/websocket:8080'
But none of them work. By browser still give error
WebSocket connection to 'wss://some.domain.co/' failed: Error during
WebSocket handshake: Unexpected response code: 200
or
WebSocket connection to 'wss://some.domain.co:8080/' failed: Error in connection establishment: net::ERR_TIMED_OUT
I think i had something wrong with my url. Any advice? Thanks before
Edit
chatServer.php
require dirname(__DIR__) . '/vendor/autoload.php';
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
include("Chat.php");
require dirname(__DIR__) . '/vendor/autoload.php';
$server = IoServer::factory(
new HttpServer(
new WsServer(
new Chat()
)
), 8080
);
$server->run();
Chat.php
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
echo "Server is Running\n";
}
public function onOpen(ConnectionInterface $conn) {
// Store the new connection to send messages to later
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
$numRecv = count($this->clients) - 1;
echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
, $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');
foreach ($this->clients as $client) {
if ($from !== $client) {
// The sender is not the receiver, send to each client connected
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn) {
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} has disconnected\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
}
Related
So currently, I manage to communicate between php and java thanks to the socket. The problem is that once the java client is connected, I can't do anything anymore.
I would like that when a js event is triggered, information to the java client is transmitted.
How can I do that?
Thanks
My code php:
$host = "0.0.0.0";
$port = 6969;
set_time_limit(0);
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Create Error");
$result = socket_bind($socket, $host, $port) or die("Bind Error");
$result = socket_listen($socket, 3) or die("Listener Error");
$spawn = socket_accept($socket) or die("Accept Error");
$input = socket_read($spawn, 1024) or die("Read Error");
echo "Received: ".$input;
$output = "Received";
socket_write($spawn, $output, strlen($output)) or die("Write Error");
My java code:
Socket socket = new Socket("localhost", 6969);
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.println("Test Message");
writer.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(reader.readLine());
I will suggest you to use REST unless you have a very specific use case .
Else you need to close socket (on client * php ) and stream once you get the data.
https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html
read the explanation here, this will help you
I'm learning WebSocket using PHP library Ratchet. But I have a problem sending the message from client/browser. I have tried using chrome and firefox.
The message is not sent to the server until I disconnect the client by closing the tab or refresh the browser.
Update: My server use Centos 7 with firewalld enabled.
After I close the browser tab, the server output is like this:
Connection 73 sending message "tes" to 1 other connection
Connection 73 has disconnected
Here is the javascript code:
conn = new WebSocket('ws://websocket.develop.local:8080');
conn.onopen = function(e) {
console.log("Connection established!");
};
conn.onmessage = function(e) {
console.log('ada message');
console.log(e.data);
};
conn.onerror = function(e) {
console.log("WebSocket Error: " , e);
//Custom function for handling errors
//handleErrors(e);
};
function sendMessage(){
var message = document.getElementById("pesan").value;
conn.send(message);
console.log('Sending message: ' + message);
};
And here is the PHP code (I got this from Ratchet docs):
<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
// Store the new connection to send messages to later
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
$numRecv = count($this->clients) - 1;
echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
, $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');
foreach ($this->clients as $client) {
if ($from !== $client) {
// The sender is not the receiver, send to each client connected
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn) {
// The connection is closed, remove it, as we can no longer send it messages
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} has disconnected\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
}
I created a very simple PHP socket server:
<?php
class Server{
public $address = "127.0.0.1";
public $port = 2000;
public $socket;
public function __construct(){
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($this->socket, $this->address, $this->port);
socket_listen($this->socket, 5);
socket_set_nonblock($this->socket);
$this->log("Server has now started on ($this->address) : $this->port");
$this->doTicks();
}
public function shutdown(){
$this->log("Shutting down...");
socket_close($this->socket);
exit(0);
}
public function doTicks(){
while(true){
if(!$this->tick()){
$this->shutdown();
}
usleep(10000);
}
}
public function tick(){
//blah, read socket
return true;
}
public function log($message){
echo $message . "\n";
}
}
Now I am very confused on the javascript side implementation of this. My goal is too make a real-time notification delivery system.
My question is:
How can I connect to this socket javascript (to be able to read it)
Can clients write to sockets, or only servers?
This is my first time with sockets, and nothing I search is giving me a clear answer to these questions.
Im kinda new with the sockets stuff and Im trying to make a server on PHP to support websockets calls from my javascript currently my code looks like this
<?php
class Websocket
{
private $server;
private $sockets = [];
public function create($host)
{
$this->server = stream_socket_server('tcp://localhost:8080', $errno, $errmsg);
stream_set_blocking($this->server, 0);
}
public function run()
{
while(true)
{
$client = stream_socket_accept($this->server);
if($client)
{
$data = stream_socket_recvfrom($client, 2048);
if($data)
{
echo 'Client connected'.PHP_EOL;
echo $data;
$response = $this->handshake($data);
stream_socket_sendto($client, $response);
}
}
}
}
private function handshake($data)
{
$data = explode(PHP_EOL, $data);
foreach($data as $header)
{
$current_header = explode(':', $header);
if($current_header[0] == 'Sec-WebSocket-Key')
{
$accept = base64_encode(sha1(trim($current_header[1]).'258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));
$response = 'HTTP/1.1 101 Switching Protocols'.PHP_EOL.'Upgrade: websocket'.PHP_EOL.'Connection: Upgrade'.PHP_EOL.'Sec-WebSocket-Accept:'.$accept.PHP_EOL.PHP_EOL;
return $response;
}
}
}
}
And my javascript is just a simple
var socket = new WebSocket('ws://localhost:8080');
socket.onopen = function(event)
{
console.log('connected');
socket.send('hello');
}
Currently the message connected appears on my chrome console but after that when the hello message is supposed to be sent I get this error
"connection to: xxx was interrupted while the page was loading"
So my question is after I have successfully send the handshake to the client how do I process messages? I know my code is always sending the handshake to new connections but on my server I will only see the first message beeing echoed (the http request) and not the "hello" one
You need to handle the message -
socket.onmessage = function(e){
var server_message = e.data;
console.log(server_message);
}
I am writing a project that is in 2 parts.
So far I have a front end View.php (HTML5,CSS3,JQuery) and this will query the server.php
The server PHP opens a TCP socket to a server and listens in and can make commands by writing to the socket.
The normal procedure now goes like this
View.php -> Calls using rest API to server.php
Server.php -> Connects to TCP -> Reads from TCP -> Json_encodes & print -> close TCP socket connection.
What I want to achieve is a script Server.php that once started. It constantly listens in to a server, until it gets a shutdown command. I want to keep a fsocket connection open. Any thoughts?
The answer is using non blocking programming. In PHP we have specific function for non blocking I/O. For sockets you should use socket_set_nonblock function on a socket resource.
$port = 8081;
$address = '127.0.0.1';
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
exit();
}
if (socket_bind($sock, $address, $port) === false) {
echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
exit();
}
if (socket_listen($sock, 5) === false) {
echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}
socket_set_nonblock($sock);
echo "listening for new connection".PHP_EOL;
$conneted_clients = [];
do {
$clientsock = socket_accept($sock);
if($clientsock !== false){
socket_set_nonblock($clientsock);
$conneted_clients[] = $clientsock;
socket_getpeername($clientsock,$address);
echo "New Connection from: ".$address.PHP_EOL;
$msg = PHP_EOL."Welcome to the PHP Test Server. " . PHP_EOL.
"To quit, type 'quit'. To shut down the server type 'shutdown'." . PHP_EOL;
socket_write($clientsock, $msg, strlen($msg));
}
$status = check_clients($conneted_clients);
if(!$status) break;
usleep(500000);
} while (true);
function check_clients($clients)
{
foreach($clients as $key => $con)
{
if(get_resource_type($con) !== "Socket")
{
socket_getpeername($clientsock,$address);
echo $address." has diconnected.".PHP_EOL;
unset($clients[$key]);
continue;
}
if (false === $buff = socket_read($con, 2048)) {
continue;
}
$buff = trim($buff);
if ($buff == 'quit') {
socket_close($con);
unset($clients[$key]);
continue;
}
if (trim($buff) == 'shutdown') {
socket_close($con);
echo "shutdown initiated".PHP_EOL;
return FALSE;
}
if($buff != false || $buff != null)
{
$talkback = "PHP: You said '$buff'.".PHP_EOL;
socket_write($con, $talkback, strlen($talkback));
echo "$buff".PHP_EOL;
}
}
return TRUE;
}
echo "Closing Server";
socket_close($sock);