這篇文章僅對不熟悉在react中使用socket.io的人、以及websocket入門者有幫助。javascript
下面這個動態圖展現的聊天系統是用react+express+websocket搭建的,很模糊吧,要得就是這樣的效果,我本身開了2個窗口,建立2個用戶自問自答。沒有什麼高深的技術,對於不少想接觸websocket的前端工程師來講,不擅長後端的websocket代碼多是硬傷。前端
服務端:express服務器java
客戶端:react技術棧,開發環境採用前端服務器的方式,打包後將靜態資源放到服務端目錄下作測試。react
想要實現一種實時的雙向通訊聊天系統,你可能會想到ajax輪詢(長或短),但你最想要的仍是websocket的實現。web
在寫測試代碼以前,我糾結於前端用什麼,後端用什麼,後來後端選擇了express、前端是react。ajax
一、服務端使用到的js庫mongodb
express socket.io
二、前端使用到的js庫express
"react": "^16.2.0", "react-dom": "^16.2.0", "socket.io-client": "^2.0.4"
服務端的實現我不想多講,你能夠去看官方demo,代碼很詳細:socket官方demo實現redux
服務端的核心代碼:後端
io.on('connection', function (socket) { // 當客戶端發出「new message」時,服務端監聽到並執行相關代碼 socket.on('new message', function (data) { // 廣播給用戶執行「new message」 socket.broadcast.emit('new message', {}); }); // 當客戶端發出「add user」時,服務端監聽到並執行相關代碼 socket.on('add user', function (username) { socket.username = username; //服務端告訴當前用戶執行'login'指令 socket.emit('login', {}); }); // 當用戶斷開時執行此指令 socket.on('disconnect', function () {}); });
socket和mongodb有點像,它須要建立一個socket服務,建立成功以後,就能夠經過on()去監聽一個action,action在這裏表示的是 'new message'、'add user'、'login'等指令,這些指令是能夠本身命名的。
這些指令有什麼做用呢?
當客戶端和服務端創建socket通訊以後,服務端能夠向客戶端發出指令,客戶端也能夠向服務端發出指令,開發者須要先給雙方的通訊約定一套指令系統。
好比服務端建立了一個 'new message'的指令,可是客戶端沒有建立這個指令,就會致使客戶端沒法接收到服務端發出的這個指令。客戶端內心可能在想:服務端老兄在瞎bb什麼?
客戶端也須要 ’new message’指令,這樣雙方就能達成一套通訊的協議,雙方能夠互相發出這條指令告訴對方最新的狀態。
上面代碼提到了socket.emit()和socket.broadcast.emit()2種用法,能夠看看下面關於emit用法的詳細解釋。
// 發送到當前請求socket通訊的客戶端 socket.emit('message', "this is a test"); // 發送給全部客戶端,除了發件人 socket.broadcast.emit('message', "this is a test"); // 發送給「遊戲」房間(頻道)中的全部客戶,發件人除外 socket.broadcast.to('game').emit('message', 'nice game'); // 發送給全部的客戶,包括髮件人 io.sockets.emit('message', "this is a test"); // 發送給「遊戲」房間(頻道)的全部客戶,包括髮件人 io.sockets.in('game').emit('message', 'cool game'); // 發送給指定的socketid io.sockets.socket(socketid).emit('message', 'for your eyes only');
socket的這種行爲更像是redux,可是redux是單向數據流,而socket是雙向。
React端的實現,纔是咱們應該關注的重點。
做爲一個前端工程師,每每只須要和後端大神配合便可(全棧除外)。
一、在react組件中導入socket.io-client
前端使用的是socket.io-client庫,這個庫使用很是簡單。下面的代碼中,直接導入socket.io-client而且指向服務端的ip+端口便可。
import React, { Component } from 'react' //require('socket.io-client')('服務端ip+端口') const socket = require('socket.io-client')('http://localhost:3077'); class App extends Component { }
二、在componentDidMount寫socket的接收指令action
socket.on()設置了服務端約定好的指令,當服務端發出這些指令時,客戶端就能接收到。這時候,你能夠在回調函數裏面根據後端返回的數據 data 作前端的處理,好比設置state的狀態,渲染服務端推送的數據。
componentDidMount() { socket.on('login', (data) => { console.log(data) }); socket.on('add user', (data) => { console.log(data) }); socket.on('new message', (data) => { console.log(data) }); }
三、客戶端推送數據到服務端
不少時候,客戶端也須要告訴服務端有新的數據更新,當你在聊天界面發了一條新消息,這時候要告訴服務端,就經過socket.emit()方法,和服務端推送的方法是同樣的。
socket.emit('new message', value)
一、當你想要告訴對方一些話時,使用socket.emit()。
二、當你想接收對方的話時,使用socket.on()。
三、emit還有點對點、廣播等用法。
四、最後說一句,這些都是基礎知識。