<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ## SocketIO消息推送 PHP系列 | PHP跨平臺實時通訊框架 Socket.IO 的應用 ## PHPSocket.IO 是什么? 1. PHPSocket.IO是PHP版本的Socket.IO服務端實現,基于workerman開發,用于替換node.js版本Socket.IO服務端。 2. PHPSocket.IO底層采用websocket協議通訊,如果客戶端不支持websocket協議, 則會自動采用http長輪詢的方式通訊。 3. PHPSocket.IO實現的Polling通信機制包括Adobe Flash Socket、AJAX長輪詢、JSONP輪詢等。具體采用哪種機制通訊對于開發者完全透明, 開發者使用的是統一的接口。 ## 設計的目標 利用PHP構建能夠在不同瀏覽器和移動設備上良好運行的實時應用,如實時分析系統、在線聊天室、在線客服系統、評論系統、WebIM等。 PHPSocket.IO與workerman的區別是,PHPSocket.IO基于workerman開發,workerman有的特性PHPSocket.IO都支持。 PHPSocket.IO最大的優勢是對各種瀏覽器的兼容性更好。 ## 文檔&&安裝 文檔倉庫:[https://github.com/walkor/phpsocket.io](https://github.com/walkor/phpsocket.io) 使用composer安裝 ``` composer require workerman/phpsocket.io ``` ## 應用案例 #### Nginx 主機配置 ```nginx server { listen 443 ssl http2; server_name www.tinywan.com; ssl_certificate letsencrypt/iot.tinywan.com/full_chain.pem; ssl_certificate_key letsencrypt/iot.tinywan.com/private.key; set $root_path /var/www/iot.tinywan.com/public; root $root_path; more_set_headers "X-Frame-Options: SAMEORIGIN"; location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s=/$1 last; break; } } location ~ \.php$ { fastcgi_index index.php; fastcgi_pass unix:/var/run/php-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { access_log off; error_log off; expires 30d; } location ~ .*\.(js|css)?$ { access_log off; error_log off; expires 12h; } # SocketIO 配置 location /socket.io { proxy_pass http://127.0.0.1:2120; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header X-Real-IP $remote_addr; } } ``` #### 服務端完整代碼 ```php <?php namespace app\http\controller; use PHPSocketIO\SocketIO; use think\facade\Log; use Workerman\Worker; class Server { /** * @desc: Socket Server * @time: 2019/4/22 19:51 */ public function server() { // 全局數組保存uid在線數據 $uidConnectionMap = array(); // 記錄最后一次廣播的在線用戶數 $last_online_count = 0; // 記錄最后一次廣播的在線頁面數 $last_online_page_count = 0; // PHPSocketIO服務 $sender_io = new SocketIO(2120); // 客戶端發起連接事件時,設置連接socket的各種事件回調 $sender_io->on('connection', function ($socket) { Log::info('客戶端發起連接事件 '); // 當客戶端斷開連接是觸發(一般是關閉網頁或者跳轉刷新導致) $socket->on('login', function ($uid) use ($socket) { Log::info('客戶端登錄uid ' . $uid); global $uidConnectionMap, $last_online_count, $last_online_page_count; // 已經登錄過了 if (isset($socket->uid)) { return; } // 更新對應uid的在線數據 $uid = (string)$uid; if (!isset($uidConnectionMap[$uid])) { $uidConnectionMap[$uid] = 0; } // 這個uid有++$uidConnectionMap[$uid]個socket連接 ++$uidConnectionMap[$uid]; // 將這個連接加入到uid分組,方便針對uid推送數據 $socket->join($uid); $socket->uid = $uid; }); // 當客戶端斷開連接是觸發(一般是關閉網頁或者跳轉刷新導致) $socket->on('disconnect', function () use ($socket) { Log::info('客戶端斷開 ' . json_encode($socket)); if (!isset($socket->uid)) { return; } global $uidConnectionMap, $sender_io; // 將uid的在線socket數減一 if (--$uidConnectionMap[$socket->uid] <= 0) { unset($uidConnectionMap[$socket->uid]); } }); }); // 當$sender_io啟動后監聽一個http端口,通過這個端口可以給任意uid或者所有uid推送數據 $sender_io->on('workerStart', function () use ($sender_io) { // 監聽一個http端口 $inner_http_worker = new Worker('http://0.0.0.0:2121');//這里IP不用改變,用的內網通訊,端口不能與socket端口想通 $inner_http_worker->onMessage = function ($http_connection, $data) use ($sender_io) { $postData = $data['post']; $to = $postData['to'] ?? ''; Log::info('發送到用戶to ' . json_encode($to)); $content = htmlspecialchars($postData['content']); // 有指定uid則向uid所在socket組發送數據 if ($to) { $sender_io->to($to)->emit('new_msg', $content); } else { // 否則向所有uid推送數據 $sender_io->emit('new_msg', $content); } // http接口返回,如果用戶離線socket返回fail if ($to && !isset($uidConnectionMap[$to])) { return $http_connection->send('offline'); } else { return $http_connection->send('ok'); } }; // 執行監聽 $inner_http_worker->listen(); }); Worker::runAll(); } } ``` 1、啟動服務端端:`php web_msg.php start -d` ``` $ php web_msg.php start -d Workerman[web_msg.php] start in DAEMON mode ------------------------------------------- WORKERMAN ------------------------------------------- Workerman version:3.5.20 PHP version:7.2.9 -------------------------------------------- WORKERS -------------------------------------------- proto user worker listen processes status tcp www PHPSocketIO socketIO://0.0.0.0:2120 1 [OK] ``` 2、發送消息 ``` function send_web_msg($to_uid = 1, $content) { if (empty($content)) { return ["error_code" => 404, "reason" => '缺少參數']; } $push_api_url = "http://127.0.0.1:2121/"; $post_data = [ "type" => "publish", "content" => $content, "to" => $to_uid ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $push_api_url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Expect:")); $return = curl_exec($ch); curl_close($ch); return $return; } send_web_msg(1, "哈嘍,Tinywan先生"); ``` #### 客戶端完整代碼 html 代碼 ``` <div><p id="notice-content" style="float: left">系統公告</p></div> ``` JS 代碼 ``` <script src='https://cdn.bootcss.com/socket.io/2.0.3/socket.io.js'></script> <script src="https://cdn.bootcss.com/notify.js/3.0.0/notify.js"></script> <script> $(document).ready(function () { $uid = "1"; var socket = io("https://www.tinywan.com", { path: '/socket.io' }); socket.on('connect', function () { console.log('連接成功'); socket.emit('login', $uid); }); socket.on('new_msg', function (msg) { console.log('系統消息:' + msg); $('#notice-content').html('系統提示:' + msg); $('.notification.sticky').notify(); }); }); </script> ``` ### 效果圖 ![](https://box.kancloud.cn/952198f9df16268640509a8c0f358b3f_677x70.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看