天天看點

用swoole擴充編寫WebSocket聊天室

最近正在接觸swoole擴充 先寫個簡單的swoole聊天室demo吧

<!DOCTYPE html>
<html>
<head>
  <title>swoole chatroom</title>
  <meta charset="UTF-8">
  <script type="text/javascript">
   var exampleSocket = new WebSocket("ws://0.0.0.0:9501");
   exampleSocket.onopen = function (event) {
    exampleSocket.send("連接配接!"); 
   };
   exampleSocket.onmessage = function (event) {
    var chat_room = document.querySelector("#chatroom");
    var data = event.data;
    var chat_list = document.createElement("li");
    var chat_content = document.createTextNode(data);
    chat_list.appendChild(chat_content);
    chat_room.appendChild(chat_list);   
   }
  </script>
</head>
<body>
 <input type="text" id="content">
 <button οnclick="exampleSocket.send( document.getElementById('content').value )">發送</button>
 <div id="chatroom">
  <ul id="chatlist">
  </ul>
 </div>
</body>
</html>
           

用的是連接配接方式是WebSocket

使用将onopen綁定到WebSocket事件原因是因為建立WebSocket的方式是異步的,是以要在其成功建立對象時确定連接配接是否成功

onmessage是接受消息時觸發的方法

<?php

$server = new swoole_websocket_server("0.0.0.0", 9501);
$max = 0;

$server->on('open', function (swoole_websocket_server $server, $req) {
    //每一次用戶端連接配接 最大連接配接數将增加
    global $max;
    $max++;
});

$server->on('message', function (swoole_websocket_server $server, $frame) {
    $fd   = $frame->fd;
    $data = $frame->data;
    $message = "連接配接号{$fd}:内容:{$data}";
    global $max;
    //向所有人廣播
    for ($i = 1; $i <= $max; $i++) {
        echo PHP_EOL . time('Y-m-d h:m:s') . ': ' . $fd . " : " . $data;
        $server->push($i, $message);
    }
});

$server->on('close', function (swoole_websocket_server $server, $fd) {
    //關閉連接配接 連接配接減少
    global $max;
    $max--;
    echo "client {$fd} closed\n";
});

$server->start();
           

服務端的原理:

全局變量$max存儲連接配接數,每當發生一個WebSocket連接配接時,$max加一

取得連接配接後,用push向所有連接配接進行廣播

關閉連接配接時,連接配接數減少

然而這仍然存在一些問題 比如當浏覽器重新整理的時候 沒有close掉舊的連接配接 而是又建立了一個新的連接配接

這些在該demo裡都沒有得到處理