結構:
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理解成只跑一次連接流程,只到把所有的事情都做完了才回去。
————————————————
版權聲明:本文為CSDN博主「yiqiebyjian」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/yiqiebyjian/article/details/79644482
nodejs系列(10)實現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"/>'; 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文檔。