I am creating an API that uses websockets for real-time communication. I use Laravel 8 with Pusher as the broadcast driver for the backend, Soketi as the web socket server on windows (development environment) and I use postman to test the requests.
The problem is, my connection to the Soketi web socket server Always crashes after about 2 minutes of connectivity with a 4201 Error: Connection was closed due to an unknown error
. I would like the connection to last a bit longer or ideally indefinitely, at least I think that's how it should work.
Console Connection message:
Console Disconnection message:
Both Postman and the console show the error, Note the time from connection to disconnection.
I did a work around to force postman to reconnect if an unexpected error caused it to close but that doesn't reconnect to the channels that were subscribed to before disconnection.
In config\broadcasting.php
I have:
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'host' => env('PUSHER_HOST'),
'port' => env('PUSHER_PORT'),
'scheme' => env('PUSHER_SCHEME', 'http'),
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => env('PUSHER_SCHEME') === 'https',
],
],
My Soketi config:
{
"debug": true,
"port": 6001,
"appManager.array.apps": [
{
"id": "SLMT",
"key": "1229272",
"secret": "sLq2dAswE&9q",
"webhooks": [
{
"url": "",
"event_types": ["channel_occupied"]
}
]
}
]
}
The key
and secret
values are only used for development that's why don't hide them. Any help is much appreciated beacuse this situation makes testing websocket events very tedious if the connection keeps breaking.
EDIT
I forgot to mention a crucial piece of information. My project is an API which uses Sanctum to authenticate users. It does not serve any Html. In case someone wants to reproduce.
Alright so I think I figured it out. I believe the socket connection closes due to an activity timeout.
I have another app which uses web sockets too but instead of an API it serves Html. Anyway I fired up the Soketi server but with different credentials specific to the Html project and I compared the console output with the API project, where the problem occurs. I noticed that on the Html app, which uses Laravel echo, the client constantly sends a pusher:ping
event to the server every 30 seconds, and the server replies with a pusher:pong
event.
The interesting part is that the pusher:pong
event increments the _iddleStart:
value under the Timeout
property of the webSocket connection output, which essentially keeps the connection from closing due to inactivity. I think the reason for the 2 minutes delay comes from the _iddleTimeout:120000
property. (Please refer to the images on the question for clarity)
After this discovery I went back to my API application and made a pusher:ping
event message on my Postman, which I then kept sending to the server Manually every minute, and the connection held intact!
The ping message that I mention looks like this on Postman:
{
"event":"pusher:ping",
"data":{}
}
I have to admit I had my suspicions but I didn't want to conclude anything without checking. The error shown by the server is not detailed or descriptive, it literally says Connection was closed due to an unknown error
and there is no lookup table for the error code afaik.
Well, this is a Postman problem in my opinion. A client is responsible for keeping the connection with the server open in a WebSockets implementation right? Postman should at least give an option to auto-send some messages for this sort of thing but I will cut them some slack because apparently their WebSocket Request is still in beta development.
I also feel there should be more detailed error info provided by the Soketi server output, but they too I will cut some slack because its a fairly new server app, which is actually great and very stable, if I might add.