• 【转】Web实时通信之Socket.IO ,真正的兼容ie


    前面两篇文章使用了Ajax long polling和WebSocket两种常用的Web实时通信方式构建了简单的聊天程序。

    但是,由于浏览器的兼容问题,不是所有的环境都可以使用WebSocket这种比较好的方式。也就是说,根据浏览器或者环境的不同,客户端和服务端可能需要使用不同的通信方式。

    Socket.IO简介

    为了解决上面的问题,Socket.IO就出现了。

    Socket.IO是一个基于Nodejs的,用于实时通信的一个软件包(包括client端和server端),Socket.IO完全由JavaScript实现。

    Socket.IO设计的目标是支持任何的浏览器,任何设备。在接口方面,Socket.IO统一了通信的API,在内部实现上支持WebSocket,AJAX long-polling, AJAX multipart streaming, Forever Iframe等方式。也就是说,Socket.IO会根据环境来选择适合的通信方式。

    在Socket.IO中,还有namespace和room的概念,可以方便的对socket进行分组,方便的实现一些例如聊天室的应用。

    关于更多Socket.IO相关的内容,请参考该链接

    好吧,又是聊天程序,这次是Socket.IO版本。

    实现

    在实现方面,客户端直接使用Socket.IO 的client,服务器端使用Nodejs。

    客户端

    客户端首先创建一个socket对象,这个socket对象会监听"new_message"和"user_status"事件。

    复制代码
    var socket;
    
    function initSocket(){
         socket = io("http://" + location.host);
         
         socket.emit("add_client", $("#clientNameSpan").text());
         
         socket.on("new_message", function(data){
             console.log(data);
             data = eval("(" + data + ")");
             if (data.sender == $("#clientNameSpan").text()){
                 $("#inbox").append("<div class='chatItemS'><span class='msg mSend'><span class='sender'>"+data.sender+": </span>"+data.msg+"</span></div>");
             }
             else {
                 $("#inbox").append("<div class='chatItemR'><span class='msg mRecv'><span class='sender'>"+data.sender+": </span>"+data.msg+"</span></div>");
             }
             $("#inbox").scrollTop($("#inbox")[0].scrollHeight);
         });
         
         socket.on("user_status", function(data){
             $("#clientCount").text("Online User: "+data.length);
             $("#clients").children().remove();
             for(var i = 0; i<data.length; i++){
                 $("#clients").append("<span id='client'>"+data[i]["clientName"]+"</span>")
             }
         })
     }
    复制代码

    服务端

    对于服务端,首先是一些静态文件、页面的处理。

    复制代码
    // get the static files
    app.get("/", function(req, res){
        res.sendFile(__dirname + "/index.html");
    });
    
    app.get("/static/jquery-1.11.3.js", function(req, res){
        res.sendFile(__dirname + "/static/jquery-1.11.3.js");
    });
    
    app.get("/static/json2.js", function(req, res){
        res.sendFile(__dirname + "/static/json2.js");
    });
    
    app.get("/static/style.css", function(req, res){
        res.sendFile(__dirname + "/static/style.css");
    });
    复制代码

    另外,服务端主要的功能就是接收消息,然后广播消息。

    服务端会根据socket id和用户名记录所有的用户,并存放在一个数组中。每当有用户加入或者用户退出,服务端就通过"user_status"事件将用户数组发送给客户端,这样客户端就能展示当前在先用户数。

    复制代码
    // save all the client {"sid": socket.id, "clientName": client}
    var clients = []
    
    io.on("connection", function(socket){
    
        socket.on("add_client", function(client){
            console.log(client+" jion the chat");
            
            var clientObj = {};
            clientObj["sid"] = socket.id;
            clientObj["clientName"] = client;
            
            clients.push(clientObj);
            io.emit("user_status", clients)
        });
        
        socket.on("new_message", function(msg){
            console.log("Server got message: "+msg);
            console.log("Send message using: "+socket.conn.transport.name);
            io.emit("new_message", msg);
        });
          
        socket.on("disconnect", function(){
            for(var i = 0; i<clients.length; i++){
                if(clients[i]["sid"] == socket.id){
                    console.log(clients[i]["clientName"]+" leave the chat");
                    clients.splice(i, 1);
                    break;
                }
            }
            io.emit("user_status", clients);
        });
      
    });
    复制代码

    运行效果

    首先是一个login页面,在服务端会将用户名跟socket id绑定,用来进行简单的用户统计。

      

    Console端打印了服务器收到的消息,以及用户的join/leave情况。

      

    当用户状态改变后,页面会收到"user_status"事件,然后更新用户状态栏。

    Socket.IO兼容性测试

    前面提到了Socket.IO的优势就是统一了接口,对用户屏蔽了底层,同时能够支持不同的设备,选择最优的通信方式。

    下面就对Socket.IO的兼容性进行一些简单的测试,主要看看IE7-10。

    首先,注意服务端的下面一段代码,用于显示当前传递消息的通信方式:

    console.log("Send message using: "+socket.conn.transport.name);

    IE10

    我本机安装的是IE10,通过服务端console可以看到,在IE10中Socket.IO会选择"WebSocket"为最终通信方式。

    IE9/IE8

    打开IE,通过F12进入下面页面,然后设置为IE9。

    通过测试可以看到,Socket.IO在IE9中可以正常工作,由于IE9不支持“WebSocket”,所以Socket.IO最终选择了"Polling"为最终通信方式。

    通过上面的设置切换到IE8模式,由于IE8不支持“WebSocket”,所以Socket.IO就会将通信方式切换到了“Polling”。

    IE7

    通过同样的步骤测试,Socket.IO在IE7中使用polling方式正常工作。

    IE7中唯一遇到的问题是“JSON.stringify”方法不支持,所以通过下面方式对IE7进行了hack:

    <!--[if IE 7]>
        <script src="/static/json2.js"></script>
    <![endif]-->

    总结

    从例子中可以看到,使用了Socket.IO后,我们只需要了解Socket.IO提供的API,而不需要关心使用哪种通信方式,使用起来简单、方便。

    文中对Socket.IO在IE上的兼容性做了一些简单的测试,结果还是很满意的,对于不支持WebSocket的环境,Socket.IO自动切换到了polling方式,用户不用去关心环境的差异了。

    Socket.IO作为一个跨环境,多种连接方式自动切换的工具,进一步简化了Web实时通信方面应用的开发。

    Ps:通过此处可以下载例子的源码。

    from:http://www.cnblogs.com/wilber2013/p/4814838.html

    备注:看了好多例子,对我来说只有这个才是真正的兼容

  • 相关阅读:
    ubuntu 15.04默认root用户登陆
    hive的not in
    Spark 1.4.1中Beeline使用的gc overhead limit exceeded
    Sequoiadb该如何选择合适的SQL引擎
    scala的object知识点
    scala中同步块
    英语口语练习系列-C36-城市-谈论活动-登高
    英语口语练习系列-C35-马戏-谈论语言-己亥杂诗
    英语口语练习系列-C34-儿童-谈论物品和人-武陵春
    英语口语练习系列-C33-露营-谈论日期-离思
  • 原文地址:https://www.cnblogs.com/xuan52rock/p/5220279.html
Copyright © 2020-2023  润新知