进入网站项目路径,使用git克隆
git clone “https://gitee.com/ypwl/TwoThink.git”
克隆完毕会在项目目录生成TwoThink文件夹,如果你想把twothink放在项目根目录,只需要进入TwoThink将其中文件移动出来即可。
配置apache设置网站指向twothink的public文件夹,这里就不多说了。
TwoThink开发使用可以参考TwoThink的文档
浏览器打开http://你的域名/install.php即可进行安装,安装过程不再详细描述类似OneThink;
使用composer方式安装GatewayWorker,由于twoThink基于thinkphp5.0,think-worker只能安装1.0版本的,
进图twothink项目目录,安装workerman
composer require topthink/think-worker:1.*
安装gateway
composer require workerman/gateway-worker-for-win
新建或编辑build.php
return [
// 生成应用公共文件
'__file__' => ['common.php', 'config.php', 'database.php'],
// 定义demo模块的自动生成 (按照实际定义的文件名生成)
'chat' => [
'__file__' => ['common.php'],
'__dir__' => ['behavior', 'controller', 'model', 'view'],
'controller' => ['Index', 'Events', 'Gate'],
'model' => ['User', 'UserType'],
'view' => ['index/index'],
],
// 其他更多的模块定义
];
拷贝至application目录下运行
php think build
显示Successed即为创建成功。
进入application/chat/controller目录,编辑Events控制器
$item)
{
$clients_list[$tmp_client_id] = $item['client_name'];
}
$clients_list[$client_id] = $client_name;
// 转播给当前房间的所有客户端,xx进入聊天室 message {type:login, client_id:xx, name:xx}
$new_message = array('type'=>$message_data['type'], 'client_id'=>$client_id, 'client_name'=>htmlspecialchars($client_name), 'time'=>date('Y-m-d H:i:s'));
Gateway::sendToGroup($room_id, json_encode($new_message));
Gateway::joinGroup($client_id, $room_id);
// 给当前用户发送用户列表
$new_message['client_list'] = $clients_list;
Gateway::sendToCurrentClient(json_encode($new_message));
return;
// 客户端发言 message: {type:say, to_client_id:xx, content:xx}
case 'say':
// 非法请求
if(!isset($_SESSION['room_id']))
{
throw new \Exception("\$_SESSION['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']}");
}
$room_id = $_SESSION['room_id'];
$client_name = $_SESSION['client_name'];
// 私聊
if($message_data['to_client_id'] != 'all')
{
$new_message = array(
'type'=>'say',
'from_client_id'=>$client_id,
'from_client_name' =>$client_name,
'to_client_id'=>$message_data['to_client_id'],
'content'=>"对你说: ".nl2br(htmlspecialchars($message_data['content'])),
'time'=>date('Y-m-d H:i:s'),
);
Gateway::sendToClient($message_data['to_client_id'], json_encode($new_message));
$new_message['content'] = "你对".htmlspecialchars($message_data['to_client_name'])."说: ".nl2br(htmlspecialchars($message_data['content']));
return Gateway::sendToCurrentClient(json_encode($new_message));
}
$new_message = array(
'type'=>'say',
'from_client_id'=>$client_id,
'from_client_name' =>$client_name,
'to_client_id'=>'all',
'content'=>nl2br(htmlspecialchars($message_data['content'])),
'time'=>date('Y-m-d H:i:s'),
);
return Gateway::sendToGroup($room_id ,json_encode($new_message));
}
}
/**
* 当客户端断开连接时
* @param integer $client_id 客户端id
*/
public static function onClose($client_id)
{
// debug
echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']} client_id:$client_id onClose:''\n";
// 从房间的客户端列表中删除
if(isset($_SESSION['room_id']))
{
$room_id = $_SESSION['room_id'];
$new_message = array('type'=>'logout', 'from_client_id'=>$client_id, 'from_client_name'=>$_SESSION['client_name'], 'time'=>date('Y-m-d H:i:s'));
Gateway::sendToGroup($room_id, json_encode($new_message));
}
}
}
编辑Gate控制器
name = 'ChatBusinessWorker';
// bussinessWorker进程数量
$worker->count = 4;
// 服务注册地址
$worker->registerAddress = '127.0.0.1:1236';
//设置处理业务的类,此处制定Events的命名空间
$worker->eventHandler = 'app\chat\controller\Events';
// 初始化 gateway 进程
$gateway = new Gateway("websocket://0.0.0.0:9501");
// 设置名称,方便status时查看
$gateway->name = 'ChatGateway';
$gateway->count = 4;
// 分布式部署时请设置成内网ip(非127.0.0.1)
$gateway->lanIp = '127.0.0.1';
// 内部通讯起始端口,假如$gateway->count=4,起始端口为4000
// 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口
$gateway->startPort = 2300;
// 心跳间隔
$gateway->pingInterval = 10;
// 心跳数据
$gateway->pingData = '{"type":"ping"}';
// 服务注册地址
$gateway->registerAddress = '127.0.0.1:1236';
//运行所有Worker;
Worker::runAll();
}
}
编辑入口文件 start.php,将入口文件放在public文件夹内
进入public目录使用以下命令启动
php start.php start
此处参考http://www.thinkphp.cn/code/3937.html
Apache反向代理之后可以隐藏端口号直接ws://域名
需要安装proxy和proxy_wstunnel模块
输入命令
sudo a2enmod proxy
sudo a2enmod proxy_wstunne
然后重启apache服务
service apache2 restart
编辑配置
我的apache是使用apt直接安装的,其配置文件在/etc/apache2/sites-enabled路径下,
输入nano 000-default.conf进行编辑,找到下方位置,做出如下修改。
ServerName 你的域名
DocumentRoot 项目路径/twothink/public
ServerAdmin [email protected]
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
ProxyPass / ws://localhost:9501/
ProxyPassReverse / ws://localhost:9501/
Crtl+O进行保存,crtl+x退出编辑器,重启服务器即可
参考文章https://blog.csdn.net/sunhuwh/article/details/48215831
这里以服务器开启ssl为前提。
配置ws+ssl需要ssl证书,可以自己生成也可以购买证书,将证书文件放在/etc/apache2/certs/路径下(根据个人喜好,只要配置的时候路径正确即可)
配置/etc/apache2/sites-enabled/default-ssl.conf
在对应域名配置中进行如下设置:
# Proxy Config
SSLProxyEngine on
ProxyRequests Off
ProxyPass /wss ws://127.0.0.1:9501
ProxyPassReverse /wss ws://127.0.0.1:9501
# 添加 SSL 协议支持协议,去掉不安全的协议
SSLProtocol all -SSLv2 -SSLv3
# 修改加密套件如下
SSLCipherSuite HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM
SSLHonorCipherOrder on
# 证书公钥配置
SSLCertificateFile 你的证书路径/your.pem
# 证书私钥配置
SSLCertificateKeyFile 你的证书路径/your.key
# 证书链配置,
SSLCertificateChainFile 你的证书路径/chain.pem
保存重启apache
在chrome中进行测试
// 证书是会检查域名的,请使用域名连接
ws = new WebSocket("wss://域名");
ws.onopen = function() {
alert("连接成功");
ws.send('tom');
alert("给服务端发送一个字符串:tom");
};
ws.onmessage = function(e) {
alert("收到服务端的消息:" + e.data);
};
详情参考http://doc3.workerman.net/315297