通过http长连接和http短连接及websocket实现在线即时通讯聊天

通过http长连接和http短连接及websocket实现在线即时通讯聊天

通过http长连接和http短连接及websocket实现在线即时通讯聊天

聊天室使我们日常生活中经常用到的,比如微信群聊,今天我带大家了解一下通过三种技术手段可以实现聊天室的功能,主要分为HTTP长连接、HTTP短连接、websocket。UDP通讯、TCP通讯,今天我们主要来讲怎么用http长短连接及websocket来实现即时通讯。

一、什么是HTTP长连接、HTTP短连接、websocket

在HTTP/1.0中默认使用http短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。

而从HTTP/1.1起,默认使用长连接,用以保持连接特性,提高传输的效率和减低服务器的开销。使用长连接的HTTP协议,会在响应头加入这行代码:

Connection:keep-alive

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。

HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。

websocket是html5的新特性,WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

二、http长连接实现即时聊天

主要通过ajax长连接后端php,后端php一直定时监控消息,有新消息就即时反馈给浏览器,重新开始新的长连接,及时性相对比较高。

<?php
function writefile($file_name, $text) {
    $handle = fopen($file_name, "a");
    if (flock($handle, LOCK_EX)) {
        fwrite($handle, $text.'\n');
        flock($handle, LOCK_UN);
    }
    fclose($handle);
}

$_talklistfile = "../Data/talklist.txt";
if (!file_exists($_talklistfile)) {
    file_put_contents($_talklistfile, "");
}

if (!empty($_POST['action'])) {
    switch ($_POST['action']) {
        case "getwords":
            $_mtime = $_POST['mtime'];
            $i = 0;
            while (true) {

                usleep(500000); //0.5秒
                $i++;
                if ($i >= 40) {
                    echo json_encode(array('error' => true));
                    exit();
                }
                //清空文件缓存
                clearstatcache();
                //如果文件修改时间大于用户那边的时间,就说明有更新
                $_newmtime = filemtime($_talklistfile);
                if ($_newmtime > $_mtime || $_mtime == 0) {
                    echo json_encode(array('error' => false, "data" => file_get_contents($_talklistfile), "mtime" => $_newmtime));

                    exit();
                }

            }

            break;
        case "sayword":
            $_words = $_POST['words'];
            $_uid = $_POST['uid'];
            writefile($_talklistfile, '用户'.$_uid." ".date('H:i:s', time())."说".$_words); //写入聊天文件
            echo json_encode(array('error' => false));
            exit();

            break;
        default:

            break;
    }

} else {
    ?>
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>ajax长轮询实现聊天</title>
        <script id="bfwone" data="dep=jquery.17&err=0" type="text/javascript" src="http://repo.bfw.wiki/bfwrepo/js/bfwone.js"></script>
        <script type="text/javascript">
            var mtime = 0;

            //生成唯一字符串

            function randomString(len) {
                len = len || 32;
                var $chars = '2345678';
                var maxPos = $chars.length;
                var pwd = '';
                for (i = 0; i < len; i++) {
                    pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
                }
                return pwd;
            }

            //发送消息
            function saywords() {
                var words = $("#words").val();
                if (words == "") {
                    alert('说点啥');
                    return;
                }
                $.ajax({
                    type: "POST",
                    dataType: "json",
                    url: "/ajaxtalk2.php",

                    data: {
                        action: "sayword",
                        words: words,
                        uid: $("#username").val()
                    }, //40秒后无论结果服务器都返回数据
                    success: function(ret, textStatus) {
                        if (ret.error == false) {
                            $("#words").val("");

                        }
                    },

                });
            }
            //长连接监听有没有新消息
            function listenwords() {
                $.ajax({
                    type: "POST",
                    dataType: "json",
                    url: "/ajaxtalk2.php",
                    timeout: 30000,
                    //ajax请求超时时间30秒
                    data: {
                        action: "getwords",
                        mtime: mtime,


                    },
                    //40秒后无论结果服务器都返回数据
                    success: function(ret, textStatus) {
                        if (ret.error == false) {
                            mtime = ret.mtime;
                            $("#msg").html(ret.data.replace(/\\n/g, "</br>"));

                        }
                        listenwords(); //循环监听
                    },
                    //Ajax请求超时,继续查询
                    error: function(XMLHttpRequest, textStatus, errorThrown) {
                        if (textStatus == "timeout") {
                            $("#msg").append("<br>[超时]");
                            listenwords();
                        }
                    }
                });
            }
            bready(function() {

                $("#username").val(randomString(6));

                listenwords();
                $("#btn").bind("click", function() {
                    saywords();
                });
            });
        </script>
        <...

点击查看剩余70%

{{collectdata}}

网友评论0