基于swoole实现多人聊天室

本文实例为大家分享了swoole创建多人多房间聊天室的具体代码,供大家参考,具体内容如下

核心的swoole代码

基本的cs(client-sercer)结构不变,这里利用的是redis的哈希和set来储存和分组;从而达到了分组,统计,定时推送等功能;最后利用onclose事件来剔除断开的连接,全部代码如下:(没做前端,就不展示了)

核心的swoole ws.php

<?php 

namespace app\common;
require_once 'Predis.php';
require_once 'Task.php';
/**
*  socket面向对象的编译
*/
class Ws
{
  CONST HOST='0.0.0.0';
  CONST PORT='9501';
  public $ws=null;
  public $getmsg=null;
  public $server=null; 

  public function __construct()
  {
    $this->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();
  }
  //监听数据接收事件
  public function onReceive($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_arr as $v) {
          $this->ws->push($v, $shuju['msg']);
        }
      }
    }
  }
  /**
   * 设置进程名,为后续平滑重启进程
   * @param $server
   */
  public function onStart($server) {
    swoole_set_process_name("live_master");
  }
  /**
    监听开启事件的回调
  */
  public function onopen($server, $request)
  {
    print_r("这时的fd是:",$request->fd);
    Predis::getInstance()->set('fd',$request->fd);
  } 

  /**
    监听接收事件的回调
  */
  public function onmessage($server, $frame)
  {
    $server->push($frame->fd, "{$frame->data}");
  }
  /**
    监听关闭事件的回调
  */
  public function onclose($ser, $fd)
  {
    print_r("你好,我的{$fd}\n");
    //退出并删除多余的分组fd
    $group=Predis::getInstance()->sMembers('group');
    foreach ($group as $v) {
      $fangjian=Predis::getInstance()->hgetall($v);
      foreach ($fangjian as $k => $vv) {
        if ($fd == $vv) {
          Predis::getInstance()->hdel($v,$k);
        }
      }
    }
  }
  public function oncloses($ser, $fd)
  {
    print_r("这个是client{$fd}\n");
  } 

  /**
  *  $serv      服务
  *  $task_id    任务ID,由swoole扩展内自动生成,用于区分不同的任务
  *  $src_worker_id $task_id和$src_worker_id组合起来才是全局唯一的,不同的worker进程投递的任务ID可能会有相同
  *  $data      是任务的内容
  */
   public function onTask($serv,$task_id,$src_worker_id,$data)
  {
    //引入任务
    $obj = new Task;
    $method = $data['data'];
    $arr = $data['arr'];
    //发布具体的任务
    $flag = $obj->$method($arr, $serv);
    return $flag; // 告诉worker
  }
  /**
  *  $task_id    是任务的ID
  *  $data      是任务处理的结果内容
  */
   public function onFinish($serv,$task_id,$data)
  {
    print_r($data).'/n';
  } 

} 

new Ws();

分发任务task.php

<?php
/**
 * 代表的是 swoole里面 后续 所有 task异步 任务 都放这里来
 * Date: 18/3/27
 * Time: 上午1:20
 */
namespace app\common;
// include 'Predis.php'; 

class Task {
  //异步创建房间
  public function chuangjian($data,$serv)
  {
    $time=$data['time']*1000;
    swoole_timer_after($time, function() use($data){
      //创建房间(修改拍卖商品状态)
      self::post("https://code.77wx.cn/index/index/in");
    });
  } 

  //进入房间并缓存信息
  public function jingru($data,$serv)
  {
    $fd=Predis::getInstance()->get('fd');
    //加入分组
    Predis::getInstance()->hset($data['name'],$data['uid'],$fd);
    //加入组集合
    Predis::getInstance()->sadd('group',$data['name']);
  } 

  public function post($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 (Windows NT 5.1) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/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 "cURL Error: " . curl_error($ch);
      return false;
    } 

    $httpCode = curl_getinfo( $ch , CURLINFO_HTTP_CODE );
    $httpInfo = array_merge( $httpInfo , curl_getinfo( $ch ) );
    //关闭url请求
    curl_close( $ch );
    return json_decode($response,1);
  } 

} 

客户端 client.php

<?php
namespace app\common; 

class Client
{
  public $msg=''; 

  public $data=[]; 

  public function lianjie(){ 

    $cli = new \swoole_client(SWOOLE_SOCK_TCP);
    //判断连接状态(同步连接模式)
    $res=$cli->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{
      return flash;
    }
  }
} 

控制器index.php

<?php
namespace app\index\controller; 

use app\common\Client;
use app\common\Predis;
use app\common\Sql;
use app\index\model\User; 

class Index
{
  //创建房间(添加拍卖倒计时)
  public function chuangjian()
  {
    $data['time']=input("time");
    $data['id']=input("id");
    $cli = new Client();
    $cli->data = [
      'data' => 'chuangjian',
      'arr' => $data
    ];
    return $cli->lianjie();
  }
  //点击添加哈希(进入房间)
  public function jingru()
  {
    $data['name']=input("name");
    $data['uid']=input("uid");
    $cli = new Client();
    $cli->data = [
      'data' => 'jingru',
      'arr' => $data
    ];
    return $cli->lianjie();
  }
  //本房间推送(出价格成功并推送)
  public function pushfan()
  {
    $data['fan']=input("fan");
    $cli = new Client();
    $cli->data = [
      'data' => $data['fan'],
      'msg' => "恭喜用户111,喜当爹!!!!"
    ];
    return $cli->lianjie();
  }
  //时间结束并指定推送
  public function zhiding()
  {
    $data['fan']=input("fan");
    $cli = new Client();
    $cli->data = [
      'data' => $data['fan'],
      'msg' => "恭喜用户111,喜当爹!!!!"
    ];
    return $cli->lianjie();
  } 

} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • PHP+swoole实现简单多人在线聊天群发

    由于本文的能力有限,有好多聊天逻辑的细节没有实现,只实现了群发,具体代码如下所示: php代码: $serv = new swoole_websocket_server("127.0.0.1",3999); //服务的基本设置 $serv->set(array( 'worker_num' => 2, 'reactor_num'=>8, 'task_worker_num'=>1, 'dispatch_mode' => 2, 'debug_mode'=>

  • swoole和websocket简单聊天室开发

    首先,我想说下写代码的一些习惯,第一,任何可配置的参数或变量都要写到一个config文件中.第二,代码中一定要有日志记录和完善的报错并记录报错.言归正传,swoole应该是每个phper必须要了解的,它号称重新定义了php.此聊天室利用了swoole高并发并且异步非阻塞的特点提高了程序的性能. 首先,定义一个 swoole_lock 和 swoole_websocket_server ,并且配置参数,具体参数详情可以去swoole官网查看. public function start() { $

  • ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例详解

    本文实例讲述了ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例.分享给大家供大家参考,具体如下: ThinkPHP使用Swoole需要安装 think-swoole Composer包,前提系统已经安装好了Swoole PECL 拓展(相关文章:Linux下源码包安装使用Swoole扩展) 在tp5的项目根目录下执行composer命令安装think-swoole: composer require topthink/think-swoole 安装成功: 话不多说

  • Ajax PHP JavaScript MySQL实现简易无刷新在线聊天室

    为更好的运用这两天学到的Ajax的相关的知识,就做了个简单的在线网络聊天室. 思路 实现聊天室,基本上就是通过Ajax来传递数据,让PHP来实现对数据的差入和查找,再交给前端JavaScript实现页面的更新,达到即时聊天的功能. 消息显示区 消息显示区就是一个DIV块,我们会借助Ajax获取到服务器端信息之后,使用JavaScript来更新页面. <h3>消息显示区</h3> <div id="up"> </div> <hr /&

  • 基于javascript、ajax、memcache和PHP实现的简易在线聊天室

    在线聊天室(online chatrooms)是一个共多人进行沟通交流的网络平台,随着越来越多的新技术的发明和成熟运用,在线聊天室也出现使用各种不同技术的, 这篇文章我想简单总结一下. 首先说一下前台技术,最新的当然是基于HTML5的websocket,它实现了浏览器与服务器全双工通信(full-duplex).WebSocket通信协议于2011年被IETF定为标准 RFC 6455,WebSocketAPI被W3C定为标准.在WebSocket API中,浏览器和服务器只需要做一个握手的动作

  • 基于Swoole实现PHP与websocket聊天室

    websocket Websocket只是一个网络通信协议 就像 http.ftp等都是网络通信的协议:不要多想: 相对于HTTP这种非持久的协议来说,Websocket是一个持久化网络通信的协议: WebSocket和HTTP的关系 有交集,但是并不是全部. Websocket只是借用了HTTP的一部分协议来完成一次握手.(HTTP的三次握手,此处只完成一次) http和websocket 请求头对比: HTTP: 原来的时候,客户端通过http(骑马)带着信请求服务器,服务器处理请求(写回信

  • 详解thinkphp5+swoole实现异步邮件群发(SMTP方式)

    本文介绍了thinkphp5+swoole实现异步邮件群发(SMTP方式),分享给大家,具体如下: 1.环境说明 阿里云centos7 thinkphp5.0.11 swoole2.0.8 2.tp实现邮件发送 在项目下建立如下的文件目录: 其中SendMail.php是我们实际调用的发送邮件的文件.以下是主要代码: namespace app\library\utils\mail; use app\library\utils\mail\PhpMailer; use app\library\ut

  • 基于swoole实现多人聊天室

    本文实例为大家分享了swoole创建多人多房间聊天室的具体代码,供大家参考,具体内容如下 核心的swoole代码 基本的cs(client-sercer)结构不变,这里利用的是redis的哈希和set来储存和分组;从而达到了分组,统计,定时推送等功能;最后利用onclose事件来剔除断开的连接,全部代码如下:(没做前端,就不展示了) 核心的swoole ws.php <?php namespace app\common; require_once 'Predis.php'; require_on

  • java使用MulticastSocket实现基于广播的多人聊天室

    使用MulticastSocket实现多点广播: (1)DatagramSocket只允许数据报发给指定的目标地址,而MulticastSocket可以将数据报以广播的方式发送到多个客户端. (2)IP协议为多点广播提供了这批特殊的IP地址,这些IP地址的范围是:224.0.0.0至239.255.255.255.. (3)MulticastSocket类时实现多点广播的关键,当MulticastSocket把一个DaragramPocket发送到多点广播的IP地址时,该数据报将会自动广播到加入

  • Java基于Socket实现多人聊天室

    本文实例为大家分享了Java基于Socket实现简易版多人聊天室的具体代码,供大家参考,具体内容如下 一. 聊天室需求 1.一个服务端,多个客户端:2.实现客户端和服务端的交互:3.客户端发送信息,服务端收到信息,再转发给其他客户端:4.上下线时显示哪个客户端上下线并且显示在线客户端数量: 二.代码分析 1. 建立连接 客户端类,创建发送端Socket对象,用自己的IP地址和端口号,与服务端建立连接. class Client: //用于与服务端通信的Socket private Socket

  • 基于java编写局域网多人聊天室

    由于需要制作网络计算机网络课程设计,并且不想搞网络布线或者局域网路由器配置等等这种完全搞不懂的东西,最后决定使用socket基于java编写一个局域网聊天室: 关于socket以及网络编程的相关知识详见我另一篇文章:Java基于socket编程 程序基于C/S结构,即客户端服务器模式. 服务器: 默认ip为本机ip 需要双方确定一个端口号 可设置最大连接人数 可启动与关闭 界面显示在线用户人以及姓名(本机不在此显示) 客户端: 需要手动设置服务器ip地址(局域网) 手动设置端口号 输入姓名 可连

  • 基于Nodejs利用socket.io实现多人聊天室

    socket.io简介 在Html5中存在着这样的一个新特性,引入了websocket,关于websocket的内部实现原理可以看这篇文章,这篇文章讲述了websocket无到有,根据协议,分析数据帧的头,进行构建websocket.虽然代码短,但可以很好地体现websocket的原理. ,这个特性提供了浏览器端和服务器端的基于TCP连接的双向通道.但是并不是所有的浏览器都支持websocket特性,故为了磨平浏览器间的差异,为开发者提供统一的接口,引入了socket.io模块.在不支持webs

  • Java基于中介者模式实现多人聊天室功能示例

    本文实例讲述了Java基于中介者模式实现多人聊天室功能.分享给大家供大家参考,具体如下: 一 模式定义 中介者模式,用一个中介对象来封装一系列对象之间的交互,使各个对象中不需要显示地引用其他对象实例,从而降低各个对象之间的耦合度,并且可以独立地改变对象间的交互关系. 二 模式举例 1 模式分析 我们借用多人聊天室来说明这一模式 2 中介模式静态类图 3 代码示例 3.1中介者接口--IMediator package com.demo.mediator; import com.demo.coll

  • Python基于Socket实现简易多人聊天室的示例代码

    前言 套接字(Sockets)是双向通信信道的端点. 套接字可以在一个进程内,在同一机器上的进程之间,或者在不同主机的进程之间进行通信,主机可以是任何一台有连接互联网的机器. 套接字可以通过多种不同的通道类型实现:Unix域套接字,TCP,UDP等. 套接字库提供了处理公共传输的特定类,以及一个用于处理其余部分的通用接口. socket模块: 要创建套接字,必须使用套接字模块中的socket.socket()函数,该函数具有一般语法 s = socket.socket (socket_famil

  • 使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室

    一,利用Node搭建静态服务器 这个是这个项目的底层支撑部分.用来支持静态资源文件像html, css, gif, jpg, png, javascript, json, plain text等等静态资源的访问.这里面是有一个mime类型的文件映射. mime.js /** * mime类型的 map * @ author Cheng Liufeng * @ date 2014/8/30 * 当请求静态服务器文件的类型 html, css, gif, jpg, png, javascript,

  • nodejs+express搭建多人聊天室步骤

    前言 本文主要是笔者在学习node的时候,作为练手的一个小项目,花了几天空余时间,边码边写教程的一个过程.适用于对node理论知识看的多,实战少的同学,那么现在就让我们开始吧! 准备工作 新建一个文件夹 chatroom 在终端输入以下命令,按照步骤npm(没装过的去官网安装下node和npm)会自动给你生成一个package.json文件 安装express和socket.io package.json文件如下: //package.json { "name": "chat

  • 利用GO语言实现多人聊天室实例教程

    前言 运用go里面的net包中的相关方法来实现一个基于tcp的简单多人聊天室,用一个服务器来管理,主要反馈客户端是否连接成功并显示客户端输入的内容,并且发送给每一个在服务器上连接的客服端,下面话不多说了,来一起看看详细的介绍吧. 示例代码 服务器代码 // server package main import ( "fmt" "net" ) var ConnMap map[string]*net.TCPConn func checkErr(err error) in

随机推荐