websocket能跨域
一直以來覺得websocket和ajax應該一樣,是不能跨域的。今天查了一下資料,發現websocket是可以跨域的,妥妥被打臉。於是決定好好學習一下websocket。
使用node開發一個demo
用node做demo再合適不過了,比起java,簡單不知道多少。node下有個socket.io的庫。是對websocket的包裝,據說在瀏覽器不支援websocket的情況下可以自動識別採用long polling。node的安裝很簡單,這裡不做介紹。下面是demo的建立過程。
工程構建
新建檔案:package.json
安裝socket.io庫:npm install socket.io –save
伺服器端
新建server.js,監聽1234埠
var io = require('socket.io')(1234); io.sockets.on('connection', function (client) { client.on('message', function (msg) { //監聽到資訊處理 console.log('Message Received: ', msg); client.send('伺服器收到了資訊:' + msg); }); client.on("disconnect", function () { //斷開處理 console.log("client has disconnected"); }); }); console.log("listen 1234...");
客戶端
新建index.html檔案。客戶端邏輯:回車後傳送input內的訊息到伺服器端,接受到伺服器端訊息顯示在頁面上。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>socket.io</title> <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script> </head> <body> Incoming Chat: <ul></ul> <br/> <input type="text" /> <script> $(function () { var iosocket = io.connect('http://localhost:1234/'); var $ul = $("ul"); var $input = $("input"); iosocket.on('connect', function () {//接通處理 $ul.append($('<li>連上啦</li>')); iosocket.on('message', function (message) {//收到資訊處理 $ul.append($('<li></li>').text(message)); }); iosocket.on('disconnect', function () { //斷開處理 $ul.append('<li>Disconnected</li>'); }); }); $input.keypress(function (event) { if (event.which == 13) { //回車 event.preventDefault(); console.log("send : " + $input.val()); iosocket.send($input.val()); $input.val(''); } }); }); </script> </body>
演示
執行伺服器端:node server.js,啟動服務。
用瀏覽器開啟index.html,file:///…/index.html。發現可以正常互動,此時的源是:file://。因此websocket是支援跨域的。
socket.io支援websocket和long polling
由於websocket協議在瀏覽器的相容性上還不夠理想,通常會有long poling的替代方案。socket.io是即支援websocket又支援long polling的。預設情況下,會先發送polling的包,確認server端是否支援websocket,如果不支援會自動轉為polling方式。可以通過配置客戶端和伺服器端程式碼實現協議的選擇。然而,本次測試發現socket.io2.x版本在polling方式下也不能在ie中正常使用。
伺服器端配置
//只支援polling方式 var io = require('socket.io')(1234, {"transports":['polling']}); //只支援websocket方式 var io = require('socket.io')(1234, {"transports":['websocket']}); //兩種方式都支援 var io = require('socket.io')(1234, {"transports":['polling', 'websocket']});
客戶端配置
//使用websocket協議連線伺服器端 var iosocket = io.connect('http://localhost:1234/', { "transports":['websocket'] }); //使用polling協議連線伺服器端 var iosocket = io.connect('http://localhost:1234/', { "transports":['polling'] });