摘要:而雙工通訊協議,不僅客戶端能向服務端發起請求,服務端也可以主動推送信息給客戶端。目的即時通訊,替代輪詢協議在年誕生,年成為國際標準。與協議有著良好的兼容性。是一個基于的,用于實時通信的一個軟件包包括端和端,完全由實現。
上一篇文章簡要的介紹了一下http協議,這次再介紹一下WebSocket協議,兩者之間有很大的區別,WebSocket協議是 HTML5 開始提供的一種在單個 TCP 連接上進行全雙工通訊的協議。
簡單的理解一下什么是雙工通訊協議,之前有講過http協議只能客戶端向服務端發起請求,是單向的應用層協議。而雙工通訊協議,不僅客戶端能向服務端發起請求,服務端也可以主動推送信息給客戶端。
目的:即時通訊,替代輪詢WebSocket 協議在2008年誕生,2011年成為國際標準。所有瀏覽器都已經支持了。
相比于http協議,websoket協議給我們帶來了極大的方便,舉個例子:
之前,我們在做消息通知的時候,需要設置定時器,頻繁的向后臺發起異步ajax請求實現長輪詢,獲取最新的數據,這樣效率非常低,非常浪費資源,因為不停的發起http請求,不停的與服務端建立連接,或者http鏈接始終打開。
而現在有了websocket,就解決了輪詢的問題,websocket只需要建立一次連接,就可以保持長久連接,相比輪詢不停的建立連接,大大的提升了效率,這樣只要服務端有數據變化,就可以立即通知前臺了。
首先HTTP有 1.1 和 1.0 之說,也就是所謂的 keep-alive ,把多個HTTP請求合并為一個,但是 Websocket 其實是一個新協議,跟HTTP協議基本沒有關系,只是為了兼容現有瀏覽器的握手規范而已,也就是說它是HTTP協議上的一種補充,Websocket是借用了HTTP的協議來完成一部分握手。
websocket有以下特點:
建立在 TCP 協議之上,服務器端的實現比較容易。
與 HTTP 協議有著良好的兼容性。默認端口也是80和443,并且握手階段采用 HTTP 協議,因此握手時不容易屏蔽,能通過各種 HTTP
代理服務器。
屬于長連接(http協議無狀態)
雙向通信(http是單向通信)
可以跨域,不受瀏覽器同源策略的限制(http協議不可跨域)
數據格式比較輕量,性能開銷小,通信高效
可以發送文本,也可以發送二進制數據。
協議標識符是ws(如果加密,則為wss),服務器網址就是 URL。如:ws://example.com:80/some/path
websocket協議應用目前websocket對大部分瀏覽器有很好的兼容,但對于IE10以下的瀏覽器無法兼容。為了解決兼容性,Socket.IO就出現了。
Socket.IO是一個基于Nodejs的,用于實時通信的一個軟件包(包括client端和server端),Socket.IO完全由JavaScript實現。
平時在應用的時候,可以直接引入socket.io這個庫就可以了。前后臺都需要引用該庫。
下面針對nodejs的服務端如何使用舉個例子:
服務端代碼:
const http = require("http"); const fs = require("fs"); const express = require("express"); const io = require("socket.io"); const app = express(); const httpServer = http.createServer(app); app.use("/", express.static(__dirname + "/www")); httpServer.listen(8081); const ioserve = io.listen(httpServer); let users = []; ioserve.on("connection", (socket) => { socket.on("login", (nickname) => { if (users.indexOf(nickname) > -1) { socket.emit("nickExisted"); } else { socket.userIndex = users.length; socket.nickname = nickname; users.push(nickname); socket.emit("loginSuccess"); ioserve.sockets.emit("system", nickname, users.length, "login"); } }); socket.on("postMsg", function (msg) { socket.broadcast.emit("newMsg", socket.nickname, msg); }); socket.on("img", function (imgData) { socket.broadcast.emit("newImg", socket.nickname, imgData); }) socket.on("disconnect", function () { users.splice(socket.userIndex, 1); socket.broadcast.emit("system", socket.nickname, users.length, "logout"); }); })
前臺代碼
html文件
HiChat :)
connecting to server...
js文件
; (function () { function Hichart() { this.socket = null; } Hichart.prototype = { init: function () { var that = this; this.socket = io.connect(); this.socket.on("connect", function () { document.getElementById("info").textContent = "get yourself a nickname :)"; document.getElementById("nickWrapper").style.display = "block"; document.getElementById("nicknameInput").focus(); that.login(); that.postMsg(); that.uploadImg(); }); this.socket.on("nickExisted", function () { document.getElementById("info").textContent = "!nickname is taken, choose another pls"; }); this.socket.on("loginSuccess", function () { document.title = "hichat | " + document.getElementById("nicknameInput").value; document.getElementById("loginWrapper").style.display = "none";//隱藏遮罩層顯聊天界面 document.getElementById("messageInput").focus();//讓消息輸入框獲得焦點 }); this.socket.on("system", function (nickname, userCount, type) { var msg = nickname + (type === "login" ? " joined" : " left"); that.displayNewMsg("system ", msg, "red"); document.getElementById("status").textContent = userCount + (userCount > 1 ? " users" : " user") + " online"; }); this.socket.on("newMsg", function (nickname, msg) { that.displayNewMsg(nickname, msg); }); this.socket.on("newImg", function (nickname, newImg) { that.displayImage(nickname, newImg); }); }, login: function () { var that = this; document.getElementById("loginBtn").addEventListener("click", function () { var nickname = document.getElementById("nicknameInput").value; if (nickname.trim().length) { that.socket.emit("login", nickname); } else { document.getElementById("nicknameInput").focus(); } }, false) }, displayNewMsg: function (user, msg, color) { var container = document.getElementById("historyMsg"); var msgToDisplay = document.createElement("p"); var data = new Date().toTimeString().substr(0, 8); msgToDisplay.style.color = color || "#000"; msgToDisplay.innerHTML = user + "(" + data + "): " + msg; container.appendChild(msgToDisplay); container.scrollTop = container.scrollHeight; }, displayImage: function (user, imgData, color) { var container = document.getElementById("historyMsg"), msgToDisplay = document.createElement("p"), date = new Date().toTimeString().substr(0, 8); msgToDisplay.style.color = color || "#000"; msgToDisplay.innerHTML = user + "(" + date + "):
" + ""; container.appendChild(msgToDisplay); container.scrollTop = container.scrollHeight; }, postMsg: function () { var that = this; var sendBtn = document.getElementById("sendBtn"); var messageInput = document.getElementById("messageInput"); sendBtn.addEventListener("click", function () { var msg = messageInput.value; if (msg.trim().length != 0) { messageInput.value = ""; messageInput.focus(); that.socket.emit("postMsg", msg); that.displayNewMsg("me", msg); } }); }, uploadImg: function () { var that = this; document.getElementById("sendImage").addEventListener("change", function () { if (this.files.length) { var file = this.files[0]; var reader = new FileReader(); if (!reader) { that.displayNewMsg("system", "!your browser doesn"t support fileReader", "red"); this.value = ""; return; } reader.onload = function (e) { this.value = ""; that.socket.emit("img", e.target.result); that.displayImage("me", e.target.result); } reader.readAsDataURL(file); } }) } } window.onload = function () { var hichart = new Hichart(); hichart.init(); } })()
完整demo請查看我的github,地址:https://github.com/jianwenjua...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108777.html
摘要:流控制通常就是在客戶端的頁面使用一個隱藏的窗口向服務端發出一個長連接的請求。和長鏈接以上幾種服務器推的技術中長輪詢和流控制其實都是基于長鏈接來實現的,也就是中所謂的。通信協議于年被定為標準,并被所補充規范。 初探WebSocket node websocket socket.io 我們平常開發的大部分web頁面都是主動‘拉’的形式,如果需要更新頁面內容,則需要刷新一個,但Slack工...
摘要:當數據發生變化,便將數據發送給。與網絡應用中,兩個應用程序同時需要向對方發送消息的能力即全雙工通信,所利用到的技術就是,其能夠提供端對端的通信。其不僅支持,還支持許多種輪詢機制以及其他實時通信方式,并封裝了通用的接口。 WebSocket 與 Socket.IO 最近小組在做一個智慧交通的項目,其中有個 分享屏幕 的功能,即一個 client 能夠將自己當前的頁面分享到另外一個 cli...
摘要:早期的輪詢是通過不斷自動刷新頁面而實現的。長輪詢的另一個問題是缺乏標準實現。服務器端接到這個請求后作出回應并不斷更新連接狀態以保證客戶端和服務器端的連接不過期。協議解析協議包含兩部分一部分是握手,一部分是數據傳輸。 Websocket是什么? Websocket是一個因為應用場景越來越復雜而提出的,針對瀏覽器和web服務器之間雙向持續通信而設計,而且優雅地兼容HTTP的協議(我猜想:同...
摘要:服務端確認協議版本,升級為協議。自己寫了一個例子,服務端在開始連接后,利用定時器主動向客戶端發送隨機數,客戶端也可以發給服務器消息,然后服務器返回這條消息給客戶端。做的事情就是給頁面的元素綁定事件。 寫在前面webSocket是一項可以讓服務器將數據主動推送給客戶端的技術。前幾天寫了一個日志功能,日志數據需要實時更新。正好項目中有封裝好的WebSocket組件,且接口支持webSock...
閱讀 857·2021-10-11 10:59
閱讀 2792·2019-08-30 15:43
閱讀 2129·2019-08-30 11:08
閱讀 1647·2019-08-29 15:20
閱讀 1002·2019-08-29 13:53
閱讀 486·2019-08-26 13:24
閱讀 1632·2019-08-26 13:24
閱讀 2819·2019-08-26 12:08