swoole和websocket简单聊天室开发

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

首先,定义一个 swoole_lock swoole_websocket_server ,并且配置参数,具体参数详情可以去swoole官网查看。

public function start()
{
   $this->lock = new swoole_lock(SWOOLE_MUTEX);            

   // 对文件或数组进行锁操作,已达到同步
   $this->server = new swoole_websocket_server($this->addr, $this->port);  

   // swoole提供的Websocket Server
   $this->server->set(array(
      'daemonize' => 0,
      'worker_num' => 4,
      'task_worker_num' => 10,
      'max_request' => 1000,
      'log_file' => ROOT_PATH . 'storage\\logs\\swoole.log'   

    // swoole日志路径,必须是绝对路径
   ));

   $this->server->on('open', array($this, 'onOpen'));
   $this->server->on('message', array($this, 'onMessage'));
   $this->server->on('task', array($this, 'onTask'));
   $this->server->on('finish', array($this, 'onFinish'));
   $this->server->on('close', array($this, 'onClose'));

   // 启动服务
   $this->server->start();
}

当有客户端链接时,简单记录客户端的信息。

public function onOpen($server, $request)
    {
      $message = array(
        'remote_addr' => $request->server['remote_addr'],
        'request_time' => date('Y-m-d H:i:s', $request->server['request_time'])
      );
      write_log($message);
    }

当有客户端发送信息时,对信息进行处理。

public function onMessage($server, $frame)
    {
      $data = json_decode($frame->data);

      switch ($data->type) {
        case 'init':
        case 'INIT':
          $this->users[$frame->fd] = $data->message;  、

      // 记录每个链接的信息,同样不要尝试打印出来看,因为你只能看到自己的链接信息
          $message = '欢迎' . $data->message . '加入了聊天室';
          $response = array(
            'type' => 1,  // 1代表系统消息,2代表用户聊天
            'message' => $message
          );
          break;
        case 'chat':
        case 'CHAT':
          $message = $data->message;
          $response = array(
            'type' => 2,  // 1代表系统消息,2代表用户聊天
            'username' => $this->users[$frame->fd],
            'message' => $message
          );
          break;
        default:
          return false;
      }
        
       // 将信息交给task处理
      $this->server->task($response);
    }

    public function onTask($server, $task_id, $from_id, $message)
    {
       // 迭代所有的客户端链接,将消息推送过去。(如果你尝试将 $this->server->connections 打印出来,那么你会发现他是空的。但当时用 foreach 去循环时,它确实有用。)
      foreach ($this->server->connections as $fd) {
        $this->server->push($fd, json_encode($message));
      }
      $server->finish( 'Task' . $task_id . 'Finished' . PHP_EOL);
    }

最后,当客户端断开链接时,利用锁机制,同步删除客户端信息,并记录日志。

public function onClose($server, $fd)
    {
      $username = $this->users[$fd];
      // 释放客户端,利用锁进行同步
      $this->lock->lock();
      unset($this->users[$fd]);
      $this->lock->unlock();

      if( $username ) {
        $response = array(
          'type' => 1,  // 1代表系统消息,2代表用户聊天
          'message' => $username . '离开了聊天室'
        );
        $this->server->task($response);
      }

      write_log( $fd . ' disconnected');
    }

服务端完了,下面就是客户端,很简单,只需要用websocket链接就ok!

// websocket
    let address = 'ws://<?php echo CLIENT_CONNECT_ADDR . ':' . CLIENT_CONNECT_PORT ?>';
    let webSocket = new WebSocket(address);
    webSocket.onerror = function (event) {
      alert('服务器连接错误,请稍后重试');
    };
    webSocket.onopen = function (event) {
      if(!sessionStorage.getItem('username')) {
        setName();
      }else {
        username = sessionStorage.getItem('username')
        webSocket.send(JSON.stringify({
          'message': username,
          'type': 'init'
        }));
      }
    };
    webSocket.onmessage = function (event) {
      console.log(event);
      let data = JSON.parse(event.data);
      if (data.type == 1) {
        $('#chat-list2').append('<li class="ui-border-tb"><span class="username">系统消息:</span><span class="message">' + data.message + '</span></li>');
      } else if (data.type == 2) {
        $('#chat-list2').append('<li class="ui-border-tb"><span class="username">' + data.username + ':</span><span class="message">' + data.message + '</span></li>');
      }

    };
    webSocket.onclose = function (event) {
      alert('散了吧,服务器都关了');
    };

详细代码可以去我的github下载

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

(0)

相关推荐

  • JavaEE7+Websockets+GlassFish4打造聊天室

    在客户机和服务器之间建立单一的双向连接,这就意味着客户只需要发送一个请求到服务端,那么服务端则会进行处理,处理好后则将其返回给客户端,客户端则可以在等待这个时间继续去做其他工作,整个过程是异步的.在本系列教程中,将指导用户如何在JAVA EE 7的容器GlassFish 4中,使用JAVA EE 7中的全新的解析Json API(JSR-353),以及综合运用jQuery和Bootstrap.本文要求读者有一定的HTML 5 Websocket的基础原理知识. 效果图 我们先来看下在完成这个教程

  • golang基于websocket实现的简易聊天室程序

    本文实例讲述了golang基于websocket实现的简易聊天室.分享给大家供大家参考,具体如下: 先说点无关的,最近忙于工作没有更新博客,今天休息顺便把golang websocket研究了一下,挺好玩的,写了一个聊天室,分享给大家. websocket包 : code.google.com/p/go.net/websocket 文档 : http://go.pkgdoc.org/code.google.com/p/go.net/websocket 首先安装websocket包 复制代码 代码

  • php基于websocket搭建简易聊天室实践

    本文实例讲述了php基于websocket搭建简易聊天室实践.分享给大家供大家参考.具体如下: 1.前言 公司游戏里面有个简单的聊天室,了解了之后才知道是node+websocket做的,想想php也来做个简单的聊天室.于是搜集各种资料看文档.找实例自己也写了个简单的聊天室. http连接分为短连接和长连接.短连接一般可以用ajax实现,长连接就是websocket.短连接实现起来比较简单,但是太过于消耗资源.websocket高效不过兼容存在点问题.websocket是html5的资源 2.前

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

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

  • Node.js websocket使用socket.io库实现实时聊天室

    认识websocket WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信(full-duple).一开始的握手需要借助HTTP请求完成. 其实websocket 并不是很依赖Http协议,它也拥有自己的一套协议机制,但在这里我们需要利用的socket.io 需要依赖到http . 之前用java jsp写过一个聊天,其实实现逻辑并不难,只是大部分时间都用在UI的设计上,其实现原理就是一个基于websocket的通信,要想做一个好的聊天室,我觉得大部

  • express框架实现基于Websocket建立的简易聊天室

    最近想写点有意思的,所以整了个这个简单的不太美观的小玩意 首先你得确认你的电脑装了node,然后就可以按照步骤 搞事情了~~ 1.建立一个文件夹 2.清空当前文件夹地址栏,在文件夹地址栏中输入cmd.exe 3.我们需要下载点小东西 ,需要在命令行输入 npm install express 回车 等待一会 npm install express-session 回车 等待一会 npm install ejs 回车 等待一会 npm install socket.io 回车 等待一会 叮~~~

  • 使用Java和WebSocket实现网页聊天室实例代码

    在没介绍正文之前,先给大家介绍下websocket的背景和原理: 背景 在浏览器中通过http仅能实现单向的通信,comet可以一定程度上模拟双向通信,但效率较低,并需要服务器有较好的支持; flash中的socket和xmlsocket可以实现真正的双向通信,通过 flex ajax bridge,可以在javascript中使用这两项功能. 可以预见,如果websocket一旦在浏览器中得到实现,将会替代上面两项技术,得到广泛的使用.面对这种状况,HTML5定义了WebSocket协议,能更

  • php+html5基于websocket实现聊天室的方法

    本文实例讲述了php+html5基于websocket实现聊天室的方法.分享给大家供大家参考.具体如下: html5的websocket 实现了双向通信,折腾了几天弄了个聊天室,分享给大家 <?php error_reporting(E_ALL); ob_implicit_flush(); $sk=new Sock('127.0.0.1',8000); $sk->run(); class Sock{ public $sockets; public $users; public $master;

  • 基于Tomcat7、Java、WebSocket的服务器推送聊天室实例

    前言 HTML5 WebSocket实现了服务器与浏览器的双向通讯,双向通讯使服务器消息推送开发更加简单,最常见的就是即时通讯和对信息实时性要求比较高的应用.以前的服务器消息推送大部分采用的都是"轮询"和"长连接"技术,这两中技术都会对服务器产生相当大的开销,而且实时性不是特别高.WebSocket技术对只会产生很小的开销,并且实时性特别高.下面就开始讲解如何利用WebSocket技术开发聊天室.在这个实例中,采用的是Tomcat7服务器,每个服务器对于WebSoc

  • 用java WebSocket做一个聊天室

    最近一个项目中,需要用到Java的websocket新特性,于是就学了一下,感觉这技术还挺好玩的,瞬间知道网页上面的那些在线客服是怎么做的了. 先看图: 实现了多客户机进行实时通讯. 下面看代码项目结构图:很简单,就1个类,1个页面 然后看具体代码 先看后端代码 package com.main; import java.io.IOException; import java.util.concurrent.CopyOnWriteArraySet; import javax.websocket.

随机推荐