当前位置: 首页 > article >正文

PHP WebSocket

文章目录

  • PHP WebSocket 介绍
  • Laravel 8 中使用 WebSocket实现广播
    • 1. 安装 Laravel WebSockets
    • 2. 配置 WebSocket
    • 3.运行 WebSocket 服务器
    • 4. 客户端代码
    • 5. 在 Laravel 中广播事件
    • 6. 触发事件
    • 7. 监听事件
  • 创建单聊
    • 1.创建一个用于发送单聊消息的事件
    • 2.设置消息发送
    • 3.设置路由
    • 4.客户端 JavaScript 代码
  • 总结


PHP WebSocket 介绍

WebSocket 是一种网络通信协议,允许在客户端和服务器之间建立持久的全双工连接。这种连接使得服务器能够主动向客户端推送数据,而不仅仅是响应请求。WebSocket 特别适合需要实时数据交互的应用,如聊天应用、在线游戏和实时通知


Laravel 8 中使用 WebSocket实现广播

Laravel 中,可以使用多个库来实现 WebSocket,最常用的是 RatchetBeyond CodeLaravel WebSockets

1. 安装 Laravel WebSockets

使用 beyondcode/laravel-websockets 包

composer require beyondcode/laravel-websockets

2. 配置 WebSocket

安装完包后,需要发布配置文件

php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider"

这个操作会创建 config/websockets.php 文件,您可以在其中配置 WebSocket 服务器的设置

3.运行 WebSocket 服务器

可以通过 Artisan 命令启动 WebSocket 服务器

php artisan websockets:serve

启动 WebSocket 服务器并在默认端口(6001)上监听

4. 客户端代码

使用 JavaScript 来连接到 WebSocket 服务器

// resources/js/app.js

const socket = new WebSocket('ws://localhost:6001');

socket.onopen = function() {
    console.log('WebSocket connection established.');
};

socket.onmessage = function(event) {
    console.log('Message from server: ', event.data);
};

socket.onclose = function() {
    console.log('WebSocket connection closed.');
};

// 发送消息到服务器
socket.send('Hello, server!');

5. 在 Laravel 中广播事件

在事件中使用 ShouldBroadcast 接口

// app/Events/MessageSent.php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class MessageSent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $user;
    public $message;

    public function __construct($user, $message)
    {
        $this->user = $user;
        $this->message = $message;
    }

    public function broadcastOn()
    {
        return new Channel('chat');
    }
}

6. 触发事件

在控制器或其他需要的地方触发事件,以控制器为例

// app/Http/Controllers/ChatController.php

namespace App\Http\Controllers;

use App\Events\MessageSent;
use Illuminate\Http\Request;

class ChatController extends Controller
{
    public function sendMessage(Request $request)
    {
        $user = $request->user(); // 获取当前用户
        $message = $request->input('message');

        // 触发广播事件
        broadcast(new MessageSent($user, $message))->toOthers();

        return response()->json(['status' => 'Message sent!']);
    }
}

7. 监听事件

在客户端,可以使用 Laravel Echo 来监听事件

// 在 app.js 中

import Echo from 'laravel-echo';
import Pusher from 'pusher-js';

window.Pusher = Pusher;

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-key',
    cluster: 'your-pusher-cluster',
    forceTLS: true,
});

Echo.channel('chat')
    .listen('MessageSent', (e) => {
        console.log(e.user.name + ': ' + e.message);
    });

确保在视图中引入这个 JavaScript 文件

<script src="{{ mix('js/app.js') }}"></script>

创建单聊

1.创建一个用于发送单聊消息的事件

// app/Events/PrivateMessageSent.php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class PrivateMessageSent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $sender;
    public $receiver;
    public $message;

    public function __construct($sender, $receiver, $message)
    {
        $this->sender = $sender;
        $this->receiver = $receiver;
        $this->message = $message;
    }

    public function broadcastOn()
    {
        // 使用私密频道,格式为 private-{userId}
        return new PrivateChannel('private-chat.' . $this->receiver->id);
    }
}

2.设置消息发送

创建一个控制器来处理消息的发送

// app/Http/Controllers/ChatController.php

namespace App\Http\Controllers;

use App\Events\PrivateMessageSent;
use Illuminate\Http\Request;

class ChatController extends Controller
{
    public function sendMessage(Request $request)
    {
        // 验证请求数据
        $request->validate([
            'receiver_id' => 'required|exists:users,id',
            'message' => 'required|string',
        ]);

        $sender = $request->user(); // 获取当前用户
        $receiver = User::find($request->receiver_id); // 获取接收者用户

        // 触发广播事件
        broadcast(new PrivateMessageSent($sender, $receiver, $request->message))->toOthers();

        return response()->json(['status' => 'Message sent!']);
    }
}

3.设置路由

routes/web.php 中添加路由

use App\Http\Controllers\ChatController;

Route::post('/send-private-message', [ChatController::class, 'sendMessage']);

4.客户端 JavaScript 代码

这里还是使用Laravel Echo 连接到 WebSocket 服务器并处理消息发送和接收

// resources/js/app.js

import Echo from 'laravel-echo';
import Pusher from 'pusher-js';

window.Pusher = Pusher;

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-key',
    cluster: 'your-pusher-cluster',
    forceTLS: true,
});

// 连接到用户的私密频道
function connectToPrivateChannel(userId) {
    window.Echo.private('private-chat.' + userId)
        .listen('PrivateMessageSent', (e) => {
            console.log(`${e.sender.name}: ${e.message}`);
            // 这里可以更新 DOM 以显示消息
        });
}

// 发送消息函数
function sendMessage(receiverId) {
    const message = document.getElementById('message').value;

    fetch('/send-private-message', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
        },
        body: JSON.stringify({ receiver_id: receiverId, message }),
    })
    .then(response => response.json())
    .then(data => {
        console.log(data.status);
    })
    .catch(error => console.error('Error:', error));
}

// 在 HTML 中调用 connectToPrivateChannel 和 sendMessage 方法

html代码

<!-- resources/views/chat.blade.php -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>Private Chat</title>
    <script src="{{ mix('js/app.js') }}"></script>
</head>
<body>
    <div>
        <h1>Private Chat Room</h1>
        <div id="chat-box">
            <!-- 这里将显示聊天记录 -->
        </div>
        <input type="text" id="message" placeholder="Type a message...">
        <select id="receiver-id">
            <!-- 动态加载用户列表 -->
            @foreach($users as $user)
                <option value="{{ $user->id }}">{{ $user->name }}</option>
            @endforeach
        </select>
        <button onclick="sendMessage(document.getElementById('receiver-id').value)">Send</button>
    </div>
</body>
</html>

总结

通过以上步骤我们可以在 Laravel 8 中实现聊天功能,实现用户之间进行通信,允许用户实时发送和接收消息,并通过 WebSocket 实时更新聊天记录,还可以根据需求扩展功能,例如添加消息存储、用户状态、聊天记录等


http://www.kler.cn/a/349668.html

相关文章:

  • zabbix7 配置字体 解决中文乱码问题(随手记)
  • ROS2---基础操作
  • 使用langchain ollama gradio搭建一个本地基于deepseek r1的RAG问答系统
  • 一文讲解Java中的异常处理机制
  • Docker小游戏 | 使用Docker部署FC-web游戏模拟器
  • wordpress每隔24小时 随机推荐一个指定分类下的置顶内容。
  • nginx代理内网服务器8080端口
  • 【jQuery】jQuery基本操作(样式操作 内容操作 节点操作 属性操作 节点遍历)
  • 作为企业的管理者,应该怎样面对信息安全等级测评这项国家政策?
  • 从纸质到云端:3C产品说明书的电子化进程与影响
  • (Java企业 / 公司项目)阿里云aliyun-对象存储OSS详细从开通到配置(微服务架构选用)
  • 通过华为鲲鹏认证发行上市的集成平台产品推荐
  • 2.2机器学习--逻辑回归(分类)
  • 鸿蒙--设置项布局
  • .net core 实现异步的方式有哪些?
  • Python 中 NameError 全局名称未定义
  • RHCE的学习(1)
  • 10.12Python数学基础-矩阵(上)
  • PLC数据如何高效传输到MongoDB?
  • lspci | grep VGA
  • Flink作业骨架结构
  • 统计好三元组(c语言)
  • Web集群服务-代理和负载均衡
  • 大商创(移动端) -- day02
  • 自由学习记录(8)
  • 机器学习(MachineLearning)(8)——模型评估与优化