由于本文的能力有限,有好多聊天逻辑的细节没有实现,只实现了群发,具体代码如下所示:

<?php
$serv = new swoole_websocket_server("127.0.0.1", 3999);
//服务的基本设置
$serv->set(array(
    'worker_num' => 2,
    'reactor_num' => 8,
    'task_worker_num' => 1,
    'dispatch_mode' => 2,
    'debug_mode' => 1,
    'daemonize' => true,
    'log_file' => __DIR__ . '/log/webs_swoole.log',
    'heartbeat_check_interval' => 60,
    'heartbeat_idle_time' => 600,
));
$serv->on('connect', function ($serv, $fd) {
// echo "客户端:$fd 已连接.".PHP_EOL;
});
//测试receive
$serv->on("receive", function (swoole_server $serv, $fd, $from_id, $data) {
// echo "接收到消息#{$from_id}: receive $data ".PHP_EOL;
});
$serv->on('open', function ($server, $req) {
// echo "server#{$server->worker_pid}: handshake success with fd#{$req->fd}".PHP_EOL;;
// echo PHP_EOL;
});
$serv->on('message', function ($server, $frame) {
// echo "message: ".$frame->data.PHP_EOL;
    $msg = json_decode($frame->data, true);
    switch ($msg['type']) {
        case 'login':
            $server->push($frame->fd, "欢迎欢迎~");
            break;
        default:
            break;
    }
    $msg['fd'] = $frame->fd;
    $server->task($msg);
});
$serv->on("workerstart", function ($server, $workerid) {
// echo "workerstart: ".$workerid.PHP_EOL;
// echo PHP_EOL;
});
$serv->on("task", "on_task");
$serv->on("finish", function ($serv, $task_id, $data) {
    return;
});
$serv->on('close', function ($server, $fd, $from_id) {
// echo "connection close: ".$fd.PHP_EOL;
// echo PHP_EOL;
});
$serv->start();
function on_task($serv, $task_id, $from_id, $data)
{
    switch ($data['type']) {
        case 'login':
            $send_msg = "说:我来了~";
            break;
        default:
            $send_msg = "说:{$data['msg']['speak']}";
            break;
    }
    foreach ($serv->connections as $conn) {
        if ($conn != $data['fd']) {
            if (strpos($data['msg']['name'], "游客") === 0) {
                $name = $data['msg']['name'] . "_" . $data['fd'];
            } else {
                $name = $data['msg']['name'];
            }
        } else {
            $name = "我";
        }
        $serv->push($conn, $name . $send_msg);
    }
    return;
}

function on_finish($serv, $task_id, $data)
{
    return true;
}

前端代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>

    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>
            WebSocket测试
        </title>
        <script language="javascript" type="text/javascript" src="jquery-1.12.0.min.js">
        </script>
    </head>

    <body>
        <h2>
            WebSocket Test
        </h2>
        昵称:
        <input type="text" id="name" size="5" value="游客" />
        <input type="text" id="content">
        <button onclick="speak_to_all()">
            发送
        </button>
        <br/>
        <br/>
        <textarea id="message" style="overflow-x:hidden" rows="10" cols="50">
        </textarea>
        <div id="output">
        </div>
    </body>
    <script language="javascript" type="text/javascript">
        var wsUri = "ws://127.0.0.1:3999/";
        var output;
        function init() {
            output = document.getElementById("output");
            testWebSocket();
        }
        function testWebSocket() {
            websocket = new WebSocket(wsUri);
            websocket.onopen = function(evt) {
                onOpen(evt)
            };
            websocket.onclose = function(evt) {
                onClose(evt)
            };
            websocket.onmessage = function(evt) {
                onMessage(evt)
            };
            websocket.onerror = function(evt) {
                onError(evt)
            };
        }
        function get_speak_msg() {
            var name = document.getElementById("name").value;
            var speak = document.getElementById("content").value;
            var json_msg = '{"name":"' + name + '","speak":\"' + speak + '"}';
            return json_msg;
        }
        function pack_msg(type, msg) {
            return '{"type":"' + type + '","msg":' + msg + '}';
        }
        function onOpen(evt) {
            append_speak("已经联通服务器.........");
            speak_msg = get_speak_msg();
            send_msg = pack_msg("login", speak_msg);
            doSend(send_msg);
        }
        function onClose(evt) {
            append_speak("俺老孙去也!");
        }
        function onMessage(evt) {
            append_speak(evt.data);
        }
        function onError(evt) {
            alert(evt.data);
        }
        function doSend(message) {
            websocket.send(message);
        }
        function append_speak(new_msg) {
            document.getElementById("message").value = document.getElementById("message").value + new_msg + "\n";
            document.getElementById('message').scrollTop = document.getElementById('message').scrollHeight;
        }
        function speak_to_all() {
            send_msg = pack_msg("speak", get_speak_msg());
            if (document.getElementById("content").value == "") {
                return;
            }
            doSend(send_msg);
            document.getElementById("content").value = "";
        }
        init();
    </script>

</html>