美文网首页
第三课:workerman之简易聊天室

第三课:workerman之简易聊天室

作者: liamu | 来源:发表于2018-06-24 18:33 被阅读20次

    代码依赖

    image.png

    服务端代码

    <?php
    require __DIR__ . '/Autoloader.php';
    
    use Workerman\Worker;
    
    $ws_worker = new Worker("websocket://0.0.0.0:9091");
    
    // 启动1个进程对外提供服务
    $ws_worker->count = 1;
    $clients = [];
    // 当收到客户端发来的数据后返回hello $data给客户端
    $ws_worker->onMessage = function($connection, $data)
    {
        global $clients;
        echo $data.PHP_EOL;
        if (preg_match('/^login:(\w{3,20})/i', $data,$result)) {
            if (!array_key_exists($connection->getRemoteIp().':'.$connection->getRemotePort(), $clients)) {
    
                $clients[$connection->getRemoteIp().':'.$connection->getRemotePort()] = ['fd'=>$connection->getRemoteIp().':'.$connection->getRemotePort(),'name'=>$result[1],'conn'=>$connection];
    
                $connection->send("notice:success");//
                $connection->send("msg:welcome back ".$result[1]);
                
                $allUser = "user:".json_encode(array_column($clients, 'name','fd'));
                foreach ($clients as $value) {
                    $value['conn']->send($allUser);
                }
            }
        } else if(preg_match("/^msg:(.*?)/isU",$data,$msgset)) {//代表 是客户端发送普通消息
            if(array_key_exists($connection->getRemoteIp(),$clients)) //必须已经认证过得客户端
            {
                echo "get msg :".$msgset[1];
            }
        } else if (preg_match("/^chat:\<(.*?)\>:(.*?)/isU",$data,$msgset)) {
            var_dump($msgset);
            $ipp = $msgset[1];
            $msg = $msgset[2];
            if (array_key_exists($ipp, $clients)) {
                $clients[$ipp]['conn']->send("msg:".$msg);
            }
        }
        $connection->onClose=function ($connection)//客户端主动关闭
        {
            global $clients;
            unset($clients[$connection->getRemoteIp().':'.$connection->getRemotePort()]);
            $allUser = "user:".json_encode(array_column($clients, 'name','fd'));
            foreach ($clients as $value) {
                $value['conn']->send($allUser);
            }        
        };  
    
    };
    
    // 运行worker
    Worker::runAll();
    

    客户端代码

    <!DOCTYPE html>
    <html>
    <head>
        <title>chat room</title>
    <script type="text/javascript">
        // WebSocket 构造函数
        var ws,name,isLogin=false;;
        function connection(){
            if (name.length == 0) {
                alert('please input u name');return;
            }
            ws = new WebSocket("ws://127.0.0.1:9091");
            ws.onopen = onopen; //指定连接成功后的回调函数
            ws.onmessage = onmessage; // 指定收到服务器数据后的回调函数
            ws.onclose = function() { //指定连接关闭后的回调函数
                console.log("连接关闭,定时重连");
                closed();
            };
            ws.onerror = function() {
                console.log("出现错误");
            };      
        }
    
        function onopen(){
            var login_msg = 'login:'+name;
            ws.send(login_msg);
        }
    
        function onmessage(evt){ // 服务器数据可能是文本,也可能是二进制数据(blob对象或Arraybuffer对象)
            
            console.log( "Received Message: " + evt.data);
            var getMsg = evt.data;
            if(/^notice:success$/.test(getMsg)) //服务器验证通过,后面做任何发送操作
            {
                isLogin=true;
            }
            else if(/^msg:/.test(getMsg)) //代表是普通消息
            {
                //<p>xxxxooo</p>
                var p=document.createElement("P");
                p.innerHTML="<span>收到消息</span>"+getMsg.replace("msg:","");
                document.getElementById("txtcontent").appendChild(p);
            } else if (/^user:/.test(getMsg)) {
                var obj = document.getElementById('alluser');
                obj.length=0;
                obj.add(new Option('please select',''));
                var alluser = eval('(' +getMsg.replace("user:","")+ ')');
                for(user in alluser){
                    console.log(user);
                    console.log(alluser[user]);
                    obj.add(new Option(alluser[user],user));
                }
                
                
            }
            else
            {
    
            }       
        }
    
    
    
        function sendText(){
            if (!isLogin) {
                alert("请先服务器验证");
                return;
            }
            var msg=document.getElementById("txtmsg").value;
    
            var listusers = document.getElementById('alluser');
            var toUser = listusers.options[listusers.selectedIndex].value;
            if (toUser == '') {
                ws.send("msg:"+msg); //用于向服务器发送数据
            } else {
                var toUserName = listusers.options[listusers.selectedIndex].innerHTML;
                ws.send("chat:<"+toUser+">:"+msg);          
            }
            //在div 中显示我们的行为
            var p = document.createElement("P");
            p.innerHTML="<span>发送消息</span>"+msg
            document.getElementById("txtcontent").appendChild(p);
        } 
        function checkstatus(){ //返回实例对象的当前状态,共有四种
            // CONNECTING:值为0,表示正在连接。
            // OPEN:值为1,表示连接成功,可以通信了。
            // CLOSING:值为2,表示连接正在关闭。
            // CLOSED:值为3,表示连接已经关闭,或者打开连接失败     
            if (!isLogin) {
                alert("请先服务器验证");
                return;
            }       
            alert(ws.readyState);
        }
    
        function closed(){
            if (!isLogin) {
                alert("请先服务器验证");
                return;
            }       
            ws.close();
        }
    </script>
    </head>
    <body>
        <form>
            <table>
                <tr>
                    <th>message</th>
                    <th><div id="txtcontent" style="width: 320px;height: 200px;border-style: solid;border-width: 1px;border-color: #000;"></div></th>
                </tr>
                <tr>
                    <th>聊天内容:</th>
                    <th><input type="text" name="message" id="txtmsg"></th>
                </tr>
                <tr>
                    <th>当前用户:</th>
                    <th><input type="text" name="name" id="name" disabled="true"></th>
                </tr>
                <tr>
                    <th>聊天对象:</th>
                    <th>
                        <select id="alluser">
                            <option value=''>所有人</option>
                        </select>
                    </th>
                </tr>           
                <tr>
                    <th><button type="button" onclick="sendText()">send</button></th>
                    <th><button type="button" onclick="checkstatus()">status</button></th>
                </tr>
                <tr>
                    <th><button type="button" onclick="connection()">connection</button></th>
                    <th><button type="button" onclick="closed()">closed</button></th>
                </tr>                                               
            </table>
        </form>
    </body>
    <script type="text/javascript">
        // 输入姓名
        function show_prompt(){  
            name = prompt('输入你的名字:', '');
            if(!name || name=='null'){  
                name = '游客';
            }
            document.getElementById('name').value = name;
        }  
        show_prompt();
    </script>
    </html>
    

    运行截图

    image.png

    相关文章

      网友评论

          本文标题:第三课:workerman之简易聊天室

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