美文网首页
基于swoole的websocket聊天室

基于swoole的websocket聊天室

作者: wuxuan94 | 来源:发表于2017-09-08 18:02 被阅读0次

    一、什么是websocket?
    websocket协议是基于TCP协议的一种新的持久化网络通信协议。通过一次浏览器请求、服务器响应(一次握手)搭建出一条网络双通道,实现服务器主动推送信息给浏览器。

    websocket和http的关系

    二、swoole的安装
    http://www.swoole.com
    我直接在服务器上安装的。。。
    三、server.php(聊天室服务端)

    <?php
    //结合redis使用
    $redis = new redis();
    $result = $redis->connect("127.0.0.1", 6379);
    $server = new swoole_websocket_server("0.0.0.0", "端口号");
    $server->on('open', function (swoole_websocket_server $server, $request) {
        global $redis;
        $nfd = $request->fd;
        echo "客户端{$nfd}成功接入\n";
        $redis->hset("User",$nfd,$nfd);//将客户端id存入redis
        $users = $redis->hvals("User");
    });
    $server->on('message', function (swoole_websocket_server $server, $frame) {
        global $redis;
        $data = $frame->data;//客户端发送的信息
        $fd = $frame->fd;//消息发送id
        //类型判断
        $str = substr($data,0,8);
        if($str == '{"name":'){
            //登录
            $data = json_decode($data);
            echo $fd.$data->name."登录"."<br>";
            $redis->hset("name",$fd,$data->name);//保存客户端昵称
            $redis->hset("email",$fd,$data->email);//保存客户端邮箱
            $users = $redis->hvals("User");//取回所有用户
            foreach ($users as $u)
            {
                //对所有用户发送消息
                $server->push($u ,'0@1@4@3'.$redis->hGet('name',$fd));
            }
        }else{
            //发送消息
            echo $fd."发送消息:".$data;
            $users = $redis->hvals("User");//取回所有用户
            foreach ($users as $u)
            {
                //对所有用户发送消息
                $server->push($u ,$redis->hGet('name',$fd).'说:'.$data);
            }
        }
    });
    $server->on('close', function ($ser, $fd) {
        global $redis;
        //清除用户信息缓存
        $redis->hdel("User",$fd);
        $redis->hdel("name",$fd);
        $redis->hdel("email",$fd);
        $users = $redis->hvals("User");
        var_dump($users);
        echo "client {$fd} closed\n";
        //$redis->flushAll();
    });
    $server->start();
    ?>
    

    四、client.php(聊天室客户端)

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="UTF-8">
        <style>
            #top{
                width: 60%;
                height: 50px;
                text-align: left;
                margin: 0 auto;
                margin-top: 50px;
                background-color: #3c3c3c;
            }
            #room{
                width: 60%;
                height: 500px;
                text-align: center;
                margin: 0 auto;
                border: 1px solid ;
            }
            #left{
                width: 25%;
                float: left;
                text-align: center;
                margin: 30px;
                border: 1px solid #ccc;
                background-color: #E8E8D0;
            }
            #right{
                width: 60%;
                height: 90%;
                float: right;
                text-align: left;
                margin: 30px 30px 20px 20px;
                background-color: #F0F0F0;
            }
            #chat{
                width: 100%;
                height: 90%;
                margin-left: 10px;
            }
            #submit1{
                width: 100%;
                height: 50px;
                padding-bottom: 10px;
                margin-top: 15px;
            }
            #submit2{
                width: 100%;
                height: 50px;
                padding-bottom: 10px;
                margin-top: 15px;
            }
        </style>
        <script type="text/javascript">
            if(window.WebSocket){
                var webSocket = new WebSocket("ws://服务端ip:端口号");
                webSocket.onopen = function (event) {
                    //webSocket.send("Hello,WebSocket!");
                };
                webSocket.onmessage = function (event) {
                    var content = document.getElementById('chat');
                    var left = document.getElementById('left');
                    if(event.data instanceof Blob) {
                        var img = document.createElement("img");
                        img.src = window.URL.createObjectURL(event.data);
                        content.appendChild(img);
                    }else {
                        var str = event.data.substring(0,7);
                        if(str == '0@1@4@3'){
                            //登录
                            var name = event.data.substring(7,event.data.length);
                            left.innerHTML = left.innerHTML.concat('<p style="margin-left:0px;height:20px;line-height:20px;">'+name+'</p>');
                        }else{
                            //发送消息
                            content.innerHTML = content.innerHTML.concat('<p style="margin-left:20px;height:20px;line-height:20px;">'+event.data+'</p>');
                        }
                    }
                };
    
                //登录
                var login = function () {
                    var name = document.getElementById('name').value;
                    var email = document.getElementById('email').value;
                    if(name == ''){
                        alert('请输入昵称');
                    }else if(email == ''){
                        alert('请输入邮箱');
                    }else{
                        var arr = new Array();
                        arr['name'] = name;
                        arr['email'] = email;
                        var a = '{"name":"'+name+'","email":"'+email+'"}';
                        webSocket.send(a);
                        document.getElementById('submit1').style.display = 'none';
                        document.getElementById('submit2').style.display = '';
                    }
                }
                //发送信息
                var sendMessage = function(){
                    var data = document.getElementById('message').value;
                    if(data == ''){
                        alert('消息不能为空');
                    }else{
                        webSocket.send(data);
                        document.getElementById('message').value = '';
                    }
                }
            }else{
                console.log("您的浏览器不支持WebSocket");
            }
        </script>
    </head>
    <body>
    <div id="top">
        <p style="line-height: 50px;margin-left: 20px;color: white">聊天室测试——swoole</p>
    </div>
    <div id="room">
        <div id="left">
            <span style="color: red;border-bottom:1px dashed red;overflow-y:auto;">在线用户</span>
        </div>
        <?php
        if(app\helpers\Isphone::is_mobile_request()) {
            ?>
            <div id="right" style="height: 70%;width: 50%">
                <div id="chat" style="overflow-y:auto;">
                    <p style="text-align: center">欢迎进入聊天室!</p>
                </div>
                <div id="submit1">
                        
                    <input type="text" id="name" name="name" placeholder="昵称" style="width: 120px"/>
                    <input type="text" id="email" name="email" placeholder="邮箱" style="width: 120px"/>
                    <button onclick="login()">登录</button>
                </div>
                <div id="submit2" style="display: none;">
                        
                    <input type="text" id="message" style="width: 70%">
                    <button onclick="sendMessage()" style="height:25px;width:75px;">发送</button>
                </div>
            </div>
            <?php
        }else {
            ?>
            <div id="right">
                <div id="chat" style="overflow-y:auto;">
                    <p style="text-align: center">欢迎进入聊天室!</p>
                </div>
                <div id="submit1">
                        
                    <input type="text" id="name" name="name" placeholder="昵称"/>
                    <input type="text" id="email" name="email" placeholder="邮箱"/>
                    <button onclick="login()">登录</button>
                </div>
                <div id="submit2" style="display: none;">
                        
                    <input type="text" id="message" style="width: 70%">
                    <button onclick="sendMessage()" style="height:25px;width:75px;">发送</button>
                </div>
            </div>
            <?php
        }
        ?>
    </div>
    </body>
    </html>
    

    五、学习总结
    初次接触到网络协议发现这里还需要自己更深入全面的学习和了解。
    在消息推送上websocket相比较于http更方便快捷,避免了浏览器无时无刻的请求服务器,由被动变主动。
    linux命令:
    nohup command &
    用途:命令不挂断、后台运行。
    中止nohup命令:ps -ef | grep command
    kill -9 pid
    聊天室弊端:
    1.页面过于简陋、用户下线没有提示。
    2.服务端没有涉及到数据库操作,无法查看历史聊天记录。

    github:https://github.com/aishangkaoniangao/websocket-chat

    相关文章

      网友评论

          本文标题:基于swoole的websocket聊天室

          本文链接:https://www.haomeiwen.com/subject/wihnjxtx.html