首页 > 新闻资讯 > 西安格创教你用php开发聊天应用
西安格创教你用php开发聊天应用
时间:2019-09-05
GatewayWorker是基于Workerman开发的一套TCP长连接的应用框架,实现了单发、群发、广播等接口,内置了mysql类库,GatewayWorker分为Gateway进程和Worker进程,天然支持分布式部署,能够支持庞大的连接数(百万甚至千万连接级别的应用)。可用于开发IM聊天应用、移动通讯、游戏后台、物联网、智能家居后台等等。
(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进程退出事件(进程事件)
(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.php和start_for_win.bat文件中一并删除相应代码。
├── 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框架源码目录,此目录开发者不用关心
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)等方法向这个客户端发送数据。
Events.php说明:
Events.php是GatewayWorker处理业务逻辑的文件,默认调用。
如果需要改名在
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方法返的回值类型。
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发送数据。
创建与服务器的链接
ws = new WebSocket("ws://"+url+":7272");
接受服务器的消息
ws.onmessage = function(e) {
console.log(e);
};
链接关闭时触发
ws.onclose = function() {
console.log("连接关闭,定时重连");
connect();
};
发生错误时触发
ws.onerror = function() {
console.log("出现错误");
};
利用Gateway::bindUid将用户的id与client_id绑定,然后利用Gateway::sendToUid推送信息给客户。
利用Gateway::joinGroup将用户加入群组中,然后用Gateway::sendToGroup推送信息给群组。
图片文件发送:
先将图片和文件上传至服务器,然后将地址发送给接收方。
表情的发送:
下载表情插件,将表情代码发送至聊天界面,再用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、娱乐、物流、咨询、房产、汽车等各个行业,是您解决疑问和难题的良好保证。