1. 程式人生 > 程式設計 >Nodejs環境實現socket通訊過程解析

Nodejs環境實現socket通訊過程解析

結構:

socket是應用層和傳輸層的橋樑。(傳輸層之上的協議所涉及的資料都是在本機處理的,並沒進入網路中)

涉及資料:

socket所涉及的資料是報文,是明文。

作用:

建立長久連結,供網路上的兩個程序通訊。

nodejs環境下的簡單通訊。

程式碼:

serve:

// 1 引入模組
const net = require('net');
// 2 建立伺服器
let clientArr = [];
const server = net.createServer();
// 3 繫結連結事件
server.on('connection',(person)=>{
console.log(clientArr.length);
// 記錄連結的程序
person.id = clientArr.length;
clientArr.push(person);
person.setEncoding('utf8');
// 客戶socket程序繫結事件
person.on('data',(chunk)=>{
console.log(chunk);
clientArr.forEach((val)=>{
// 資料寫入全部客戶程序中
val.write(chunk);
})
})
person.on('close',(p1)=>{
clientArr[p1.id] = null;
} )
person.on('error',(p1)=>{
clientArr[p1.id] = null;
})
})
server.listen(800);

client:

// 1 引入模組
const net = require('net');
const readline = require('readline');
// 2 建立套接字和輸入輸出命令列
let rl = readline.createInterface({
// 呼叫std介面
input:process.stdin,output:process.stdout
})
let client = new net.Socket();
// 3 連結
client.connect(800,'localhost');

client.setEncoding('utf8');
client.on('data',(chunk)=>{

})
client.on('error',(e)=>{
console.log(e.message);
})
// 繫結輸io流事件,獲取輸入輸出字元
rl.on('line',(mes)=>{
client.write(mes);
})

小結:

server端:繫結連線事件 --> 在連線事件中管理客戶端程序物件(1,把新增到陣列中 2,處理客戶端發來的資料)-->開啟埠監聽請求 。

client端:建立連線伺服器用的套接字 --> 連線伺服器 。

socket建立的連線是長久連線。而應用層的http協議是3次握手協議,是短連線。

socket工作原理和http類似,只是不規定斷開連線的時間。可以把http理解成一個人辦一件事情就跑一次連線流程。socket理解成只跑一次連線流程,只到把所有的事情都做完了才回去。

Socket主要作用是實現客戶端與服務端的實時通訊保持通話,它不像ajax請求,每次對話完成後都會把連線斷開。Socket通訊在

Node.js中實現其實很簡單,沒有想象中複雜,基本上只要懂得監聽(.on)和推送(.emit)訊息,即能實現Socket通訊。

Socket服務端

在服務端使用Socket,需先引入socket.io模組,該模組詳細文件可參考https://socket.io/:

cnpm install socket.io

服務端例項程式碼如下:

var server = app.listen(8081,"127.0.0.1",function() {
  var host = server.address().address;
  var port = server.address().port;
});
 
/********************socketIO********************/
var io = require('socket.io').listen(server);
// 建立連線
io.sockets.on('connection',function(socket) { //此處每個回撥socket就是一個獨立的客戶端,通常會用一個公共列表陣列統一管理
  // 連線斷開,如關閉頁面時觸發
  socket.on('disconnect',function() {
    console.log('已斷開連結');
  });
  // 監聽客戶端傳送的訊息
  socket.on('clientmessage',function(data) {
    //推送給除自己外其他所有使用者的訊息,類似於廣播
    socket.broadcast.emit('message',{
      text: '你的朋友上線了'
    });
  });
  //傳送給自己的訊息
  socket.emit('message',{
    text: '你上線了'
  });
});

上例中實現了4步:

1. 建立連線並新增斷開連線監聽。

2. 建立clientmessage監聽,當客戶端發來該名稱的事件時,伺服器向除自己外其他的使用者廣播事件名稱為message的訊息。

3.在剛建立連線時,向客戶端推送事件名稱為message的訊息。

其中主要應用到的函式有5個:

  • .on('connection',function(socket){ }):與客戶端建立連線時監聽。
  • .on('disconnect',function(){ }):與客戶端斷開連線時監聽。
  • .on('event-name',function(data) { }):監聽客戶端發來的訊息。
  • .broadcast.emit('event-name',{ }):向除自己外的所有其他使用者廣播訊息。
  • .emit('event-name',{ }):僅向當前連線的客戶端(自己)推送訊息。

(注)相關客戶端的介面關聯請往下看客戶端的例子。

Socket客戶端

需先去下載socket.io.js檔案,下載地址為:https://github.com/socketio/socket.io-client

客戶端例項程式碼如下:

<!DOCTYPE html>
<html>
 
  <head>
    <meta charset="UTF-8">
    <title>socketio測試</title>
    <script>
      var tmp_html = '<link rel="stylesheet" href="../js/libs/bootstrap/3.3.7/css/bootstrap.css" rel="external nofollow" />';
      tmp_html += '<script src="../js/libs/jquery/3.2.1/jquery.js"><\/script>';
      tmp_html += '<script src="../js/libs/bootstrap/3.3.7/bootstrap.js"><\/script>';
      tmp_html += '<script src="../js/libs/socketio/socket.io.js"><\/script>';
      document.write(tmp_html);
      document.close();
    </script>
  </head>
 
  <body>
    <button id="btn">傳送訊息</button>
  </body>
  <script>
    var socket = io.connect('http://127.0.0.1:8081');
    socket.on('message',function(data) {
      console.log(data.text);
    })
 
    $("#btn").click(function() {
      socket.emit('clientmessage',{
        text: "hello"
      });
    });
  </script>
</html>

客戶端主要應用到的函式有2個:

  • .on('event-name',function(data) { }):監聽服務端發來的訊息。
  • .emit('event-name',{ }):向服務端推送訊息。

Socket即時通訊就是那麼簡單,而且在連線斷開時還會自動重連。還有一種實現方法就是使用net模組的套接字,可以直接檢視Node.js文件。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。