Laravel Websockets:如何获取已建立的WebSocket连接?
Hey there! I’ve worked extensively with BeyondCode’s Laravel Websockets, so I can help you solve this problem of sending messages via API to existing WebSocket connections (either by fetching all connections or targeting a specific socket ID).
Option 1: Use Laravel’s Built-in Broadcast System (Simplest Approach)
The easiest way to send messages to a specific socket ID is leveraging Laravel’s broadcast functionality, which integrates seamlessly with BeyondCode’s package. You don’t need to manually handle connection objects here—Laravel takes care of the heavy lifting.
Create a Broadcast Event:
namespace App\Events; use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; class ApiTriggeredMessage implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; public $payload; public function __construct(array $payload) { $this->payload = $payload; } // Define the channel (can be public, private, or presence) public function broadcastOn() { return new Channel('api-messages'); } // Optional: Customize the event name your frontend listens for public function broadcastAs() { return 'api.message.received'; } }Send the Message from Your API Controller:
Use thetoSocket()method to target a specific connection by its socket ID:use App\Events\ApiTriggeredMessage; use Illuminate\Http\Request; class ApiMessageController extends Controller { public function send(Request $request) { $validated = $request->validate([ 'socket_id' => 'required|string', 'message' => 'required|string' ]); // Send directly to the specified socket ID broadcast(new ApiTriggeredMessage([ 'message' => $validated['message'], 'timestamp' => now()->toDateTimeString() ]))->toSocket($validated['socket_id']); return response()->json(['status' => 'Message sent successfully']); } }
Option 2: Manually Fetch Connections via the WebSocket Server Instance
If you need direct access to all active connections (e.g., to broadcast to everyone or filter connections), you can use the WebSocketServer singleton provided by the package.
Important Note: This only works if your API and WebSocket server are running in the same process (uncommon in production). For production setups where they’re separate processes, use Option 1 or a queue-based approach (see below).
Fetch All Active Connections:
use BeyondCode\LaravelWebSockets\WebSockets\WebSocketServer; $server = app(WebSocketServer::class); $allConnections = $server->getConnections(); foreach ($allConnections as $connection) { // Access the socket ID: $connection->socketId // Send a raw JSON message $connection->send(json_encode([ 'event' => 'global.notification', 'data' => ['message' => 'Hello from the API!'] ])); }Fetch a Specific Connection by Socket ID:
$socketId = 'your-target-socket-id'; $server = app(WebSocketServer::class); $connection = $server->getConnectionById($socketId); if ($connection) { $connection->send(json_encode([ 'event' => 'direct.message', 'data' => ['message' => 'This is a direct message!'] ])); } else { // Handle case where connection no longer exists return response()->json(['error' => 'Connection not found'], 404); }
Option 3: Queue-Based Approach for Production (Separate API/WebSocket Processes)
In most production setups, your API and WebSocket server run as separate processes. This means the API can’t directly access the WebSocket server’s connection state. Instead, use a queue to relay messages to the WebSocket server.
Create a Queue Job:
namespace App\Jobs; use BeyondCode\LaravelWebSockets\WebSockets\WebSocketServer; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class SendWebSocketMessage implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; protected $socketId; protected $message; public function __construct(string $socketId, array $message) { $this->socketId = $socketId; $this->message = $message; } public function handle() { $server = app(WebSocketServer::class); $connection = $server->getConnectionById($this->socketId); if ($connection) { $connection->send(json_encode([ 'event' => 'api.message', 'data' => $this->message ])); } } }Dispatch the Job from Your API Controller:
use App\Jobs\SendWebSocketMessage; use Illuminate\Http\Request; class ApiMessageController extends Controller { public function send(Request $request) { $validated = $request->validate([ 'socket_id' => 'required|string', 'message' => 'required|string' ]); dispatch(new SendWebSocketMessage( $validated['socket_id'], ['content' => $validated['message']] )); return response()->json(['status' => 'Message queued for delivery']); } }Ensure the Queue Worker Runs in the WebSocket Environment:
Make sure your queue worker is running in the same environment as the WebSocket server so it can access theWebSocketServerinstance. You can start it with:php artisan queue:work
Why Storing Connection Objects Doesn’t Work
As you discovered, saving the connection object to config or sessions is impossible because:
- Connection objects are tied to the WebSocket server’s process memory—they can’t be serialized or shared across processes.
- They contain live network resources and dependencies that can’t be persisted.
The approaches above avoid this by either using Laravel’s broadcast layer, accessing the in-process connection state (for same-process setups), or relaying messages via a queue (for production).
内容的提问来源于stack exchange,提问作者Uros Miric

