基于swoole的websocket聊天室

一、什么是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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容