swoole 搭建websocker聊天室加聊天记录

客户端html页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./jquery-3.2.1.min.js"></script>
    <script src="./jquery.qqFace.js"></script>
    <style>
        li{
            list-style: none;
        }
    </style>
</head>
<body>
    <div>
        <div class="left" style="float: left;border: 1px solid red;width: 70%;height: 600px">
            <div style="height: 450px;">
                <ul id="message">
                    <li style="text-align: right;">测试</li>
                    <li style="text-align: right;">聊天室</li>
                </ul>
            </div>
            <hr>
            <div class="com_form">
                <div style="display: none;">
                    <textarea  class="input" name="saytext" id="saytext" cols="120%" rows="5" placeholder="发送内容" style="min-height: 50px;min-width: 600px;"></textarea>
                </div>
                <select name="send_user" id=""></select><span class="emotion">表情</span><a href="javascript:;" id="history_list">查看聊天记录</a>
                <textarea  class="input"  id="content" cols="120%" rows="5" placeholder="发送内容" style="min-height: 50px;min-width: 600px;"></textarea>
                <button id="sendMessage">发送</button>
            </div>
        </div>
        <div class="right" style="float: right;border: 1px solid blue;width: 29%;height: 600px">
            <ul id="user_list">

            </ul>
            <ul id="history_msg">

            </ul>
        </div>
    </div>
</body>
</html>
<script>
    /*$('.emotion').qqFace({
        id : 'facebox', //表情盒子的ID
        assign:'saytext', //给那个控件赋值
        path:'face/',	//表情存放的路径
    });*/
    $(".emotion").click(function(){
        $(this).qqFace({
            id : 'facebox', //表情盒子的ID
            assign:'saytext', //给那个控件赋值
            path:'face/',	//表情存放的路径
        })
        var str = $("#saytext").val();
        $("#content").html(str);
    });

    var user_name = '';
    var password = '123456';

    function showprompt(){
        while( user_name == '' ){
            user_name = prompt('请输入你的用户名');
        }
        while( password == '' ){
            password = prompt('请输入你的密码');
        }
        // type = 1 标示发送的是登录的数据
        var data = '{"type":1,"user_name":"'+user_name+'","password":"'+password+'"}';

        console.log( '发送给服务端数据:'+ data );
        websocket.send( data );
        console.log(123)
    }
    $('#sendMessage').click(function(){
        sendMessage()
    })
    function sendMessage(){
        var content = $('#content').val();
        var user_id = $('[name=send_user]').val();
        console.log(user_id);
        $('#content').val('')
//    content.replace('\r\n',"<br/>");
        content=content.replace(/\r/g,"&nbsp;");
        content=content.replace(/\n/g,"<br />");
        if( user_id != -1 ){
            var json ='{"type":2,"user_name":"'+user_name+'","message":"'+content+'","send_to":'+user_id+'}';
        }else{
            var json ='{"type":2,"user_name":"'+user_name+'","message":"'+content+'","send_to":"all"}';
        }

        console.log(json);
        websocket.send(json);
    }
    $('#history_list').click(function(){
        sendHistory()
    })
    function sendHistory(){
//        var content = $('#content').val();
        var user_id = $('[name=send_user]').val();
        console.log(user_id);
//        $('#content').val('')
//    content.replace('\r\n',"<br/>");
        if( user_id != -1 ){
            var json ='{"type":3,"send_to":'+user_id+'}';
        }else{
            var json ='{"type":3,"send_to":"all"}';
        }

        console.log(json);
        websocket.send(json);
    }


    var wsServer = 'ws://127.0.0.1:9501';
    var websocket = new WebSocket(wsServer);
    websocket.onopen = function (evt) {
        console.log("连接成功");
        showprompt();
    };

    websocket.onclose = function (evt) {
        console.log("Disconnected");
    };

    websocket.onmessage = function (evt) {
//        console.log( typeof evt.data);
//        console.log( evt.data);
        var s_data = JSON.parse( evt.data);
//        console.log( s_data.type );

        if( s_data.type == 'connect' ){

        }else if( s_data.type == 'login' ){
            if(s_data.status != 1000 ){
                user_name = '';
                password = '';
                alert(s_data.msg);
                showprompt();
            }
        }else if( s_data.type == 'online' ){
            $('#message').find('li').last().after(
                    '<li>'+s_data.msg+'</li>'
            );
        }else if( s_data.type == 'online_list'){
            console.log(s_data)
            var user_list = '';
            var option_list = '<option value="-1">所有人</option>';
            for( var i in s_data ){
                console.log(s_data[i]!='online_list')
                if(s_data[i]!='online_list'){
                    user_list += '<li>'+s_data[i].user_name+'</li>';
                    option_list += '<option value="'+s_data[i].fd+'">'
                            + s_data[i].user_name+'</option>'
                }
            }
//            console.log(user_list)
//            console.log(option_list)
            $('#user_list').html( user_list );
            $('[name=send_user]').html(option_list);

        }else if( s_data.type == 'message'){

            var s_mesage = s_data.msg;
            var new1 =replace_em( s_mesage );
//            console.log(new1);
            if( s_data.isme == 1 ){
                var msg = '<li style="text-align: right;">'+new1+'</li>';
            }else{
                var msg = '<li>'+new1+'</li>';
            }
            console.log(msg)
            $('#message').find('li').last().after( msg );
        }else if(s_data.type=='his_data'){
            console.log(s_data.data)
            var his_list = '<li><hr/></li>';
            for( var i in s_data.data ){
                if(s_data.data[i].isme==1){
                    his_list += '<li style="text-align: right;">'+s_data.data[i].name+':'+s_data.data[i].message+'</li>';
                }else{
                    his_list += '<li>'+s_data.data[i].name+':'+s_data.data[i].message+'</li>';
                }
            }
            $('#history_msg').html( his_list );
        }
    };

    websocket.onerror = function (evt, e) {
        console.log('Error occured: ' + evt.data);
    };


    function replace_em(str){
//        str = str.replace(/\</g,'&lt;');
//        str = str.replace(/\>/g,'&gt;');
//        str = str.replace(/\n/g,'<br/>');
        str = str.replace(/\[em_([0-9]*)\]/g,'<img src="face/$1.gif" border="0" />');
        return str;
    }
</script>

php后端代码:

<?php
function async($data)
{
    $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
    /*$rand=range(1,100);
    shuffle($rand);
    $num=json_encode($rand);*/
//注册连接成功回调
    $client->on("connect", function($cli)use($data){
//    $cli->send("hello world\n");
        $cli->send(json_encode($data));
        $cli->close();
    });

//注册数据接收回调
    $client->on("receive", function($cli, $data){
//    $cli->send($num);
        echo "Received: ".$data."\n";
    });

//注册连接失败回调
    $client->on("error", function($cli){
        echo "Connect failed\n";
    });

//注册连接关闭回调
    $client->on("close", function($cli){
        echo "Connection close\n";
    });

//发起连接
    $client->connect('127.0.0.1', 3306, 0.5);
}
	//创建websocket服务器对象,监听0.0.0.0:9502端口
$ws = new swoole_websocket_server("0.0.0.0", 9501);
$ws->set(['task_worker_num'=>200]);
$ws->on('task',function($ws,$task_id,$form_id,$data){
    echo '异步处理';
    var_dump($data);
});
//监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) {
    var_dump($request->fd, $request->get, $request->server);
    $ws->push($request->fd, "hello, welcome\n");
});

//监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
    $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
    $redis = new Swoole\Coroutine\Redis();
    $redis->connect('127.0.0.1', 6379);
    $online_str=$redis->get('online_user');
    if(empty($online_str)){
        $online_info=[];
    }else{
        $online_info=json_decode($online_str,true);
    }
    echo "Message: {$frame->data}\n";
    $data_arr=json_decode($frame->data,true);
    //登录
    if($data_arr['type']==1){
        if(!empty($data_arr['user_name'])&&$data_arr['password']=='123456'){
            $msg=[
                'type'=>'online',
                'msg'=>'登陆'.$data_arr['user_name'].'登录',
                'status'=>1000
            ];
            $login_info=[
                $frame->fd=>[
                    'user_name'=>$data_arr['user_name'],
                    'password'=>$data_arr['password'],
                    'fd'=>$frame->fd
                ]
            ];
            $online_arr=$online_info+$login_info;
            $redis->set('online_user',json_encode($online_arr));
            $online_data=$online_arr;
            $online_arr['type']='online_list';
            var_dump($online_data);
            foreach($online_data as $k=>$v){
                $ws->push($k, json_encode($msg));
                $ws->push($k, json_encode($online_arr));
            }

        }else{
            $msg=[
                'type'=>'login',
                'message'=>'账号或密码不正确',
                'status'=>500
            ];
            $ws->push($frame->fd, json_encode($msg));
        }
    }elseif($data_arr['type']==2)
    {
        $swoole_mysql = new Swoole\Coroutine\MySQL();
        $swoole_mysql->connect([
            'host' => '127.0.0.1',
            'port' => 3306,
            'user' => '',
            'password' => '',
            'database' => '',
        ]);
        if($data_arr['send_to']=='all'){
            $data=[
                'type'=>'message',
                'msg'=>$data_arr['user_name'].':'.$data_arr['message'],
                'status'=>1000
            ];
            foreach($online_info as $k=>$v){
                if($v['fd']==$frame->fd){
                    $data['isme']=1;
                }else{
                    $data['isme']=2;
                }
                $ws->push($k, json_encode($data));
            }
            $message=[
                'name'=>$data_arr['user_name'],
                'message'=>$data_arr['message'],
                'fd'=>$frame->fd
            ];
            //发送异步请求
//            async($message);
            $name=$data_arr['user_name'];
            $message=$data_arr['message'];
            $fd=$frame->fd;
            $time=time();
            $sql="insert into pub_msg VALUE (null,'$name','$message','$fd','$time')";
        }else{
            $data=[
                'type'=>'message',
                'msg'=>"<span style='color: red;'>".$data_arr['user_name'].'对你说:'.$data_arr['message']."</span>",
                'status'=>1000,
                'isme'=>2
            ];
            $data2=[
                'type'=>'message',
                'msg'=>"<span style='color: red;'>".'你对'.$online_info[$data_arr['send_to']]['user_name'].'说:'.$data_arr['message']."</span>",
                'status'=>1000,
                'isme'=>1
            ];
            $ws->push($data_arr['send_to'], json_encode($data));
            $ws->push($frame->fd, json_encode($data2));
            $name=$data_arr['user_name'];
            $message=$data_arr['message'];
            $fd=$frame->fd;
            $to_fd=$data_arr['send_to'];
            $time=time();
            $sql="insert into pri_msg VALUE (null,'$name','$message','$fd','$to_fd','$time')";
        }
        $res=$swoole_mysql->query($sql);
        echo $sql."\n";
        if($res){
            echo '记录成功';
        }else{
            echo '记录失败';
        }
    }elseif($data_arr['type']==3){
        $swoole_mysql = new Swoole\Coroutine\MySQL();
        $swoole_mysql->connect([
            'host' => '127.0.0.1',
            'port' => 3306,
            'user' => '',
            'password' => '',
            'database' => '',
        ]);
        if($data_arr['send_to']=='all'){
            $sql="select * from pub_msg order by send_time asc";
            $arr=$swoole_mysql->query($sql);
            foreach($arr as $k=>$v){
                if($v['fd']==$frame->fd){
                    $arr[$k]['isme']=1;
                }else{
                    $arr[$k]['isme']=2;
                }
            }
            $data=[
                'type'=>'his_data',
                'data'=>$arr
            ];
        }else{
            $to_fd=$data_arr['send_to'];
            $fd=$frame->fd;
            $sqlme="select * from pri_msg where fd=$fd and to_fd=$to_fd";
            $sqlit="select * from pri_msg where fd=$to_fd and to_fd=$fd";
            $arr1=$swoole_mysql->query($sqlme);
            $arr2=$swoole_mysql->query($sqlit);
//            $arr=(array)$arr1+(array)$arr2;
            $arr=array_merge((array)$arr1,(array)$arr2);
            foreach($arr as $k=>$v){
                if($v['fd']==$frame->fd){
                    $arr[$k]['isme']=1;
                }else{
                    $arr[$k]['isme']=2;
                }
            }
            $datetime = array();
            foreach ($arr as $user) {
                $datetime[] = $user['send_time'];
            }
            array_multisort($datetime,SORT_DESC,$arr);
            $data=[
                'type'=>'his_data',
                'data'=>$arr
            ];
        }
        $ws->push($frame->fd, json_encode($data));
    }

});

//监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
//    echo "client-{$fd} is closed\n";
    $redis = new Swoole\Coroutine\Redis();
    $redis->connect('127.0.0.1', 6379);
    $online_str=$redis->get('online_user');
    if(empty($online_str)){
        $online_info=[];
    }else{
        $online_info=json_decode($online_str,true);
    }
    $msg=[
        'type'=>'online',
        'msg'=>$online_info[$fd]['user_name'].'已下线',
        'status'=>1000
    ];
    unset($online_info[$fd]);

    $redis->set('online_user',json_encode($online_info));
    $online_data=$online_info;
    $online_info['type']='online_list';
    var_dump($online_data);
    foreach($online_data as $k=>$v){
        $ws->push($k, json_encode($msg));
        $ws->push($k, json_encode($online_info));
    }

});

$ws->start();
?>

本文参考swoole文档详细请看 https://wiki.swoole.com/wiki/page/397.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值