日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

websocket 学习--简单使用,nodejs搭建websocket服务器,到模拟股票,到实现聊天室

發布時間:2025/3/12 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 websocket 学习--简单使用,nodejs搭建websocket服务器,到模拟股票,到实现聊天室 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

websocket簡介:

WebSocket協議是?HTML5 開始提供的一種基于TCP的一種新的全雙工通訊的網絡通訊協議。它允許服務器主動發送信息給客戶端

?

?

和http協議的不同??

HTTP 協議是一種無狀態的、無連接的、單向的應用層協議。它采用了請求/響應模型。通信請求只能由客戶端發起,服務端對請求做出應答處理。這種通信模型有一個弊端:HTTP 協議無法實現服務器主動向客戶端發起消息。而這種單向請求的特點,注定了如果服務器有連續的狀態變化,客戶端要獲知就非常麻煩。

簡單的說,WebSocket協議之前,實現雙工通信就是通過不停發送HTTP請求(長輪詢,使用?Ajax 輪詢技術,輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求),從服務器拉取更新來實現,這導致了效率低下,浪費帶寬資源,WebSocket解決了這個問題。

WebSocket 就是這樣發明的。WebSocket 連接允許客戶端和服務器之間進行全雙工通信,以便任一方都可以通過建立的連接將數據推送到另一端。WebSocket 只需要建立一次連接,就可以一直保持連接狀態。這相比于輪詢方式的不停建立連接顯然效率要大大提高。

?

?

websocket如何工作??

?

在實現websocket連線過程中,需要通過瀏覽器發出websocket連線請求,然后服務器發出回應,這個過程通常稱為"握手" 。在 WebSocket API 中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,并進行雙向數據傳輸相傳送。

?

?

瀏覽器通過 JavaScript 向服務器發出建立 WebSocket 連接的請求,連接建立以后,客戶端和服務器端就可以通過 TCP 連接直接交換數據。當你獲取 Web Socket 連接后,你可以通過?send()?方法來向服務器發送數據,并通過?onmessage?事件來接收服務器返回的數據。

?

以下 API 用于創建 WebSocket 對象。第一個參數 url, 指定連接的 URL。而URL參數需要以WS://或者WSS://開頭,例如:ws://www.websocket.org,如果URL有語法錯誤,構造函數會拋出異常。第二個參數 protocol 是可選的,指定了可接受的子協議。議的參數例如XMPP(Extensible?Messaging?and?Presence?Protocol)、SOAP(Simple?Object?Access?Protocol)或者自定義協議。??第二個參數是協議名稱,是可選的,服務端和客服端使用的協議必須一致,這樣收發消息彼此才能理解,你可以定義一個或多個客戶端使用的協議,服務端會選擇一個來使用,一個客服端和一個服務端之間只能有一個協議

var Socket = new WebSocket(url, [protocol] );

注意:基于多線程或多進程的服務器無法適用于 WebSockets,因為它旨在打開連接,盡可能快地處理請求,然后關閉連接。任何實際的 WebSockets 服務器端實現都需要一個異步服務器。

目前大部分瀏覽器支持 WebSocket() 接口,如 Chrome, Mozilla, Opera 和 Safari。

?

?

WS和WSS的區別??

注意:WebSocket協議定義了兩種URL方案,WS和WSS分別代表了客戶端和服務端之間未加密和加密的通信。WS(WebSocket)類似于Http URL,而WSS(WebSocket Security)URL 表示連接是基于安全傳輸層(TLS/SSL)和https的連接是同樣的安全機制。

?

?

?

websocket的屬性、事件、方法

屬性描述
Socket.readyState

只讀屬性?readyState?表示連接狀態,可以是以下值:

0 - 表示連接尚未建立。

1 - 表示連接已建立,可以進行通信。

2 - 表示連接正在進行關閉。

3 - 表示連接已經關閉或者連接不能打開。

Socket.bufferedAmount

只讀屬性?bufferedAmount?已被 send() 放入正在隊列中等待傳輸,但是還沒有發出的 UTF-8 文本字節數。

注意:上述readyState?屬性用于表示鏈接狀態!

?

事件事件處理程序描述
openSocket.onopen連接建立時觸發
messageSocket.onmessage客戶端接收服務端數據時觸發
errorSocket.onerror通信發生錯誤時觸發
closeSocket.onclose連接關閉時觸發

?

方法描述
Socket.send()

使用連接發送數據

Socket.close()

關閉連接

?

?

?

websocket+nodejs簡單實例應用

WebSocket 協議本質上是一個基于 TCP 的協議。為了建立一個 WebSocket 連接,客戶端瀏覽器首先要向服務器發起一個 HTTP 請求,這個請求和通常的 HTTP 請求不同,包含了一些附加頭信息,其中附加頭信息"Upgrade: WebSocket"表明這是一個申請協議升級的 HTTP 請求,服務器端解析這些附加的頭信息然后產生應答信息返回給客戶端,客戶端和服務器端的 WebSocket 連接就建立起來了,雙方就可以通過這個連接通道自由的傳遞信息,并且這個連接會持續存在直到客戶端或者服務器端的某一方主動的關閉連接。

WebSocket API是純事件驅動,一旦建立全雙工連接,當服務端給客戶端發送數據或者資源,它能自動發送狀態改變的數據和通知。所以你不需要為了狀態的更新而去輪訓Server,在客戶端監聽即可。

?

websocket客戶端:

<!DOCTYPE HTML> <html><head><meta charset="utf-8"><title>websocket測試(runoob.com)</title><script type="text/javascript">function WebSocketTest(){if ("WebSocket" in window){alert("您的瀏覽器支持 WebSocket!");// 初始化一個 WebSocket 對象,參數指明urlvar ws = new WebSocket("ws://localhost:9999");// WebSocket 連接時候觸發ws.onopen = function(){//使用 send() 方法發送數據ws.send("客戶端發送的數據");alert("數據發送中...");};// 接收服務端數據時觸發ws.onmessage = function (evt) { var received_msg = evt.data;console.log(received_msg);alert("數據已接收...");};//斷開 web socket 連接成功觸發事件ws.onclose = function(){ // 關閉 websocketalert("連接已關閉..."); };}else{// 瀏覽器不支持 WebSocketalert("您的瀏覽器不支持 WebSocket!");}}</script></head><body><div id="sse"><a href="javascript:WebSocketTest()">運行 WebSocket</a></div></body> </html>

?

websocket服務端:

WebSocket 在服務端的實現非常豐富。Node.js、Java、C++、Python 等多種語言都有自己的解決方案。這里主要記錄nodejs作為websocket服務端的解決方案。

Node 實現有以下三種。

  • μWebSockets
  • Socket.IO
  • WebSocket-Node

?

這里主要記錄使用nodejs搭建websocket服務器的方案

ws 是nodejs的一個WebSocket庫,可以用來創建服務。使用cnpm install ws 命令行進行安裝

下面是server.js的文件內容,cmd轉到文件目錄運行 node server.js? 命令行

?

var WebSocketServer = require('ws').Server, wss = new WebSocketServer({ port: 9999 }); wss.on('connection', function (ws) {console.log('client connected');ws.on('message', function (message) {console.log(message);ws.send("服務端接收到請求后,發送給客戶端的數據");});});

效果如下:

?

?

?

進階:websocket+nodejs模擬股票實例

上面的例子很簡單,只是為了演示如何運用nodejs的ws創建一個WebSocket服務器。且可以接受客戶端的消息。那么下面這個例子演示股票的實時更新。客服端只需要連接一次,服務器端會不斷地發送新數據,客戶端收數據后更新UI.頁面如下,有五只股票,開始和停止按鈕測試連接和關閉。

注意:一定要先在項目文件夾下運行?cnpm install ws ?安裝wwebsocket依賴包,不然會報以下錯誤

?

?

服務端server.js文件內容如下:

//引入websocket 的ws模塊 var WebSocketServer = require('ws').Server,//初始化websocket對象 wss = new WebSocketServer({ port: 8181 });//初始數據對象 var stocks = {"AAPL": 95.0,"MSFT": 50.0,"AMZN": 300.0,"GOOG": 550.0,"YHOO": 35.0 }//獲取隨機數據的函數 function randomInterval(min, max) {return Math.floor(Math.random() * (max - min + 1) + min); }//定時器返回的句柄 var stockUpdater; var randomStockUpdater=function(){for (var symbol in stocks) { //遍歷對象屬性進行隨機增加浮動數值if(stocks.hasOwnProperty(symbol)) { //遍歷對象非繼承屬性var randomizedChange = randomInterval(-150, 150);var floatChange = randomizedChange / 100;stocks[symbol] += floatChange;}}//隨機時間間隔,獲取一個數據區間中的隨機數值var randomMSTime = randomInterval(500, 2500); stockUpdater = setTimeout(function() { //模擬股票數據變化,隨機更改對象屬性值randomStockUpdater();}, randomMSTime);}//執行模擬數據變化更新 randomStockUpdater();//聲明clientStocks接收客戶端數據 var clientStocks = [];//連接建立后 wss.on('connection', function (ws) {//定義數據更新函數var sendStockUpdates = function (ws) {if (ws.readyState == 1) { //readyState為1表示已經建立連接var stocksObj = {};for (var i = 0; i < clientStocks.length; i++) {var symbol = clientStocks[i];stocksObj[symbol] = stocks[symbol];}if (stocksObj.length !== 0) { //數據包內容不為空時將數據響應給客戶端ws.send(JSON.stringify(stocksObj));//需要將對象轉成字符串。WebSocket只支持文本和二進制數據console.log("更新", JSON.stringify(stocksObj));}}}//服務器端定時更新響應數據var clientStockUpdater = setInterval(function () {sendStockUpdates(ws);}, 1000);//服務器端接收到客戶端發送過來的數據,根據請求的數據更新響應數據ws.on('message', function (message) {var stockRequest = JSON.parse(message);console.log("服務器收到的消息:", stockRequest);clientStocks = stockRequest['stocks'];sendStockUpdates(ws);});});

?

客戶端client.html 文件如下,界面使用了和jquery和bootstrape框架

<html xmlns="http://www.w3.org/1999/xhtml"> <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>WebSocket Demo</title><meta name="viewport" content="width=device-width, initial-scale=1"/><link href="../bootstrap-3.3.5/css/bootstrap.min.css" rel="stylesheet" /><script src="../js/jquery-1.12.3.min.js"></script><script src="../bootstrap-3.3.5/js/bootstrap.min.js"></script> </head><body> <div class="vertical-center"><div class="container"><h1>Stock Chart over WebSocket</h1><button class="btn btn-primary">開始</button><button class="btn btn-danger">停止</button><table class="table" id="stockTable"><thead><tr><th>Symbol</th><th>Price</th></tr></thead><tbody id="stockRows"><tr><td><h3>AAPL</h3></td><td id="AAPL"><h3><span class="label label-default">95.00</span></h3></td></tr><tr><td><h3>MSFT</h3></td><td id="MSFT"><h3><span class="label label-default">50.00</span></h3></td></tr><tr><td><h3>AMZN</h3></td><td id="AMZN"><h3><span class="label label-default">300.00</span></h3></td></tr><tr><td><h3>GOOG</h3></td><td id="GOOG"><h3><span class="label label-default">550.00</span></h3></td></tr><tr><td><h3>YHOO</h3></td><td id="YHOO"><h3><span class="label label-default">35.00</span></h3></td></tr></tbody></table></div> </div><script>//客戶端初始化websocket對象var ws = new WebSocket("ws://localhost:9999");//客戶端發送的請求對象var stock_request = { "stocks": ["AAPL", "MSFT", "AMZN", "GOOG", "YHOO"] };var isClose = false; //通訊連接是否被關閉//界面的初始化數據對象var stocks = {"AAPL": 0, "MSFT": 0, "AMZN": 0, "GOOG": 0, "YHOO": 0};//定義更新UI界面的函數function updataUI() {//websocket連接上時觸發ws.onopen = function (e) {console.log('Connection to server opened');isClose = false;ws.send(JSON.stringify(stock_request));console.log("sened a mesg");}// UI update functionvar changeStockEntry = function (symbol, originalValue, newValue) {var valElem = $('#' + symbol + ' span');valElem.html(newValue.toFixed(2)); //toFixed() 方法可把 Number 四舍五入為指定小數位數的數字。if (newValue < originalValue) {valElem.addClass('label-danger');valElem.removeClass('label-success');} else if (newValue > originalValue) {valElem.addClass('label-success');valElem.removeClass('label-danger');}}// websocket接收到服務端數據時觸發ws.onmessage = function (e) {var stocksData = JSON.parse(e.data); //字符串轉JSON對象console.log(stocksData);for (var symbol in stocksData) { //遍歷對象屬性,更改客戶端界面數據if (stocksData.hasOwnProperty(symbol)) {changeStockEntry(symbol, stocks[symbol], stocksData[symbol]);stocks[symbol] = stocksData[symbol];}}};}updataUI(); //更新UI界面$(".btn-primary").click(function() { //開始按鈕點擊可以在斷開后重連websocketif (isClose) {ws = new WebSocket("ws://localhost:9999");}updataUI(); //重連后更新UI界面});$(".btn-danger").click(function() { //斷開按鈕可以關閉websocket連接ws.close();});//觸發websocket連接關閉事件ws.onclose = function (e) {console.log("Connection closed", e);isClose = true;};</script> </body> </html>

源碼見文章底部鏈接,效果如下:

?

?

?

進階:websocket+nodejs模擬聊天室實例

?

上面的例子是連接建立之后,服務端不斷給客戶端發送數據。接下來例子是一個簡單的聊天室類的例子。可以建立多個連接。

1.安裝node-uuid模塊,用來給每個連接一個唯一號。

2、客戶端代碼如下:

<html xmlns="http://www.w3.org/1999/xhtml"> <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>WebSocket Echo Demo</title><meta name="viewport" content="width=device-width, initial-scale=1"/><link href="../bootstrap-3.3.5/css/bootstrap.min.css" rel="stylesheet" /><script src="../js/jquery-1.12.3.min.js"></script><script src="../js/jquery-1.12.3.min.js"></script><script src="../bootstrap-3.3.5/js/bootstrap.min.js"></script><script>//建立連接var ws = new WebSocket("ws://localhost:8181");var nickname = "";ws.onopen = function (e) {console.log('Connection to server opened');}//顯示函數,根據客戶端接收到的數據類型進行ui界面顯示function appendLog(type, nickname, message) {if (typeof message == "undefined") return;var messages = document.getElementById('messages');var messageElem = document.createElement("li");var preface_label;if (type === 'notification') {preface_label = "<span class=\"label label-info\">*</span>";} else if (type == 'nick_update') {preface_label = "<span class=\"label label-warning\">*</span>";} else {preface_label = "<span class=\"label label-success\">"+ nickname + "</span>";}var message_text = "<h2>" + preface_label + "&nbsp;&nbsp;"+ message + "</h2>";messageElem.innerHTML = message_text;messages.appendChild(messageElem);}//收到消息處理ws.onmessage = function (e) {var data = JSON.parse(e.data);nickname = data.nickname;appendLog(data.type, data.nickname, data.message);console.log("ID: [%s] = %s", data.id, data.message);}ws.onclose = function (e) {appendLog("Connection closed");console.log("Connection closed");}//發送消息function sendMessage() {var messageField = document.getElementById('message');if (ws.readyState === WebSocket.OPEN) {ws.send(messageField.value);}messageField.value = '';messageField.focus();}//修改名稱function changName() {var name = $("#name").val();if (ws.readyState === WebSocket.OPEN) {ws.send("/nick " + name);}}function disconnect() {ws.close();}</script> </head><body ><div class="vertical-center"><div class="container"><ul id="messages" class="list-unstyled"></ul><hr/><form role="form" id="chat_form" onsubmit="sendMessage(); return false;"><div class="form-group"><input class="form-control" type="text" id="message" name="message"placeholder="Type text to echo in here" value="" autofocus/></div><button type="button" id="send" class="btn btn-primary"onclick="sendMessage();">Send Message</button></form><div class="form-group"><span>nikename:</span><input id="name" type="text" /> <button class="btn btn-sm btn-info" onclick="changName();">change</button></div></div></div> </body> </html>

?

3、服務端代碼如下:

//引入ws模塊,初始化websocket服務端 var WebSocket = require('ws'); var WebSocketServer = WebSocket.Server, wss = new WebSocketServer({ port: 8181 });//引入node-uuid模塊,唯一標識 var uuid = require('node-uuid');//客戶端數組 var clients = [];//遍歷所有客戶端連接,依次下發數據 function wsSend(type, client_uuid, nickname, message) {for (var i = 0; i < clients.length; i++) {var clientSocket = clients[i].ws;if (clientSocket.readyState === WebSocket.OPEN) {clientSocket.send(JSON.stringify({ //websocket傳遞JSONA字符串格式"type": type,"id": client_uuid,"nickname": nickname,"message": message}));}} }var clientIndex = 1;//每一個客戶端和服務端建立連接時觸發 wss.on('connection', function(ws) {var client_uuid = uuid.v4(); //獲取隨機唯一標識var nickname = "AnonymousUser" + clientIndex;clientIndex += 1;clients.push({ "id": client_uuid, "ws": ws, "nickname": nickname });console.log('client [%s] connected', client_uuid);var connect_message = nickname + " has connected";wsSend("notification", client_uuid, nickname, connect_message);console.log('client [%s] connected', client_uuid);ws.on('message', function(message) {if (message.indexOf('/nick') === 0) { //json字符串數據包含修改昵稱的數據時var nickname_array = message.split(' ');if (nickname_array.length >= 2) {var old_nickname = nickname;nickname = nickname_array[1];var nickname_message = "Client " + old_nickname + " changed to " + nickname;wsSend("nick_update", client_uuid, nickname, nickname_message);}} else {wsSend("message", client_uuid, nickname, message);}});//斷開指定uuid的連接var closeSocket = function(customMessage) {for (var i = 0; i < clients.length; i++) {if (clients[i].id == client_uuid) {var disconnect_message;if (customMessage) {disconnect_message = customMessage;} else {disconnect_message = nickname + " has disconnected";}wsSend("notification", client_uuid, nickname, disconnect_message);clients.splice(i, 1);}}};//某個客戶端連接斷開時觸發ws.on('close', function () {closeSocket();});//SIGINT這個信號是系統默認信號,代表信號中斷,就是ctrl+cprocess.on('SIGINT', function () {console.log("Closing things");closeSocket('Server has disconnected');process.exit();}); });

效果如下:

源碼見文章尾部

?

上述代碼實現了一個服務器下的多個客戶端連接,單并沒有實現客戶端的及時通訊,比如微信和QQ的單聊和群聊效果,可以參考以下demo

參考網址:https://blog.csdn.net/CJXBShowZhouyujuan/article/details/77816944

?

?

?

node-uuid是什么??

?

nodejs生成UID(唯一標識符)——node-uuid模塊

unique identifier 惟一標識符 ? ? ? ?-->> uid

在項目開發中我們常需要給某些數據定義一個唯一標識符,便于尋找,關聯。node-uuid模塊很好的提供了這個功能。

?

使用起來很簡單,兩種:

1、uuid.v1(); -->基于時間戳生成 ?(time-based)

2、uuid.v4(); -->隨機生成 ?(random)

?

通常我們使用基于時間戳 ?v1() ?生成的UID,隨機生成 ?v4() ?還是有一定幾率重復的。

var UUID = require('uuid');var ID = UUID.v1();

?

?

websocket 和 socket 的區別??

軟件通信有七層結構,下三層結構偏向與數據通信,上三層更偏向于數據處理,中間的傳輸層則是連接上三層與下三層之間的橋梁,每一層都做不同的工作,上層協議依賴與下層協議。基于這個通信結構的概念。

Socket 其實并不是一個協議,是應用層與 TCP/IP 協議族通信的中間軟件抽象層,它是一組接口。當兩臺主機通信時,讓 Socket 去組織數據,以符合指定的協議。TCP 連接則更依靠于底層的 IP 協議,IP 協議的連接則依賴于鏈路層等更低層次。

WebSocket 則是一個典型的應用層協議。

總的來說:Socket 是傳輸控制層協議,WebSocket 是應用層協議。

?

?源碼:http://pan.baidu.com/s/1c2FfKbA

或 百度鏈接:https://pan.baidu.com/s/1cabjJKikHC3xBW-qUtP-3g? ?提取碼:yb4u?
?

參考網址:

https://www.cnblogs.com/stoneniqiu/p/5402311.html

http://www.runoob.com/html/html5-websocket.html

總結

以上是生活随笔為你收集整理的websocket 学习--简单使用,nodejs搭建websocket服务器,到模拟股票,到实现聊天室的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。