I have created a PHP websocket server script as following.
$socket = socket_create(AF_INET, SOCK_STREAM, 0);
$result = socket_bind($socket, '127.0.0.1', 5001);
while (true) {
$result = socket_listen($socket);
$client = socket_accept($socket);
$input = socket_read($client, 1024);
$output = 'Input Received: '.$input;
socket_write($client, $output, strlen($output));
socket_close($client);
}
socket_close($socket);
I've executed file containing above code in terminal using following command
$ php server.php
Now I want to get the response on my front-end using JavaScript. I've used following JS snippet but not working.
var ws = new WebSocket("ws://localhost:5001/echo");
ws.onopen = function() {
ws.send("Message to send");
alert("Message is sent...");
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
alert("Message is received...");
};
ws.onclose = function() {
alert("Connection is closed...");
};
Receiving following error:
WebSocket connection to 'ws://localhost:5001/echo' failed: Error during WebSocket handshake: net::ERR_INVALID_HTTP_RESPONSE
Writing a PHP websocket server requires to perform a certain handshake with the client connecting to you via ws:// . In addition you need to decode and encode messages going in and out. The real fun starts when the clients contact you via wss://, then you have to take care of certificate and key within your PHP server and use stream-io instead of socket-io and so on and on. You can have a look at my implementation of all this and use it as another starting point .
https://github.com/napengam/phpWebSocketServer
Related
I'm trying to receive json data from an ESP32 via TCP to a website hosted thru WAMP (localhost -> ESP32 IP address on local network is 10.11.125:23). Below is my javascript function. My browser (Firefox Developer) generates a "SecurityError: The operation is insecure" when executing the line var connection = new webSocket('ws://10.11.13.125:23'). What am I missing??
function openWebsocket() {
console.log("open Websocket.....");
var connection = new WebSocket('ws://10.11.13.125:23');
connection.onerror = function(error) {
$("#Connection").html("Connection Error");
console.log("Websocket Error: " + error);
}
connection.onopen = function(evt) {
$("#Connection").html("Connected");
}
connection.binaryType = 'arraybuffer';
connection.onmessage = function(evt) {
console.log("Server: " + evt.data.byteLength);
}
console.log("ReadyState: "+connection.readyState);
}
I found the problem. The Chromium browser yields a more descriptive error message. Port 23 is not available. Switched over to
var connection = new WebSocket('ws://10.11.13.125:80');
and voila, everything works as expected.
Sorry for posting about an issue that in the end I found the solution for myself.
I have an issue when send data from client to server - Python websocket.
Here my client code:
<script type="text/javascript">
var s = new WebSocket('ws://127.0.0.1:8999');
s.onopen = function (e) {
console.log("Socket opened.");
};
s.onclose = function (e) {
console.log("Socket closed.");
};
s.onmessage = function(t){alert(t)};
function onSubmit() {
s.send("Hello from client");
}
</script>
And server - Python code:
import socket
import re
from base64 import b64encode
from hashlib import sha1
websocket_answer = (
'HTTP/1.1 101 Switching Protocols',
'Upgrade: websocket',
'Connection: Upgrade',
'Sec-WebSocket-Accept: {key} \r\n\r\n',
)
GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 8999))
s.listen(10)
client, address = s.accept()
text = client.recv(1024)
print "Get data text from client and send back this data: "
print text
key = (re.search('Sec-WebSocket-Key:\s+(.*?)[\n\r\r\n]+', text)
.groups()[0]
.strip())
response_key = b64encode(sha1(key + GUID).digest())
response = '\r\n'.join(websocket_answer).format(key=response_key)
client.send(response)
clientData = client.recv(4096)
client.send("Hello from server")
When run Python Socket Server, I can connect from client, it mean "console.log("Socket opened.");" is working.
But when I send data from client to server by running function onSubmit() data, I get the error "Invalid frame header" in console log of Chrome develop tool.
And when I debug data from client sent to server (clientData variable in Python file), I got an crack string: "��Ϭ����Ջ��ߕ������܉�".
Anybody can help me to resolve this problem?
So I've been trying to get this whole connection between PHP socket server and Javascript websockets working, but I cant get them to connect. I have looked everywhere to figure out what I'm doing wrong. My guess is it's the protocol but I have no idea. Everything helps, comment if you have questions.
Client-Side Example
<script>
var connection = new WebSocket('ws://127.0.0.1:4446');
connection.onopen = function () {
connection.send('Ping'); // Send the message 'Ping' to the server
};
// Log errors
connection.onerror = function (error){
console.log('WebSocket Error ' + error);
};
// Log messages from the server
connection.onmessage = function (e) {
console.log('Server: ' + e.data);
};
</script>
Server-Side Example -PHP
<?php
$conn = stream_socket_server('tcp://127.0.0.1:4446');
while ($socket = stream_socket_accept($conn)) {
$pkt = stream_socket_recvfrom($socket, 1500, 0, $peer);
if (false === empty($pkt)) {
stream_socket_sendto($socket, $pkt, 0, $peer);
}
fclose($socket);
usleep(10000); //100ms delay
}
stream_socket_shutdown($conn, \STREAM_SHUT_RDWR);
?>
Console Log Error
VM4666:35 WebSocket connection to 'ws://127.0.0.1:4446/' failed: Error during WebSocket handshake: net::ERR_INVALID_HTTP_RESPONSE
I understand that there are many questions on here similar but I cant seem to find a solution, I appreciate any help!
I'm moving to upgrade the web sockets on my page to use a secure connection. However, when I call new WebSocket() with a wss:// instead of ws://, there are no headers being sent at all.
This is what I have so far:
php:
$lcNull = NULL; //null var
$lcHost = '0.0.0.0'; //host
$lnPort = '8080'; //port
$lcCertPath = '/path/to/cert';
//Create TCP/IP stream socket
$lhContext = stream_context_create();
stream_context_set_option($lhContext, 'ssl', 'local_cert', $lcCertPath);
stream_context_set_option($lhContext, 'ssl', 'passphrase', 'something');
stream_context_set_option($lhContext, 'ssl', 'allow_self_signed', true);
stream_context_set_option($lhContext, 'ssl', 'verify_peer', false);
$lsSocket = stream_socket_server(
"ssl://0.0.0.0:$lnPort",
$errno,
$errstr,
STREAM_SERVER_BIND | STREAM_SERVER_LISTEN,
$lhContext
);
if ($errno > 0) { //An error has occured
echo("Main socket error ($errno): $errstr");
die();
} else {
echo("Main socket started, listening on $lcHost:$lnPort");
}
//create & add listening socket to the list
$laClients = array($lsSocket);
$laSocketUser = [];
//start endless loop, so that our script doesn't stop
while (true) {
//manage multiple connections
$laChanged = $laClients;
//returns the socket resources in $laChanged array
stream_select($laChanged, $lcNull, $lcNull, 0, 10);
# User Connected!
if (in_array($lsSocket, $laChanged)) {
$lsSocketNew = stream_socket_accept($lsSocket); //accept new socket
print "accepted " . stream_socket_get_name($lsSocketNew, true) . "\n";
$laClients[] = $lsSocketNew; //add socket to client array
echo "\nReading header:>";
stream_set_blocking($lsSocketNew, true);
$lcHeader = fread($lsSocketNew, 5000); //read data sent by the socket
echo $lcHeader . "<\n\n";
...
And the output depends how the web socket is created in the Javascript:
this sends headers:
var wsUri = "ws://"+window.location.host;
websocket = new WebSocket(wsUri);
this sends nothing :P (i.e. the php above echos out Reading header:><, meaning it did not receive any headers.)
var wsUri = "wss://"+window.location.host+":8080";
websocket = new WebSocket(wsUri);
So my question is: Why does the wss:// example not send any headers, and how can I get it to send the headers correctly?
Im trying to get a connection between a JavaScript WebSocket and a TCP Server/Client applicat written in VisualBasic .Net . My problem is that the handshake fails. I do get a handshake request from the local website, but it does not accept my response.
The code of the JavaScript file:
<script type="text/javascript">
var ws;
function connect() {
if("WebSocket" in window) {
debugger;
ws = new WebSocket("ws://192.168.193.178:1925");
ws.onopen = function() {
alert("Connection established");
};
ws.onmessage = function(evt) {
var received_msg = evt.data;
alert("Message is received: " + received_msg);
};
ws.onerror = function(evt) {
alert("Error");
var received_msg = evt.data;
alert("Error: " + received_msg);
};
ws.onclose = function() {
// websocket is closed.
alert("Connection closed");
};
//ws.send("Test");
//ws.close();
} else {
alert("WebSocket NOT supported by your Browser!");
}
}
function disconnect() {
ws.close();
}
function send(message) {
ws.send(message);
alert("Sent: " + message);
}
</script>
The VB.Net code output:
Received:
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 192.168.193.178:1925
Origin: http://127.0.0.1:8020
Sec-WebSocket-Key: eGzO0afUD5jCeUdzdoxwjw==
Sec-WebSocket-Version: 13
Sent:
HTTP/1.1 101 Web Socket Protocol Handshake\r\n
Upgrade: WebSocket\r\n
Connection: Upgrade\r\n
Sec-WebSocket-Origin: null\r\n
Sec-WebSocket-Accept: NzU3M2IwYzk0ZWFmYjg4MzMyZWI1ODhhZWI4NWUyZDE1YWU2YzhlNA==\r\n
\r\n
I just cant get the WebSocket to accept the handshake, I hope anyone can help me out.
Maybe the hash-generation contains errors?
Edit:
I now get the correct Sec-WebSocket-Accept String (dXOwyU6vuIMy61iK64Xi0VrmyOQ=), anyway the WebSocket seems not to handle the handshake response. I tried debugging it with the Chrome Developer Tools, but I don't get usefull information from it. Any tips?
One thing sticks out immediately. The Sec-WebSocket-Accept value in the server response is much longer than what a correct value looks like. In fact, the correct value for that Key should be "dXOwyU6vuIMy61iK64Xi0VrmyOQ=". My guess is you're doing the base-64 encoding on the string representation of the SHA1 result. The encoding should be done on the byte representation of SHA1 result.