We currently have a Laravel CMS server that sends a request to another Laravel websocket server which then broadcasts to multiple IoT devices listening on their individual channels for requests. Everything works perfectly.
So it looks like this: CMS server -> Socket server -> devices
I am trying to initiate these websocket requests from a third server which is not running Laravel, it's just running core PHP and JavaScript. I looked in my browser's Network tab to spy on the websocket connection from a legitimate request, copied it exactly, the connection and subscription succeed but when I send the requests over the socket from my test script, nothing happens. It's literally the exact same socket request over the same channel on the same connection, just with a different socket ID. How could this fail?
I thought maybe it was only accepting requests from that specific server so I copied my test script to that server and still no response. I don't know much about web sockets, could someone please help me understand how I can spoof these messages without using Laravel?
If you're wondering what I'm actually up to, we're decommissioning this CMS server for our new CMS we built in core PHP so we no longer have Laravel as an option but I don't want to rewrite the socket server which uses Laravel, that can stay. I just need to interface with it any way possible. I have full SSH and DNS access to anything I need to configure.
Here is my test script, I've tried about 50 of them I found on Google, none of them give me a response from my specific socket server, besides the connection successful and subscription successful responses.
<script>
let socket = new WebSocket('wss://subdomain.domain.ca:6001/app/apikeyyyyy?protocol=7&client=js&version=4.4.0&flash=false');
var message = {
channel:"aaaaaa.bbbbbbbb",
event:"1000",
data:"{\"channelName\":\"aaaaaa.bbbbbbbb\",\"message\":{\"msgId\":\"\",\"cmd\":\"help\",\"timestamp\":1663616905529,\"request_id\":\"\",\"device_id\":\"\"},event:\"1000\",timestamp:1663616905529,request_id:\"\",device_id:\"\"}"
};
socket.onopen = function(e) {
var data_json = {
event:'pusher:subscribe',
data:{
channel:'aaaaaa.bbbbbbbb',
}
};
socket.send(JSON.stringify(data_json));
socket.send(JSON.stringify(message));
};
socket.onmessage = function(event) {
console.log("Response: " + event.data);
};
socket.onclose = function(event) {
if (event.wasClean) {
alert(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
} else {
// e.g. server process killed or network down
// event.code is usually 1006 in this case
alert('[close] Connection died');
}
};
socket.onerror = function(error) {
alert(`[error] ${error.message}`)
};
</script>
I obviously removed the channel name, domain and application key for security but the rest is accurate. And here's what I see in my browser console:
Response: {"event":"pusher:connection_established","data":"{\"socket_id\":\"166323189.236668505\",\"activity_timeout\":30}"}
Response: {"event":"pusher_internal:subscription_succeeded","channel":"aaaaaa.bbbbbbbb"}
When I send a request from the (working) CMS server, I get a OK response from the socket server and the related device will reboot or whatever I asked it to do. When I send the exact same response from my test script, I see the request get logged in the websockets.log file on the socket server but no response is logged like it is with the requests from the CMS server. And no response prints in the browser console even though I do see the responses print in the browser console for my test script when I send them from the CMS so I know the subscription is working correctly. Also the devices do not reboot.