简单的聊天室代码php+swoole
php swoole+websocket
客户端代码
备注: 测试发现在docker容器内启动php服务9502,不需要经过nginx配置来连接,直接在容器设置端口,用前端指向到PHP端口访问。
<!DOCTYPE html> <html> <head> <title></title> <meta name="viewport" content="width=device-width,initial-scale=1"> <meta charset="utf-8"/> <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.4/css/bootstrap.min.css"> <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.4/css/bootstrap-theme.min.css"> <script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script> <script src="http://cdn.bootcss.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> <script src="http://cdn.bootcss.com/socket.io/1.3.5/socket.io.js"></script> </head> <body> <div id="box" style="max-width:700px;margin:0 auto;"> <div class="panel panel-default"> <div class="panel-heading"><h2>聊天室</h2><span style="color:green;display:none;">(当前在线:<span id="length">0</span>人)</span></div> <div class="panel-body" id="body" style="height:400px;overflow-y:auto;"> </div> </div> <div class="input-group"> <input type="text" class="form-control" id="in" placeholder="您想说什么?" aria-describedby="basic-addon2"> <span class="input-group-addon" id="basic-addon2" style="cursor:pointer;">发送</span> </div> </div> <div class="modal fade bs-example-modal-sm" data-backdrop="static" id="model" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true"> <div class="modal-dialog modal-sm"> <div class="modal-content"> <div class="input-group"> <input type="text" class="form-control" id="name" placeholder="请输入您的昵称" aria-describedby="basic-addon3"> <span class="input-group-addon" id="basic-addon3" style="cursor:pointer;">开始聊天</span> </div> </div> </div> </div> </body> <script> $(document).ready(function(){ window.username = 'others'; var wsServer = 'ws://192.168.151.125:9502'; var websocket = new WebSocket(wsServer); websocket.onopen = function (evt) { console.log("Connected to WebSocket server."); $("#model").modal('show'); }; websocket.onmessage = function (evt) { console.log('Retrieved data from server: ' + evt.data); $(".panel-body").append(evt.data); //$(".panel-body").append('<p><span style="color:#177bbb">'+evt.data.username+'</span> <span style="color:#aaaaaa">('+evt.data.time+')</span>: '+evt.data.msg+'</p>'); var body = document.getElementById("body"); body.scrollTop = body.scrollHeight; $("#in").focus(); }; $("#basic-addon2").click(function(){ var msg = $("#in").val(); websocket.send(msg); $("#in").val(''); }); $("#basic-addon3").click(function(){ window.username = $("#name").val(); websocket.send("login|@|"+window.username); $("#model").modal('hide'); }); }); </script> </html>
php代码
安装
swoole扩展(php官方已经支持)
可直接安装
linux执行
pecl install swoole
成功后查看phpinfo是否安装成功swoole
服务端代码
date_default_timezone_set('PRC'); $users = array(); //创建websocket服务器对象,监听0.0.0.0:9502端口 $ws = new swoole_websocket_server("0.0.0.0", 9502); $ws->set(array( 'worker_num' => 1, )); //监听WebSocket连接打开事件 $ws->on('open', function ($ws, $request) { // var_dump($request->fd, $request->get, $request->server); //global $users; // var_dump($users); // $users[] = $request->fd; //var_dump($users); //$ws->push($request->fd, "hello, welcome\n"); }); //监听WebSocket消息事件 $ws->on('message', function ($ws, $frame) { global $users; // var_dump($frame); $data = $frame->data; $arr = explode('n|@|',$data); if(count($arr)>1){ $users[$frame->fd] = $arr[1]; foreach($users as $fd=>$name){ $ws->push($fd,'<p><span style="color:#177bbb">系统通知</span><span style="color:#aaaaaa">('.date('H:i:s').')</span>:'.$arr[1].'加入聊天</p>'); } }else{ // var_dump($users); foreach($users as $fd=>$name){ //$msg = 'from'.$name.":{$frame->data}\n"; $msg = '<p><span style="color:#177bbb">'.$users[$frame->fd].'</span> <span style="color:#aaaaaa">('.date('H:i:s').')</span>: '.$frame->data.'</p>'; $ws->push($fd,$msg); } } }); //监听WebSocket连接关闭事件 $ws->on('close', function ($ws, $fd) { echo "client-{$fd} is closed\n"; }); $ws->start();
简单的聊天室就ok了
Nginx配置
1./etc/nginx/nginx.conf
user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; map $http_upgrade $connection_upgrade { default upgrade; '' close; } include /etc/nginx/conf.d/*.conf; }
2./etc/nginx/conf.d/default.conf
server { listen 80; listen [::]:80; server_name t.17379.com; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html/Swoole-Webchat; index index.html index.htm; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # location ~ \.php$ { root html; fastcgi_pass 172.17.0.2:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/share/nginx/www/Swoole-Webchat$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; include fastcgi_params; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } upstream sre_backend { hash $remote_addr consistent; server 172.17.0.2:9502; } server { listen 443 ssl; server_name t1.17379.com; access_log /var/log/nginx/sre.ayunw.cn.access.log main; error_log /var/log/nginx/sre.ayunw.cn.error.log error; ssl_certificate /data/certs/nginx/t1.17379.com.crt; ssl_certificate_key /data/certs/nginx/t1.17379.com.key; ssl_session_timeout 5m; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { proxy_pass http://sre_backend; proxy_ssl_server_name on; #include proxy.conf; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "$connection_upgrade"; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }