首先,我想说下写代码的一些习惯,第一,任何可配置的参数或变量都要写到一个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' => ,
'worker_num' => ,
'task_worker_num' => ,
'max_request' => ,
'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代表系统消息,2代表用户聊天
'message' => $message
);
break;
case 'chat':
case 'CHAT':
$message = $data->message;
$response = array(
'type' => , // 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代表系统消息,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 == ) {
$('#chat-list2').append('<li class="ui-border-tb"><span class="username">系统消息:</span><span class="message">' + data.message + '</span></li>');
} else if (data.type == ) {
$('#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下载

用swoole和websocket开发简单聊天室的更多相关文章

  1. Java和WebSocket开发网页聊天室

    小编心语:咳咳咳,今天又是聊天室,到现在为止小编已经分享了不下两个了,这一次跟之前的又不大相同,这一次是网页聊天室,具体怎么着,还请各位看官往下看~ Java和WebSocket开发网页聊天室 一.项 ...

  2. Netty 系列八(基于 WebSocket 的简单聊天室).

    一.前言 之前写过一篇 Spring 集成 WebSocket 协议的文章 —— Spring消息之WebSocket ,所以对于 WebSocket 协议的介绍就不多说了,可以参考这篇文章.这里只做 ...

  3. Flask基于websocket的简单聊天室

    1.安装gevent-websocket pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ gevent-websocket 2.cha ...

  4. 使用go,基于martini,和websocket开发简易聊天室

    一.首先,需要了解一下websocket基本原理:here 二.go语言的websocket实现: 基于go语言的websocket也有不少,比如github.com/gorilla/websocke ...

  5. workerman-chat(PHP开发的基于Websocket协议的聊天室框架)(thinkphp也是支持socket聊天的)

    workerman-chat(PHP开发的基于Websocket协议的聊天室框架)(thinkphp也是支持socket聊天的) 一.总结 1.下面链接里面还有一个来聊的php聊天室源码可以学习 2. ...

  6. swoole中websoket创建在线聊天室(php)

    swoole中websoket创建在线聊天室(php) swoole现仅支持Linix,macos 创建websocket服务器 首先现在服务器创建一个websocket服务器 <?php // ...

  7. 分享基于 websocket 网页端聊天室

    博客地址:https://ainyi.com/67 有一个月没有写博客了,也是因为年前需求多.回家过春节的原因,现在返回北京的第二天,想想,应该也要分享技术专题的博客了!! 主题 基于 websock ...

  8. SpringBoot 搭建简单聊天室

    SpringBoot 搭建简单聊天室(queue 点对点) 1.引用 SpringBoot 搭建 WebSocket 链接 https://www.cnblogs.com/yi1036943655/p ...

  9. 基于Node.js + WebSocket 的简易聊天室

    代码地址如下:http://www.demodashi.com/demo/13282.html Node.js聊天室运行说明 Node.js的本质就是运行在服务端的JavaScript.Node.js ...

随机推荐

  1. javascript 之异常处理try catch finally--05

    语法结构 try catch finally是ECMAScript-262 第三版提供异常处理机制的标准,语法结构如下: try{ //可能会发生的错误代码 } catch(error){ //错误处 ...

  2. js获取本地ip和地区

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. win8在安装office visio2003出现“请求的操作需要提升”,解决方法

    单击右键,然后以管理员身份运行即可

  4. IntelliJ下断点不可用 No executable code found

    情景说明:ant工程+IntelliJ Idea 采取copy编译后的class文件到WEB-INF/classes目录下,断点一直不可用 如图: 网上查了很多资料都说的不够明确,IntelliJ社区 ...

  5. Angular通信$q服务和promise对象

    promise 约定(promise)是一个对象,表示在未来时间点会发生的某件事情,约定可以是三种状态之一:等待.完成或拒绝.约定将从等待状态开始,然后可以转换为完成或者拒绝状态,一旦约定完成或者被拒 ...

  6. HTTP服务简介

    第1章 HTTP服务介绍 1.1 简述用户访网站流程 a 进行域名信息的DNS解析   dig +trace 获得www.oldboyedu.com  ip地址信息 b 进行与网站服务器建立连接,tc ...

  7. zookeeper分布式搭建

    1下载并解压zookeeper安装包 2进入zookeeper配置文件目录,找到zoo_sample.cfg,执行cp zoo_sample.cfg  zoo.cfg 3打开zoo.cfg文件,修改d ...

  8. Grunt打包seajs项目

    在使用seajs时,常常将若干脚本分为多次require进来,这样开发中比较方便,但是,会增加http请求次数,在生产环境中需要进行打包合并.压缩等操作. 以Grunt构建工具为例,对一个seajs项 ...

  9. arguments对象

    改变函数arguments也会改变对应的参数,arguments会自动映射到对应的参数上 但是改变参数并不会同步改变arguments 它们并不公用内存 在strict模式,不能对arguments付 ...

  10. threejs 组成的3d管道,寻最短路径问题

    threejs 里面的3d管道的每个节点ID是唯一的,且对应x,y,z坐标.那么当需要从A点到B点的时候,可能出现有多条路径可走,此时便需要求出最短行走路径,因此用到一个寻路径算法.我们将问题简化如下 ...