即时交互的应用

大家应该都有所体会,在现代的 Web 应用中很多场景都需要运用到即时通讯,比如说最常见的支付回调,与三方登录。这些业务场景都基本需要遵循以下流程:
在过去,为了实现这种即时通讯,能让客户端正确响应处理结果,最为常用的技术就是轮询,因为 HTTP 协议的单向性,客户端只能一遍一遍的主动询问服务端的处理结果。这种方式有显见的缺陷,占用服务端资源不说,还不能实时获得服务端处理结果。
现在,我们可以使用 WebSocket 协议来处理实时交互,它是一种双向协议,允许服务端主动推送信息到客户端。本篇我们将借助 Laravel 强大的事件系统来构建实时的交互。你将需要用到以下知识:
Redis
在开始之前,我们需要开启一个 redis 服务,并在 Laravel 应用中进行配置启用,因为在整个流程中,我们需要借助 redis 的订阅和发布机制来实现即时通讯。
Redis 是一个开源高效的键值对存储系统。它通常作为一个数据结构服务器来存储键值对,它可以支持字符串,散列,列表,集合和有序结合。在 Laravel 中使用 Redis 你需用通过 Composer 来安装 predis/predis 包文件。
配置
Redis 在应用中的配置文件存储在 config/database.php,在这个文件中,你可以看到一个包含了 Redis 服务信息的 redis 数组:
'redis' => [ 'cluster' => false, 'default' => [ 'host' => '127.0.0.1', 'port' => 6379, 'database' => 0, ], ]
如果你修改了 redis 服务的端口,请保持配置文件中的端口一致。
Laravel Event
这里我们需要借助 Laravel 强大的事件广播能力:
广播事件
很多现代化的应用中,会使用 Web Sockets 来实现实时交互的用户接口。当一些数据在服务端变更时,一条消息会通过 WebSocket 连接来传递到客户端进行处理。
为了帮助你构建这种类型的应用。Laravel 使通过 WebSocket 连接进行广播事件变的非常简单。Laravel 允许你广播事件来共享事件的名称到你的服务端和客户端的 JavaScript 框架。
配置
所有的事件广播配置选项都被存储在 config/broadcasting.php 配置文件中。Laravel 附带了几种可用的驱动如 Pusher,Redis,和 Log,我们将使用 Redis 作为广播驱动,这里需要依赖 predis/predis 类库。
由于默认的广播驱动使用的是 pusher,所以我们需要在 .env 文件中设置 BROADCAST_DRIVER=redis。
我们创建一个 WechatLoginedEvent 事件类用来在用户扫描微信登录后进行广播:
<?php
namespace App\Events;
use App\Events\Event;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class WechatLoginedEvent extends Event implements ShouldBroadcast
{
use SerializesModels;
public $token;
protected $channel;
/**
* Create a new event instance.
*
* @param string $token
* @param string $channel
* @return void
*/
public function __construct($token, $channel)
{
$this->token = $token;
$this->channel = $channel;
}
/**
* Get the channels the event should be broadcast on.
*
* @return array
*/
public function broadcastOn()
{
return [$this->channel];
}
/**
* Get the name the event should be broadcast on.
*
* @return string
*/
public function broadcastAs()
{
return 'wechat.login';
}
}
其中你需要注意 broadcastOn 方法应返回一个数组,它表示所需广播的频道,而 broadcastAs 返回的是一个字符串,它表示广播所触发的事件,Laravel 默认的是返回事件类的全类名,这里是 App\Events\WechatLoginedEvent.
最重要的是你需要手动的让该类实现 ShouldBroadcast 契约。Laravel 在生成事件时,已经自动添加了该命名空间,该契约只约束 broadcastOn 方法。
事件完成接下来就是触发事件了,简单的一行代码就可以:
event(new WechatLoginedEvent($token, $channel));
这个操作会自动的触发事件的执行并将信息广播出去。该广播操作底层借助了 redis 的订阅和发布机制。
RedisBroadcaster 会将事件中的允许公开访问的数据通过给定的频道发布出去。如果你想对公开的数据拥有更多的控制,你可以在事件中添加 broadcastWith 方法,它应该返回一个数组:
/**
* Get the data to broadcast.
*
* @return array
*/
public function broadcastWith()
{
return ['user' => $this->user->id];
}
Node.js 和 Socket.io
对于发布出去的信息,我们需要一个服务来对接,让其能对 redis 的发布能够进行订阅,并且能把信息以 WebSocket 协议转发出去,这里我们可以借用 Node.js 和 socket.io 来非常方便的构建这个服务:
// server.js
var app = require('http').createServer(handler);
var io = require('socket.io')(app);
var Redis = require('ioredis');
var redis = new Redis();
app.listen(6001, function () {
console.log('Server is running!') ;
});
function handler(req, res) {
res.writeHead(200);
res.end('');
}
io.on('connection', function (socket) {
socket.on('message', function (message) {
console.log(message)
})
socket.on('disconnect', function () {
console.log('user disconnect')
})
});
redis.psubscribe('*', function (err, count) {
});
redis.on('pmessage', function (subscrbed, channel, message) {
message = JSON.parse(message);
io.emit(channel + ':' + message.event, message.data);
});
这里我们使用 Node.js 引入 socket.io 服务端并监听 6001 端口,借用 redis 的 psubscribe 指令使用通配符来快速的批量订阅,接着在消息触发时将消息通过 WebSocket 转发出去。
Socket.io 客户端
在 web 前端,我们需要引入 Socket.io 客户端开启与服务端 6001 端口的通讯,并订阅频道事件:
// client.js
let io = require('socket.io-client')
var socket = io(':6001')
socket.on($channel + ':wechat.login', (data) => {
socket.close()
// save user token and redirect to dashboard
})
至此整个通讯闭环结束,开发流程看起来就是这样的:
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
# laravel
# 应用
# 即时通讯
# 即时聊天
# 服务端
# 客户端
# 的是
# 第三方
# 如果你
# 配置文件
# 你可以
# 一遍
# 来实现
# 键值
# 是一个
# 闭环
# 在这个
# 并在
# 它是
# 所需
# 我们可以
# 数据结构
# 能让
相关文章:
如何在景安服务器上快速搭建个人网站?
建站之星导航如何优化提升用户体验?
如何解决ASP生成WAP建站中文乱码问题?
网站图片在线制作软件,怎么在图片上做链接?
成都响应式网站开发,dw怎么把手机适应页面变成网页?
C++如何编写函数模板?(泛型编程入门)
历史网站制作软件,华为如何找回被删除的网站?
简历在线制作网站免费,免费下载个人简历的网站是哪些?
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
python的本地网站制作,如何创建本地站点?
建站主机助手选型指南:2025年热门推荐与高效部署技巧
建站之星免费版是否永久可用?
名字制作网站免费,所有小说网站的名字?
如何快速搭建高效服务器建站系统?
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
山东云建站价格为何差异显著?
建站之星安全性能如何?防护体系能否抵御黑客入侵?
成都网站制作价格表,现在成都广电的单独网络宽带有多少的,资费是什么情况呢?
建站VPS能否同时实现高效与安全翻墙?
教学论文网站制作软件有哪些,写论文用什么软件
?
惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?
如何通过服务器快速搭建网站?完整步骤解析
网站专业制作公司有哪些,做一个公司网站要多少钱?
建站之星如何修改网站生成路径?
制作网站公司那家好,网络公司是做什么的?
c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗
佛山企业网站制作公司有哪些,沟通100网上服务官网?
如何用美橙互联一键搭建多站合一网站?
小型网站制作HTML,*游戏网站怎么搭建?
如何配置WinSCP新建站点的密钥验证步骤?
网站制作免费,什么网站能看正片电影?
重庆网站制作公司哪家好,重庆中考招生办官方网站?
XML的“混合内容”是什么 怎么用DTD或XSD定义
建站之星安装步骤有哪些常见问题?
建站主机选购指南:核心配置优化与品牌推荐方案
小型网站建站如何选择虚拟主机?
网站制作专业公司有哪些,如何制作一个企业网站,建设网站的基本步骤有哪些?
网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
如何获取免费开源的自助建站系统源码?
广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?
成都网站制作公司哪家好,四川省职工服务网是做什么用?
常州企业建站如何选择最佳模板?
c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】
javascript基本数据类型及类型检测常用方法小结
如何快速搭建虚拟主机网站?新手必看指南
Android使用GridView实现日历的简单功能
如何用好域名打造高点击率的自主建站?
赚钱网站制作软件,建一个网站怎样才能赚钱?是如何盈利的?
企业网站制作费用多少,企业网站空间一般需要多大,费用是多少?
*请认真填写需求信息,我们会在24小时内与您取得联系。