Nicksxs's Blog

What hurts more, the pain of hard work or the pain of regret?

0%

# swoole-websocket-test

发表于 2016-07-13 更新于 2020-01-12 分类于 php 阅读次数： 阅读次数： Disqus：

### 玩一下swoole的websocket

WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455，WebSocketAPI被W3C定为标准。
,在web私信，im等应用较多。背景和优缺点可以参看wiki。

### 环境准备

因为swoole官方还不支持windows，所以需要装下linux,之前都是用ubuntu，
这次就试一下centos7，还是满好看的，虽然虚拟机会默认最小安装，需要在安装
时自己选择带gnome的，当然最小安装也是可以的，只是最后需要改下防火墙。
然后是装下PHP，Nginx什么的，我是用Oneinstack，可以按需安装
给做这个的大大点个赞。

## swoole

1.install via pecl

    pecl install swoole

2.install from source

    sudo apt-get install php5-dev
    git clone https://github.com/swoole/swoole-src.git
    cd swoole-src
    phpize
    ./configure
    make && make install

3.add extension

    extension = swoole.so

4.test extension

    php -m | grep swoole

如果存在就代表安装成功啦

## Exec

实现代码看了这位仁兄的代码

还是贴一下代码
服务端：

    //创建websocket服务器对象，监听0.0.0.0:9502端口
    $ws = new swoole_websocket_server("0.0.0.0", 9502);

    //监听WebSocket连接打开事件
    $ws->on('open', function ($ws, $request) {
        $fd[] = $request->fd;
        $GLOBALS['fd'][] = $fd;
        //区别下当前用户
        $ws->push($request->fd, "hello user{$request->fd}, welcome\n");
    });

    //监听WebSocket消息事件
    $ws->on('message', function ($ws, $frame) {
        $msg =  'from'.$frame->fd.":{$frame->data}\n";

        foreach($GLOBALS['fd'] as $aa){
            foreach($aa as $i){
                if($i != $frame->fd) {
                    # code...
                    $ws->push($i,$msg);
                }
            }
        }
    });

    //监听WebSocket连接关闭事件
    $ws->on('close', function ($ws, $fd) {
        echo "client-{$fd} is closed\n";
    });

    $ws->start();

客户端：

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div id="msg"></div>
    <input type="text" id="text">
    <input type="submit" value="发送数据" onclick="song()">
    </body>
    <script>
        var msg = document.getElementById("msg");
        var wsServer = 'ws://0.0.0.0:9502';
        //调用websocket对象建立连接：
        //参数：ws/wss(加密)：//ip:port （字符串）
        var websocket = new WebSocket(wsServer);
        //onopen监听连接打开
        websocket.onopen = function (evt) {
            //websocket.readyState 属性：
            /*
            CONNECTING    0    The connection is not yet open.
            OPEN    1    The connection is open and ready to communicate.
            CLOSING    2    The connection is in the process of closing.
            CLOSED    3    The connection is closed or couldn't be opened.
            */
            msg.innerHTML = websocket.readyState;
        };

        function song(){
            var text = document.getElementById('text').value;
            document.getElementById('text').value = '';
            //向服务器发送数据
            websocket.send(text);
        }
          //监听连接关闭
    //    websocket.onclose = function (evt) {
    //        console.log("Disconnected");
    //    };

        //onmessage 监听服务器数据推送
        websocket.onmessage = function (evt) {
            msg.innerHTML += evt.data +'<br>';
    //        console.log('Retrieved data from server: ' + evt.data);
        };
    //监听连接错误信息
    //    websocket.onerror = function (evt, e) {
    //        console.log('Error occured: ' + evt.data);
    //    };

    </script>
    </html>

做了个循环，将当前用户的消息发送给同时在线的其他用户，比较简陋，如下图
user1: