跨域(二)——WebSocket

严格地说,WebSocket技术不属于HTML5,这个技术是对HTTP无状态连接的一种革新,本质就是一种持久性socket连接,在浏览器客户端通过javascript进行初始化连接后,就可以监听相关的事件和调用socket方法来对服务器的消息进行读写操作。与Ajax相比,Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息;XHR受到域的限制,而WebSocket允许跨域通信,这个特性导致我们至少可以用来做远控。

WebSocket实现了全双工通信,使WEB上的真正的实时通信成为可能。浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。在WebSocket协议中,为我们实现即时服务带来了三个好处:

  1. 客户端和服务器端之间数据传输时请求头信息比较小,大概2个字节。
  2. 服务器和客户端可以相互主动的发送数据给对方。
  3. 不需要多次创建TCP请求和销毁,节约宽带和服务器的资源。

WebSocket的官方地址是:www.websocket.org,其中给出了一些样例,可以直接在线测试。

对于WebSocket,目前浏览器支持情况如下:
Chrome
Supported in version 4+
Firefox
Supported in version 4+
Internet Explorer
Supported in version 10+
Opera
Supported in version 10+
Safari
Supported in version 5+

服务器支持情况如下:

服务器名称 下载网址
Tomcat服务器 http://tomcat.apache.org
Php服务器 http://code.google.com/p/phpwebsocket
Node服务器 http://nodejs.org
Ruby服务器 http://github.com/gimite/web-socket-ruby
Jetty服务器 http://jetty.codehaus.org/jetty/
Netty服务器 http://www.jboss.org/netty
Kaazing服务器 http://www.kaazizng.org/confluence/KAAZING/Home

这里选择Node服务器,创建WebSocket Node.js应用程序事实上的标准库Socket.IO。node.js提供了高效的服务端运行环境,socket.io基于node.js并简化了WebSocket API,统一了通信的API,统一了服务端与客户端的编程方式。

与很多其他的Node.js库相似,Socket.IO也是一个NPM模块,可以按如下方式进行安装:

$ npm install socket.io

下面是一个基于Socket.IO的WebSocket聊天应用程序

Node.js服务器端代码server.js:

var io = require('socket.io').listen(4000);
io.sockets.on('connection', function (socket) {
  socket.on('clientMessage', function(content) {
    socket.emit('serverMessage', 'You said: ' + content);
    socket.broadcast.emit('serverMessage', socket.id + ' said: ' + 
      content);
  });
});

客户端代码client.html:

<html>
  <head>
    <title>Node.js WebSocket chat</title>
    <style type="text/css">
      #input {
        width: 200px;
      }
      #messages {
        position: fixed;
        top: 40px;
        bottom: 8px;
        left: 8px;
        right: 8px;
        border: 1px solid #EEEEEE;
        padding: 8px;
      }
    </style>
  </head>

  <body>

    Your message:
    <input type="text" id="input">

    <div id="messages"></div>

    <script src="http://localhost:4000/socket.io/socket.io.js"></script>
    <script type="text/javascript">
      var messagesElement = document.getElementById('messages');
      var lastMessageElement = null;

      function addMessage(message) {
        var newMessageElement = document.createElement('div');
        var newMessageText = document.createTextNode(message);

        newMessageElement.appendChild(newMessageText);
        messagesElement.insertBefore(newMessageElement, 
          lastMessageElement);
        lastMessageElement = newMessageElement;
      }

      var socket = io.connect('http://localhost:4000');
      socket.on('serverMessage', function(content) {
        addMessage(content);
      });

      var inputElement = document.getElementById('input');

      inputElement.onkeydown = function(keyboardEvent) {
        if (keyboardEvent.keyCode === 13) {
          socket.emit('clientMessage', inputElement.value);
          inputElement.value = '';
          return false;
        } else {
          return true;
        }
      };
    </script>

  </body>
</html>
原文地址:https://www.cnblogs.com/aaron-shu/p/4162260.html