基于swoole实现多人聊天室
本文实例为大家分享了swoole创建多人多房间聊天室的具体代码,供大家参考,具体内容如下
核心的swoole代码
基本的cs(client-sercer)结构不变,这里利用的是redis的哈希和set来储存和分组;从而达到了分组,统计,定时推送等功能;最后利用onclose事件来剔除断开的连接,全部代码如下:(没做前端,就不展示了)
核心的swoolews.php
ws=new\swoole_websocket_server(self::HOST,self::PORT);
$this->ws->set([
//启动task必须要设置其数量
'worker_num'=>4,
'task_worker_num'=>2,
//'heartbeat_check_interval'=>5,
//'heartbeat_idle_time'=>10,
]);
//监听新端口
$this->server=$this->ws->listen("127.0.0.1",9502,SWOOLE_SOCK_TCP);
//关闭websocket模式
$this->server->set([
'open_websocket_protocol'=>false,
]);
$this->ws->on("start",[$this,'onStart']);
$this->ws->on('open',[$this,'onopen']);
$this->server->on("receive",[$this,'onReceive']);
$this->ws->on('task',[$this,'onTask']);
$this->ws->on('finish',[$this,'onFinish']);
$this->ws->on('message',[$this,'onmessage']);
$this->ws->on('close',[$this,'onclose']);
$this->server->on("close",[$this,'oncloses']);
$this->ws->start();
}
//监听数据接收事件
publicfunctiononReceive($serv,$fd,$from_id,$data)
{
$shuju=json_decode($data,ture);
//print_r($shuju).PHP_EOL;
if(empty($shuju['data'])){
$this->ws->push(Predis::getInstance()->get('fd'),$data);
}else{
if(empty($shuju['msg'])){
//执行异步任务
$this->ws->task($shuju);
}else{
$push_arr=Predis::getInstance()->hvals($shuju['data']);
//echo"集群是:".print_r($push_arr);
foreach($push_arras$v){
$this->ws->push($v,$shuju['msg']);
}
}
}
}
/**
*设置进程名,为后续平滑重启进程
*@param$server
*/
publicfunctiononStart($server){
swoole_set_process_name("live_master");
}
/**
监听开启事件的回调
*/
publicfunctiononopen($server,$request)
{
print_r("这时的fd是:",$request->fd);
Predis::getInstance()->set('fd',$request->fd);
}
/**
监听接收事件的回调
*/
publicfunctiononmessage($server,$frame)
{
$server->push($frame->fd,"{$frame->data}");
}
/**
监听关闭事件的回调
*/
publicfunctiononclose($ser,$fd)
{
print_r("你好,我的{$fd}\n");
//退出并删除多余的分组fd
$group=Predis::getInstance()->sMembers('group');
foreach($groupas$v){
$fangjian=Predis::getInstance()->hgetall($v);
foreach($fangjianas$k=>$vv){
if($fd==$vv){
Predis::getInstance()->hdel($v,$k);
}
}
}
}
publicfunctiononcloses($ser,$fd)
{
print_r("这个是client{$fd}\n");
}
/**
*$serv服务
*$task_id任务ID,由swoole扩展内自动生成,用于区分不同的任务
*$src_worker_id$task_id和$src_worker_id组合起来才是全局唯一的,不同的worker进程投递的任务ID可能会有相同
*$data是任务的内容
*/
publicfunctiononTask($serv,$task_id,$src_worker_id,$data)
{
//引入任务
$obj=newTask;
$method=$data['data'];
$arr=$data['arr'];
//发布具体的任务
$flag=$obj->$method($arr,$serv);
return$flag;//告诉worker
}
/**
*$task_id是任务的ID
*$data是任务处理的结果内容
*/
publicfunctiononFinish($serv,$task_id,$data)
{
print_r($data).'/n';
}
}
newWs();
分发任务task.php
get('fd');
//加入分组
Predis::getInstance()->hset($data['name'],$data['uid'],$fd);
//加入组集合
Predis::getInstance()->sadd('group',$data['name']);
}
publicfunctionpost($url,$params=false,$ispost=0)
{
$httpInfo=array();
$ch=curl_init();
curl_setopt($ch,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0(WindowsNT5.1)AppleWebKit/537.22(KHTML,likeGecko)Chrome/25.0.1364.172Safari/537.22');
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,30);
curl_setopt($ch,CURLOPT_TIMEOUT,30);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
if($ispost)
{
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$params);
curl_setopt($ch,CURLOPT_URL,$url);
}
else
{
if($params){
curl_setopt($ch,CURLOPT_URL,$url.'?'.$params);
}else{
curl_setopt($ch,CURLOPT_URL,$url);
}
}
//执行
$response=curl_exec($ch);
if($response===FALSE){
//echo"cURLError:".curl_error($ch);
returnfalse;
}
$httpCode=curl_getinfo($ch,CURLINFO_HTTP_CODE);
$httpInfo=array_merge($httpInfo,curl_getinfo($ch));
//关闭url请求
curl_close($ch);
returnjson_decode($response,1);
}
}
客户端client.php
connect('127.0.0.1',9502);
if(empty($res)){
return"连接失败";
}
if(!empty($this->data)){
//发送消息给server
$rel=$cli->send(json_encode($this->data));
}else{
//发送消息给server
$rel=$cli->send($this->msg);
}
if(!empty($rel)){
return$rel;
}else{
returnflash;
}
}
}
控制器index.php
data=[
'data'=>'chuangjian',
'arr'=>$data
];
return$cli->lianjie();
}
//点击添加哈希(进入房间)
publicfunctionjingru()
{
$data['name']=input("name");
$data['uid']=input("uid");
$cli=newClient();
$cli->data=[
'data'=>'jingru',
'arr'=>$data
];
return$cli->lianjie();
}
//本房间推送(出价格成功并推送)
publicfunctionpushfan()
{
$data['fan']=input("fan");
$cli=newClient();
$cli->data=[
'data'=>$data['fan'],
'msg'=>"恭喜用户111,喜当爹!!!!"
];
return$cli->lianjie();
}
//时间结束并指定推送
publicfunctionzhiding()
{
$data['fan']=input("fan");
$cli=newClient();
$cli->data=[
'data'=>$data['fan'],
'msg'=>"恭喜用户111,喜当爹!!!!"
];
return$cli->lianjie();
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。