一、这里引用别人的教程,不过再完善了下那个细节,原教程 没有说明遇到的一些错误跟要注意的地方,这里补充下。
https://blog.csdn.net/blog_phpxz/article/details/80325802 (安装swoole)
https://blog.csdn.net/qq_28602957/article/details/53523240 (教程 )
或者,
https://github.com/diligentyang/danmu (资源下载)
二、如果顺利,以上教程是没问题的,不过有些细节如下:
1、如果报错,那是你的php文件运行不对(如图)
2、查看了下nginx的错误日志:如下:
意思是说swoole要在php_cli下运行(因为项目有个PHP文件,里面有一行php代码是new 一个swoole服务连接)。如下图:
3、解决办法:不能在浏览器输入php文件去运行,
a、先把那个php文件修改权限,改成可执行,linux命令 chmod,也可以用FileZilla Client连接服务器直接右键改
b、在linux下,直接用命令:php 空格 你的这个PHP文件所放的路径,再按回车,就可以了。
c、如果想在后台一直不间断运行:
nohup php ws_server.php > log.txt & (将php ws_server.php放到后台运行,输出的内容保存在log.txt文件中)
附:
查看php是否加载的模块
php -m | grep swoole
三、如果在阿里云上,服务端运行了,客户端没法连接,大多是端口没开放
解决办法:
1、开放阿里云端口
登陆控制台,点要开放端口的实例ECS(开放端口是一个一个实例的,如果你有多个实例,想开放哪个的端口,就要单独开,不能直接点下面的【安全组】)
2、在LINUX中,用命令开放端口
iptables -I INPUT -p tcp -m tcp --dport 端口号 -j ACCEPT
# 查看规则是否生效
iptables -L -n
然后就可以连接了
四、如果使用HTTPS,客户端要改用wss://域名/wss(http是用ws://ip:端口),服务端PHP文件,服务器配置如下
nginx配置:nginx代理WSS只需添加红色部分即可,其它的都是监听80转443的HTTPS配置。
要注意,下面蓝色的ssl_session_timeout 和 proxy_read_timeout配置,这里要根据自己的项目设置,端口号也要根据上面开放的设置,这里用9005
server {
listen 80;
server_name 域名;
rewrite ^(.*)$ https://${server_name}$1 permanent;
}
server
{
listen 443;
#listen [::]:80 default_server ipv6only=on;
server_name 域名;
root 项目目录;
index index.php index.html index.htm;
ssl_certificate 证书路径;
ssl_certificate_key 证书路径;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location /wss {
proxy_pass http://127.0.0.1:9505;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 3600s;
#proxy_read_timeout 3600s这个是设置端口保持多久断开,除了设置这个,前端在超时时间内发心跳包,刷新再读时间,这样才能跟服务器保持长连接。
}
location / {
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?s=$1 last;
#rewrite ^/index.php/(.*)$ /index.php?s=$1 last;
break;
}
}
#error_page 404 /404.html;
# Deny access to PHP files in specific directory
#location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }
#include proxy-pass-php.conf;
location /nginx_status
{
stub_status on;
access_log off;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 12h;
}
location ~ /.well-known {
allow all;
}
location ~ /\.
{
deny all;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ \.php$ {
#root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
access_log /home/www/项目名access.log;
error_log /home/www/项目名error_log.log;
}
服务端PHP文件
<?php
//创建websocket服务器对象,监听0.0.0.0:9505端口
$ws = new swoole_websocket_server("0.0.0.0", 9505);
//监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) {
//var_dump($request->fd, $request->get, $request->server);
//相当于记录一个日志吧,有连接时间和连接ip
echo $request->fd.'-----time:'.date("Y-m-d H:i:s",$request->server['request_time']).'--IP--'.$request->server['remote_addr'].'-----';
});
//监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
//记录收到的消息,可以写到日志文件中
echo "Message: {$frame->data}"."}"."\n";
//遍历所有连接,循环广播
foreach($ws->connections as $fd){
//如果是某个客户端,自己发的则加上isnew属性,否则不加
if($frame->fd == $fd){
$ws->push($frame->fd, $frame->data.',"isnew":""');
}else{
$ws->push($fd, "{$frame->data}");
}
}
});
//监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
echo "client-{$fd} is closed\n";
});
$ws->start();