// 标记是全局启动
define('GLOBAL_START', 1); require_once __DIR__ . '/Workerman/Connection.php';
require_once __DIR__ . '/Workerman/Autoloader.php'; use Workerman\Worker;
use Workerman\Lib\Timer; // 心跳间隔25秒
define('HEARTBEAT_TIME', 25); // 设置时区
date_default_timezone_set('PRC'); // 以websocket协议为例
// Create a Websocket server
$ws = new Worker("websocket://118.xxx.xxx.xx:4980"); // 启动4个进程对外提供服务
$ws->count = 4; // 已连接客户端 ,便于统计在线用户
$ws->hasConnections = array(); // 当新客户端连上来时分配uid,并保存连接,并通知所有客户端
$ws->onConnect = function($connection)
{
global $ws;
// 为这个链接分配一个uid
$connection->uid = ++$global_uid; foreach ($ws->connections as $conn) {
$conn->send("用户{$connection->uid} 已上线");
}
$connection->close(); // 关闭socket连接
// echo "New connection\n";
}; // 当客户端发送消息过来时,转发给所有人 (聊天主要使用的功能)
$ws->onMessage = function($connection, $message)
{
global $ws,$db;
$data = json_decode($message, true); $data['time'] = date('Y-m-d H:i:s');
$insert = array(
'uid' =>$data['uid'],
'avatar' =>$data['avatar'],
'name' =>$data['name'],
'type' =>$data['type'],
'content' =>$data['content'],
'img_path' =>$data['img_path'],
'voice_path' =>$data['voice_path'],
'topic_id' =>$data['topic_id'],
'is_question' =>$data['is_question'],
'status' =>$data['status'],
'time' =>$data['time']
); switch ($data['type']) {
case 'save':
// 把房间和用户信息保存下来
$ws->hasConnections[$connection->id] = array('name' => $data['name'], 'uid' => $data['uid'], 'topic_id' => $data['topic_id'], 'avatar' => $data['avatar']);
sendMessage($data, $data['topic_id']);
// $back_data = array('content' => $content, 'client_id' => $connection->id, 'client_name' => $data['name'], 'type' => 'login', 'clients' => $ws->hasConnections, 'time' => date('Y-m-d H:i:s')); break; case 'text':
sendMessage($data, $data['topic_id']);
$insert_id = $db->insert('chat_record')->cols($insert)->query(); // 存数据库 save data
break; case 'img':
sendMessage($data, $data['topic_id']);
$insert_id = $db->insert('chat_record')->cols($insert)->query(); // 存数据库 save data
break; case 'voice':
sendMessage($data, $data['topic_id']);
$insert_id = $db->insert('chat_record')->cols($insert)->query(); // 存数据库 save data
break;
default:
break;
} // $connection->close(); // 关闭socket连接
}; // 当客户端断开时,广播给所有客户端
// $ws->onClose = function($connection)
// {
// global $ws;
// foreach ($ws->connections as $conn) {
// $conn->send("用户[{$connection->uid}] 消消走了");
// }
// $connection->close(); // 关闭socket连接
// }; // 给房间的每个人发消息
function sendMessage($data, $topic_id){
global $ws;
$data = json_encode($data);
foreach ($ws->connections as $id => $conn) {
if ($ws->hasConnections[$id]['topic_id'] == $topic_id) {
$conn->send($data);
// $conn->send($ws->hasConnections[$id]);
}
}
} // 进程启动后设置一个每秒运行一次的定时器(心跳, 保持长连接)
$ws->onWorkerStart = function($ws) {
global $db;
// ip, 端口号, 账号, 密码, 库名
$db = new \Workerman\MySQL\Connection('127.0.0.1', '3306', 'username', 'password', 'database'); Timer::add(1, function()use($ws){
// global $ws;
$arr = array('type'=>'keep','content'=>'ping');
$arr = json_encode($arr);
foreach($ws->connections as $connection) {
$connection->send($arr);
}
});
}; // Run worker
Worker::runAll();

Workerman创建聊天室实例的更多相关文章

  1. SignalR 聊天室实例详解(服务器端推送版)

    翻译自:http://www.codeproject.com/Articles/562023/Asp-Net-SignalR-Chat-Room  (在这里可以下载到实例的源码) Asp.Net Si ...

  2. laravel整合workerman做聊天室

    测试工具  http://www.blue-zero.com/WebSocket/ 2018年8月6日17:28:24 <?php namespace App\Console\Commands; ...

  3. Java NIO 聊天室实例

    最近写了个Java NIO聊天室聊天的程序,NIO学习起来比较困难的,我的代码能给大家起到一个抛砖引玉的作用! 服务端: package test.javanio; /** * @author * @ ...

  4. workerman搭建聊天室

    首先,先打开官网手册   http://doc.workerman.net/ 根据手册里安装里的提示,完成环境检测,和安装对应的扩展,并把对应的WorkerMan代码包下载解压至根目录 在根目录下创建 ...

  5. 使用signalR创建聊天室。

    浏览器支持Html5的情况下,SignalR使用WebSockets,当不支持时SignalR将使用其它技术来实现通讯. 界面如下:左侧包含三种聊天对象,不同的聊天对象会创建不同的对话框. 设计思路参 ...

  6. 史上最全面的SignalR系列教程-6、SignalR 实现聊天室

    1.概述 通过前面几篇文章对SignalR的详细介绍.我们知道Asp.net SignalR是微软为实现实时通信的一个类库.一般情况下,SignalR会使用JavaScript的长轮询(long po ...

  7. electron聊天室|vue+electron-vue仿微信客户端|electron桌面聊天

    一.项目概况 基于Electron+vue+electron-vue+vuex+Nodejs+vueVideoPlayer+electron-builder等技术仿制微信电脑端界面聊天室实例,实现消息 ...

  8. 用SignalR 2.0开发客服系统[系列2:实现聊天室]

    前言 交流群:195866844 上周发表了 用SignalR 2.0开发客服系统[系列1:实现群发通讯] 这篇文章,得到了很多帮助和鼓励,小弟在此真心的感谢大家的支持.. 这周继续系列2,实现聊天室 ...

  9. [Asp.net 开发系列之SignalR篇]专题三:使用SignalR实现聊天室的功能

    一.引言 在前一篇文章中,我向大家介绍了如何实现实现端对端聊天的功能的,在这一篇文章中将像大家如何使用SignalR实现群聊这样的功能. 二.实现思路 要想实现群聊的功能,首先我们需要创建一个房间,然 ...

随机推荐

  1. Android中的透明度

    最近在实践中,在一个设置了背景图的LinearLayout中放一个透明度15%,背景色为#ffffff的容器,里面再放白色#ffffff的文本,开始容器用background="#fffff ...

  2. 基础总结(03)-- css有趣的特性

    1.currentColor:可用于background/border-color/渐变/box-shadow/svg填充色,颜色继承自color. 待补充…

  3. 基础总结(01)--css清除浮动几种方法

    1.父元素添加overflow:auto/hidden; 2.父元素内加空div,添加样式clear:both; 3.父元素添加伪类; .parent:after{ content:''; displ ...

  4. Vue 表格里的下拉列表

    下拉列表column-select.vue组件内容: <template> <div class="column-select-wrapper"> < ...

  5. TestLink环境搭建及用例导入

    以下是笔者亲身实践,精心挑选出来的比较好的博文: CentOS7下TestLink环境的部署 https://blog.csdn.net/fxsok244969309/article/details/ ...

  6. PLSQL安装教程,无需oracle客户端(解决本地需要安装oracle客户端的烦恼)

    最近用笔记本开发,项目用的是Oracle数据库,不想本地安装Oracle客户端. 就只装了一个PLSQL 连接数据库的时候各种错误,现在解决了记录一下. 详细内容见  附件

  7. 什么是pyc文件,Python

    pyc文件就是 Python 程序编译后得到的字节码文件 (py->pyc).pyc文件一般由3个部分组成:最开始4个字节是一个Maigc int, 标识此pyc的版本信息, 不同的版本的 Ma ...

  8. dojo里添加目录树

    其实循环生成目录树这个方法不仅仅局限于在使用dojo的情况下,只要明白了其中的原理,在任何一种语言下都能动态循环生成. 1. 数据结构 在这里先说明一下数据结构,我这里循环生成目录树的数据结构是像这样 ...

  9. [CSS3]环形进度条

    来源:https://codepen.io/eZ0/pen/eZXNzd 点击上面链接有源码有示例. .ko-progress-circle { width: 120px; height: 120px ...

  10. FI-盘盈盘亏借贷科目

    资产的盘盈盘亏一般分两步:第一步,批准前调整为账实相符:第二步,批准后结转处理.库存现金.存货.固定资产.工程物资的盘盈盘亏的账务处理见下图: 以上科目中可能并不完整,比如“原材料等科目”就可能包括“ ...