首页 > 新闻资讯 > 西安格创教你用php开发聊天应用

西安格创教你用php开发聊天应用

时间:2019-09-05

1、GatewayWorker是什么?

GatewayWorker是基于Workerman开发的一套TCP长连接的应用框架,实现了单发、群发、广播等接口,内置了mysql类库,GatewayWorker分为Gateway进程和Worker进程,天然支持分布式部署,能够支持庞大的连接数(百万甚至千万连接级别的应用)。可用于开发IM聊天应用、移动通讯、游戏后台、物联网、智能家居后台等等。

2、工作原理

(1) Register、Gateway、BusinessWorker进程启动

(2) Gateway、BusinessWorker进程启动后向Register服务进程发起长连接注册自己

(3) Register服务收到Gateway的注册后,把所有Gateway的通讯地址保存在内存中

(4) Register服务收到BusinessWorker的注册后,把内存中所有的Gateway的通讯地址发给BusinessWorker

(5) BusinessWorker进程得到所有的Gateway内部通讯地址后尝试连接Gateway

(6) 如果运行过程中有新的Gateway服务注册到Register(一般是分布式部署加机器),则将新的Gateway内部通讯地址列表将广播给所有BusinessWorker,BusinessWorker收到后建立连接

(7) 如果有Gateway下线,则Register服务会收到通知,会将对应的内部通讯地址删除,然后广播新的内部通讯地址列表给所有BusinessWorker,BusinessWorker不再连接下线的Gateway

(8) 至此Gateway与BusinessWorker通过Register已经建立起长连接

(9) 客户端的事件及数据全部由Gateway转发给BusinessWorker处理,BusinessWorker默认调用Events.php中的onConnect onMessage onClose处理业务逻辑。

(10) BusinessWorker的业务逻辑入口全部在Events.php中,包括onWorkerStart进程启动事件(进程事件)、onConnect连接事件(客户端事件)、onMessage消息事件(客户端事件)、onClose连接关闭事件(客户端事件)、onWorkerStop进程退出事件(进程事件)

3、快速搭建

(1) 下载PHP聊天室框架

https://www.workerman.net/workerman-chat

(2) 启动

Windows环境双击start_for_win.bat运行

linux环境输入php start.php start -d运行

(3) 使用

浏览器访问端口http://ip:55151或者http://域名:55151

注:Applications下的start_web.php是demo自带的web服务,正式项目中可以删除,删除的时候注意在start.phpstart_for_win.bat文件中一并删除相应代码。

4、目录结构

├── Applications // 这里是所有开发者应用项目

│   └── YourApp  // 其中一个项目目录,目录名可以自定义

│       ├── Events.php // 开发者只需要关注这个文件

│       ├── start_gateway.php // gateway进程启动脚本,包括端口号等设置

│       ├── start_businessworker.php // businessWorker进程启动脚本

│       └── start_register.php // 注册服务启动脚本

├── start.php // linux环境全局启动脚本,此脚本会依次加载Applications/项目/start_*.php启动脚本

├── start_for_win.bat//Windows环境启动脚本

└── vendor  // GatewayWorker框架和Workerman框架源码目录,此目录开发者不用关心

5、client_id说明

client_id固定为20个字符的字符串,用来全局标记一个socket连接,每个客户端连接都会被分配一个全局唯一的client_id。

client_id不能自定义,由GatewayWorker自动生成。

如果client_id对应的客户端连接断开了,那么这个client_id也就失效了。当这个客户端再次连接到Gateway时,将会获得一个新的client_id。也就是说client_id和客户端的socket连接生命周期是一致的。

client_id一旦被使用过,将不会被再次使用,也就是说client_id是不会重复的,即使分布式部署也不会重复。

只要有client_id,并且对应的客户端在线,就可以调用Gateway::sendToClient($client_id, $data)等方法向这个客户端发送数据。

6、Events类

Events.php说明:

Events.phpGatewayWorker处理业务逻辑的文件,默认调用。

如果需要改名在

workerman-chat\vendor\workerman\gateway-worker\src\BusinessWorker.php中修改:

public $eventHandler = 'Events';

回调属性说明

Events::onConnect

说明:

void Events::onConnect(string $client_id);

当客户端连接上gateway进程时(TCP三次握手完毕时)触发的回调函数在需要启动聊天时处理逻辑时调用。

Events::onMessage

说明:

void Events::onMessage(string $client_id, mixed $recv_data);

当客户端发来数据(Gateway进程收到数据)后触发的回调函数主要处理消息回复。

参数:$client_id全局唯一的客户端socket连接标识

$recv_data完整的客户端请求数据,数据类型取决于Gateway所使用协议的decode方法返的回值类型

7、常用方法

Gateway::bindUid

说明:

void Gateway::bindUid(string $client_id, mixed $uid);

client_id与uid绑定,以便通过Gateway::sendToUid($uid)发送数据,通过Gateway::isUidOnline($uid)用户是否在线。一个uid可以绑定多个client_id

Gateway::getUidByClientId

说明:

string Gateway::getUidByClientId(string $client_id);

返回client_id绑定的uid,如果client_id没有绑定uid,则返回null。

Gateway::getClientIdByUid

说明:

array Gateway::getClientIdByUid(mixed $uid);

返回一个数组,数组元素为与uid绑定的所有在线的client_id。如果没有在线的client_id则返回一个空数组。

此方法可以判断一个uid是否在线。

注意:返回值为与uid绑定的所有在线的client_id数组。因为已经下线的client_id会自动与uid解绑,所以已经下线的client_id不会出现在返回值中。

Gateway::sendToUid

说明:

void Gateway::sendToUid(mixed $uid, string $message);

uid绑定的所有在线client_id发送数据。

Gateway::joinGroup

说明:

void Gateway::joinGroup(string $client_id, mixed $group);

client_id加入某个组,以便通过Gateway::sendToGroup发送数据。

可以通过Gateway::getClientSessionsByGroup($group)获得该组所有在线成员数据。 可以通过Gateway::getClientCountByGroup($group)获得该组所有在线连接数(人数)。

该方法对于分组发送数据例如房间广播非常有用。

Gateway::leaveGroup

说明:

void Gateway::leaveGroup(string $client_id, mixed $group);

client_id从某个组中删除,不再接收该分组广播(Gateway::sendToGroup)发送的数据。

注意:当client_id下线(连接断开)时,client_id会自动从它所属的各个分组中删除,也就是说无需在onClose回调中调用Gateway::leaveGroup

Gateway::sendToGroup

说明:

void Gateway::sendToGroup(mixed $group, string $message [, array $exclude_client_id = null [, bool $raw = false]]);

向某个分组的所有在线client_id发送数据。

8、前端js说明

创建与服务器的链接

ws = new WebSocket("ws://"+url+":7272");

接受服务器的消息

ws.onmessage = function(e) {

   console.log(e);

};

链接关闭时触发

ws.onclose = function() {

   console.log("连接关闭,定时重连");

   connect();

};

 

 

发生错误时触发

ws.onerror = function() {

    console.log("出现错误");

};

9、单聊的实现

利用Gateway::bindUid将用户的id与client_id绑定,然后利用Gateway::sendToUid推送信息给客户。

10、群聊的实现

利用Gateway::joinGroup将用户加入群组中,然后用Gateway::sendToGroup推送信息给群组。

11、图片、文件、表情的发送

图片文件发送:

先将图片和文件上传至服务器,然后将地址发送给接收方。

表情的发送:

下载表情插件,将表情代码发送至聊天界面,再用js解析显示。

12、快速开发流程(以tp5为例)

workerman-chat解压至你的tp5根目录下,然后将chat放置于你的application下,将chat文件中index.html中的jq路径换成你自己的,打开workerman-chat/start_for_win.bat,调用chat下的Index/index方法进行聊天。

流程说明:

调用chat下的Index/index方法后,会自动调用

workerman-chat\Applications\Chat\Events.php中的onConnect方法发送client_id到聊天页面(chat中的index.html),

然后聊天页面利用ajax发送用户id到Index/bindclientidtoid方法中,利用Gateway::bindUid将client与用户的id绑定。

用户在聊天页面利用ajax将聊天内容发送到Index/sendmsg方法中处理,然后利用Gateway::sendToUid推送聊天内容至客户端。

注:

1)如果在其他框架中开发,在控制器引入以下代码

use \GatewayWorker\Lib\Gateway;

require_once './workerman-chat/vendor/autoload.php';

其余参照chat模块开发就行,workerman-chat依然放在框架根目录下。

3)如果tp项目不是直接位于web根目录下,注意修改index.html中ajax发送链接。

4)使用本实例代码打开两个聊天界面聊天时,会发现两个界面的名称和头像是相反的,是因为在控制器中头像和名称是写死的。

5)开发时注意打开7272端口和1236端口权限。

不过想要开发聊天应用最好还是来找西安格创网络科技有限公司,西安格创开发实力雄厚,产品涉及医药卫生、建筑、IT、娱乐、物流、咨询、房产、汽车等各个行业,您解决疑问和难题的良好保证。

格创科技 专业成就品牌

以真诚和专业 , 为客户提供真正有价值的 , 一站式传播解决方案

返回顶部

服务热线

189 6671 7535

156 9181 3376

在线咨询 1

微信扫码咨询