一、這裏引用別人的教程,不過再完善了下那個細節,原教程 沒有說明遇到的一些錯誤跟要注意的地方,這裏補充下。
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();