整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          這是即時(shí)通訊的 4 種實(shí)現(xiàn)方案

          const http = require('http');
          const fs = require('fs');
          const app = http.createServer((req, res) => {
              // 設(shè)置響應(yīng)頭
              res.setHeader('Content-type', 'application/json; charset=utf-8');
              res.setHeader('Cache-Control', 'max-age=0'); // 沒有緩存
              let num = 0;
              // 地柜返回
              const send = () => {
                  if (num > 20) {
                      res.end();
                      return;
                  }
                  num++;
                  const data = Math.random() + '';
                  res.write(data, 'utf8');
                  setTimeout(send, 1000);
              }
              send();
          });
          app.listen(8081, () => {
              console.log('127.0.0.1:8081');
          })
          

          前端監(jiān)聽的事件,每當(dāng)服務(wù)器返回一段數(shù)據(jù)都會(huì)觸發(fā)一次事件,可以從中得到當(dāng)前獲取到的全部數(shù)據(jù)。

          var xhr = new XMLHttpRequest();
          xhr.open('GET', '/api');
          xhr.timeout = 30000;
          xhr.responseType = 'text';
          xhr.onreadystatechange = function () {
              if (this.readyState == 3) { // 分段獲取服務(wù)端返回的數(shù)據(jù)
                  console.log(this.responseText);
              }
              if (this.readyState == 4) {
                  if (this.status >= 200 && this.status < 300 || this.status == 304) {
                      // this.response
                  } else {
                      // this.statusText
                  }
              }
          }
          xhr.send()
          

          2.

          具有三個(gè)優(yōu)點(diǎn),雙向通信,自動(dòng)跨域,性能高。最主要的是可以傳輸多種格式的數(shù)據(jù)。 協(xié)議在2008年誕生,2011年成為國(guó)際標(biāo)準(zhǔn)。所有瀏覽器都已經(jīng)支持了,也是應(yīng)用很廣泛的一種即時(shí)通信協(xié)議。

          是HTML5新增的API,屬于瀏覽器或者前端的內(nèi)容。后端用的是socket,socket協(xié)議的歷史相當(dāng)古老基本四十年前就已經(jīng)存在了。在H5中自帶一些安全的措施,而原生的socket就沒什么安全性可言了。

          客戶端瀏覽器通過實(shí)例化,傳入服務(wù)地址創(chuàng)建鏈接,message中會(huì)接收到服務(wù)端推送的數(shù)據(jù),也可通過send方法向服務(wù)端發(fā)送數(shù)據(jù)。

          const ws = new Websocket('ws://127.0.0.1:8080/api');
          // 原生沒有emit,自己封裝一個(gè)
          ws.emit = function(name, ...args) {
              ws.send(JSON.stringify({
                  name,
                  data: [...args]
              }))
          }
          ws.onopen = function() {
              console.log('鏈接上了');
              // ws.send('dadadadadasda'); // 發(fā)送數(shù)據(jù),只有一個(gè)參數(shù)一個(gè)大字符串
              ws.emit('msg', 12, 5, 8);
          }; // 已經(jīng)鏈接
          ws.onmessage = function() {
              console.log('接收到消息了')
          }; // 收到數(shù)據(jù)
          ws.onclose = function() {
              console.log('斷開鏈接了')
          }; // 斷開了
          

          在node中想要實(shí)現(xiàn)socket可以借助node原生的net模塊,這是一個(gè)相對(duì)底層的網(wǎng)絡(luò)模塊,是一個(gè)tcp的庫(kù)。net是http的底層,很多東西都需要自己去實(shí)現(xiàn),比如這里可以使用net.來創(chuàng)建服務(wù)。

          也是給予http的,先通過http請(qǐng)求到服務(wù),會(huì)攜帶一個(gè)upgrade為的請(qǐng)求頭,表示希望升級(jí)為,這個(gè)時(shí)候服務(wù)可以返回101狀態(tài)碼,表示進(jìn)行服務(wù)可以升級(jí)。

          實(shí)時(shí)庫(kù)種數(shù)據(jù)有哪些類型_實(shí)時(shí)數(shù)據(jù)庫(kù)有幾種_實(shí)時(shí)庫(kù)種數(shù)據(jù)有哪些

          const http = require('http');
          const net = require('net'); // TCP的庫(kù),可以理解為原生的Socket
          const crypto = require('crypto'); // 借助加密庫(kù)實(shí)現(xiàn)一些安全性
          const server = net.createServer(sock=> {
              console.log('鏈接上了');
              sock.on('end', () => {
                  console.log('客戶端斷開了')
              }); // 斷開
              sock.once('data', (data) => {
                  console.log('hand shake start...');
                  // 最先過來的是http頭
                  const str = data.toString();
                  // 將http頭用\r\n切開
                  let lines = str.split('\r\n');
                  // 刪除第一行和最后一行,因?yàn)闆]啥用
                  lines = lines.slice(1, lines.length - 2);
                  // 將所有請(qǐng)求頭通過'分號(hào)空格'切開
                  const headers = {};
                  lines.forEach(line => {
                      const [key, value ] = line.split(': ');
                      // 將請(qǐng)求頭變成小寫
                      headers[key.toLowerCase()] = val;
                  })
                  // http協(xié)議轉(zhuǎn)websocket會(huì)傳入upgrade為websocket
                  if (headers['upgrade'] != 'websocket') {
                      console.log('其他協(xié)議,暫不支持');
                      sock.end();
                  } else if (headers['sec-websocket-version'] != 13) {
                      console.log('不兼容不是13的版本');
                      sock.end();
                  } else {
                      const key = headers['sec-websocket-key'];
                      // 13版本的源碼是258E,可以百度的到
                      const mask = '258EAFA5-47DA-95CA-C5AB0DC85B11';
                      // 需要把key和mask加在一起,然后用sha1加密,再變成base64,還給客戶端
                      // sha1(key + mask) -> base64 -> client;
                      const hash = crypto.createHash('sha1');
                      hash.update(key + mask);
                      const tokey = hash.digest('base64');
                      // 數(shù)據(jù)以HTTP發(fā)回客戶端,因?yàn)轵?yàn)證的過程還是http階段, 狀態(tài)值為101(正在切換協(xié)議,協(xié)議升級(jí) Switching Protocols)
                      sock.write('HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: ' + tokey + '\r\n'); // Upgrade: websocket告訴瀏覽器升級(jí)為websocket,冒號(hào)要有空格
                      // 至此,握手已經(jīng)結(jié)束了。因?yàn)槲帐值倪^程只有一次,所以不要用on處理,用once處理
                      // 從這里開始,才是真正的數(shù)據(jù),以后所有的數(shù)據(jù)都走這里,所以用on處理
                      sock.on('data', data => {
                          // 獲取到的數(shù)據(jù)
                          // 不過數(shù)據(jù)是一個(gè)buffer的數(shù)據(jù)包,解析起來比較麻煩。
                          console.log(data);
                      })
                  }
              }); // 有數(shù)據(jù)過來
          }).listen(8080);
          

          上面介紹的是的一個(gè)實(shí)現(xiàn)原理,項(xiàng)目中可以直接使用socket.io這個(gè)庫(kù)。

          前端代碼如下:

          const sock = io.connect('ws://127.0.0.1:8080/api');
          sock.on('connect', () => {
              console.log('已鏈接');
              sock.emit('aaa', 12, 5,8);
              sock.on('time', (ts) => {
                  console.loh(ts);
              })
          });
          sock.on('disconnect', () => {
              console.log('已斷開');
          });
          

          服務(wù)端代碼如下:

          實(shí)時(shí)庫(kù)種數(shù)據(jù)有哪些_實(shí)時(shí)庫(kù)種數(shù)據(jù)有哪些類型_實(shí)時(shí)數(shù)據(jù)庫(kù)有幾種

          const http = require('http');
          const io = require('socket.io');
          // 創(chuàng)建http服務(wù),開啟8080端口號(hào)
          const httpServer = http.createServer().listen(8080);
          // socket監(jiān)聽http服務(wù)
          const wsServer = io.listen(httpServer);
          // 當(dāng)有鏈接的時(shí)候
          wsServer.on('connection', sock => {
              // 發(fā)送
              // sock.emit
              sock.emit('time', Date.now());
              // 接收
              sock.on('aaa', (a, b, c) => {
                  console.loh(a, b, c);
              })
          })
          

          3. SSE

          SSE全稱是Server-Sent Events,指的是網(wǎng)頁(yè)自動(dòng)獲取來自服務(wù)器的更新,也就是自動(dòng)獲取服務(wù)端推送至網(wǎng)頁(yè)的數(shù)據(jù),這是一個(gè)H5的屬性,除了IE,其它標(biāo)準(zhǔn)瀏覽器基本都兼容。

          實(shí)現(xiàn)方式和第二種有一些像,服務(wù)器向客戶端聲明要發(fā)送流信息,然后連續(xù)不斷地發(fā)送過來。這時(shí)客戶端是不會(huì)關(guān)閉連接的,會(huì)一直等著服務(wù)器發(fā)過來的新的數(shù)據(jù)流。比如音視頻的媒體流就是這種機(jī)制。

          SSE 只能服務(wù)器向?yàn)g覽器發(fā)送數(shù)據(jù),這點(diǎn)和第二種方式很像,能力上都不如,優(yōu)點(diǎn)是SSE使用更加簡(jiǎn)單,并且基于http協(xié)議,兼容性還可以(當(dāng)然2022年了,沒有啥是兼容性不可以的了)。

          H5端使用對(duì)象,填入要請(qǐng)求的url地址就可以了。

          var source = new EventSource('/api', {
              withCredentials: true
          });
          source.onopen = function () {
              console.log('鏈接已建立', this.readyState);
          }
          source.onmessage = function (event) {
              console.log('實(shí)時(shí)獲取的數(shù)據(jù)', event.data);
          }
          source.onerror = function () {
              console.log('發(fā)生錯(cuò)誤');
          }
          // 關(guān)閉
          // source.close();
          

          服務(wù)器向?yàn)g覽器發(fā)送的 SSE 數(shù)據(jù),首先必須設(shè)置響應(yīng)頭的Content-type為text/event-stream,且編碼格式為utf-8。返回的數(shù)據(jù)格式必須為data: xxxx\n\n。除了data還有event,id,以及retry,可以參考Server--mdn。

          服務(wù)端代碼如下:

          const http = require('http');
          const fs = require('fs');
          const app = http.createServer((req, res) => {
              res.setHeader('Content-type', 'text/event-stream; charset=utf-8');
              res.setHeader('Cache-Control', 'max-age=0'); // 清楚緩存
              res.setHeader('Access-Control-Allow-Origin', 'http:127.0.0.1/');
              let num = 0;
              const send = () => {
                  if (num > 20) {
                      res.end();
                      return;
                  }
                  num++;
                  const data = Math.random() + '';
                  res.write(`data: ${data}\n\n`, 'utf8');
                  setTimeout(send, 1000);
              }
              send();
          });
          app.listen(8081, () => {
              console.log('127.0.0.1:8081');
          })
          

          4. ajax

          ajax輪詢,這個(gè)沒啥好說的,是個(gè)人都想的到,就不介紹了。

          沒錯(cuò),這條就是用來湊數(shù)的。


          主站蜘蛛池模板: 中文字幕在线视频一区| 色窝窝无码一区二区三区| 性色A码一区二区三区天美传媒| 久久一区二区精品综合| 国产高清一区二区三区视频| 精品国产亚洲一区二区三区| 国产一区二区精品久久91| 一区二区在线电影| 国产一区二区精品尤物| 免费视频精品一区二区| 亚欧在线精品免费观看一区| 另类一区二区三区| 东京热无码av一区二区| 无码av不卡一区二区三区| 精品国产一区二区三区久久影院 | 伊人无码精品久久一区二区| 性无码免费一区二区三区在线| 丝袜人妻一区二区三区| 亚洲午夜日韩高清一区| 国产日韩AV免费无码一区二区三区| 爱爱帝国亚洲一区二区三区| 无码夜色一区二区三区| 亚洲av成人一区二区三区在线播放 | 久久精品一区二区国产| 波多野结衣av高清一区二区三区| 国产福利微拍精品一区二区| 亚洲熟妇av一区| 国产对白精品刺激一区二区| 亚洲国产成人久久综合一区| 精品无码AV一区二区三区不卡| 亚欧成人中文字幕一区| 91精品福利一区二区三区野战| 少妇激情AV一区二区三区| 日韩AV无码久久一区二区| 亚洲综合在线成人一区| 亚洲AV日韩AV一区二区三曲| 在线视频亚洲一区| 香蕉一区二区三区观| 国产一区二区免费视频| 亚洲乱码一区av春药高潮| 亚洲AV无码国产精品永久一区 |