前言

PHP本身自带的socket套接字连接一直都是尴尬的存在...从create到bind到listen再到accept一切连接所需要做的事情都得你有亲手去解决,这可是工作量极其繁重的事情,且必须是对各协议的通信过程了解的情况下才能入手,但是如果你拥有了swoole这PHP异步、并行、高性能网络通信引擎的话就一切将会变的更加容易!

以下是我利用swoole轻松构建websocket服务器,以实现一个在线即时聊天室的DEMO.

为什么选择websocket

什么是websocket?这里就不一一细述,想了解的同学可以自行百科,通俗的来讲就是html5新出的通信协议,可以实现browser与server之间的双向通讯。

接下来说说为什么要选择他,相信大家都只要如果在web实现聊天室的功能通常的做法就是利用ajax长轮询定时发起http请求至服务器取得最新数据,这种方式虽然简单但是有很多的缺点,如果只是构造一个10人不等的聊天室肯定不成为问题,但是如果当100人1000人同时发起大量http请求时,这就大大增加了性能消耗,严重浪费服务器资源,为了解决此问题,websocket因此诞生。

CODE

Server


//构造一个websocket服务器
$serv = new swoole_websocket_server('0.0.0.0',9501);
//定义连接事件
$serv->on('open',function(swoole_websocket_server $serv,$request){
    echo '客户 '.$request->fd.' 连接服务器'.PHP_EOL;
}
);
//定义消息事件
$serv->on('message',function(swoole_websocket_server $serv,$request){
    //构造一个memcache对象并连接
    $mem = new Memcached();
    $mem->addServer('127.0.0.1',11211);
    if(($data = json_decode($request->data,true))['action'] == 'add'){
        $mem->set($request->fd,$data['data']);
    } else{
        echo '来自 '.$mem->get($request->fd).' 的信息: '.$request->data.PHP_EOL;
        //取出所有已连接服务器的FD列表
        $clientList = $serv->connection_list();
        //遍历fd列表,单独最每个fd发送message
        foreach ($clientList as $fd) {
            $serv->push($fd,$mem->get($request->fd).':'.$request->data);
        }
    }
}
);
//定义关闭事件
$serv->on('close',function(swoole_websocket_server $serv,$fd){
    $mem = new Memcached();
    $mem->addServer('127.0.0.1',11211);
    foreach ($serv->connection_list() as $fd) {
        $serv->push($fd,$mem->get($request->fd).' 离开房间.');
    }
}
);
$serv->start();

client


    var uname;
    var ws;
    ws = new WebSocket("ws://ubuntu.otokaze.cn:9501");
    ws.onopen = function() {
        if (!$.cookie('uname')) {
            uname = (uname = prompt('君の名前は?')) ? uname: '名無し';
            $.cookie('uname', uname);
            ws.send(JSON.stringify({
               'action': 'add',
                'data': uname
            }));
        }
    };
    ws.onmessage = function(evt) {
        $('#box').html($('#box').html() + evt.data + "
"); };

效果图


一介布衣