一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - JAVA教程 - 利用Socket.io 實現消息實時推送功能

利用Socket.io 實現消息實時推送功能

2021-02-27 11:13noiron JAVA教程

這篇文章主要介紹了利用Socket.io 實現消息實時推送功能,需要的朋友可以參考下

項目背景介紹

最近在寫的項目中存在著社交模塊,需要實現這樣的一個功能:當發(fā)生了用戶被點贊、評論、關注等操作時,需要由服務器向用戶實時地推送一條消息。最終完成的項目地址為:https://github.com/noiron/socket-message-push,這里將介紹一下實現的思路及部分代碼。

項目的流程中存在著這樣的幾個對象:

  • 用 java 實現的后端服務器
  • 用 node.js 實現的消息推送服務器
  • 用戶進行操作的客戶端

事件處理的流程如下:

  • 用戶進行點贊操作時,后端服務器會進行處理,并向 node.js 消息推送服務器發(fā)送一條消息
  • node.js 消息推送服務器接收到后端發(fā)送的消息后,處理數據,并確定向哪個用戶進行推送
  • 用戶的客戶端接收到由 node.js 服務器推送來的消息后,即可進行通知的顯示。
  • 上面的流程中,java 后端服務器是如何實現的不在此篇文章的討論范圍內,本文將主要介紹如何使用 node.js 來實現這個消息推送服務器。

考慮消息推送服務器上必須記錄下當前在線用戶的信息,這樣才能向特定的用戶推送消息。所以當用戶登錄時,必須將自身的用戶信息發(fā)到 node.js 服務器上。為了達到這種雙向的實時消息傳遞,很明顯地考慮用 websocket 來實現。既然我們在消息推送服務器上使用了 node.js,我們就有了一個很方便的選項:socket.io。

socket.io 介紹

socket.io是一個用 javascript 實現的實時雙向通信的庫,利用它來實現我們的功能會很簡單。

socket.io 包含兩個部分:

  • 服務器端(server):運行在 node.js 服務器上
  • 客戶端(client):運行在瀏覽器中

可以看看如下的 socket.io 的示例代碼,它給出了 socket.io 發(fā)出及監(jiān)聽事件的基本用法:

?
1
2
3
4
5
io.on('connection', function(socket){
 socket.emit('request', /* */); // emit an event to the socket
 io.emit('broadcast', /* */); // emit an event to all connected sockets
 socket.on('reply', function(){ /* */ }); // listen to the event
});

關于 socket.io 還有一點需要注意:socke.io 并不完全是 websocket 的實現。

note: socket.io is not a websocket implementation. although socket.io indeed uses websocket as a transport when possible, it adds some metadata to each packet: the packet type, the namespace and the ack id when a message acknowledgement is needed.
接下來我們需要用 express.js 來建立一個服務器端程序,并在其中引入 socket.io。

node.js 服務器的搭建

利用 express.js 搭建基礎服務器

我們使用了 express.js 來搭建 node.js 消息推送服務器,先利用一個簡要的例子來瀏覽其功能:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// server.js
const express = require('express');
const app = express();
const path = require('path');
const http = require('http').server(app);
const port = 4001;
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res) {
 res.sendfile(__dirname + '/public/index.html');
});
app.get('/api', function(req, res) {
 res.send('.');
});
http.listen(port, function() {
 console.log(`listening on port:${port}`);
});

將上面的代碼保存為 server.js,新建一個 public 文件夾,在其中放入 index.html 文件。運行以下命令:

node server.js

現在即可在 localhost:4001 查看效果了。

引入 socket.io

現在已經有了一個基礎的 express 服務器,接下來需要將 socket.io 加入其中。

?
1
2
3
4
5
const io = require('socket.io')(http);
io.on('connection', function(socket) {
 console.log('a user connected');
 socket.broadcast.emit('new_user', {});
}

這里的 io 監(jiān)聽 connection 事件,當 client 與 server 建立了連接之后,這里的回調函數會被調用( client中的代碼將在下一節(jié)介紹)。

函數的參數 socket 代表的是當前的 client 和 server 間建立的這個連接。可在 client 程序中將這個建立的 socket 連接打印出來,如下圖所示:

利用Socket.io 實現消息實時推送功能

其中的 id 屬性可以用于標識出這一連接,從而 server 可以向特定的用戶發(fā)送消息。

?
1
socket.broadcast.emit('new_user', {});

這一行代碼表示 socket 將向當前所有與 server 建立了連接的 client(不包括自己) 廣播一條名為 new_user 的消息。

后端推送消息的處理流程

  • 在 node 服務器建立一個用戶信息和 socket id 的映射表,因為同一用戶可能打開了多個頁面,所以他的 socket id 可能存在多個值。當用戶建立連接時,往其中添加值;用戶斷開連接后,刪除相應值。
  • 當 java 后臺存在需要推送的消息時,會向 node 服務器的 /api 路徑 post 一條消息,其中包括用于標識用戶的 tokenid 和其它數據。
  • node 服務器接收到 post 請求后,對請求內容進行處理。根據 tokenid 找出與該用戶對應的 socket id,socket.io 會根據 id 來向用戶推送消息。

對用戶信息的處理

方便起見,這里只用一個數組保存用戶信息,實際工作中可以根據需要放入數據庫中保存。

?
1
global.users = []; // 記錄下登錄用戶的tokenid, socketid

當用戶登錄時, client 會向 server 發(fā)送 user_login 事件,服務器接收到后會做如下操作:

?
1
2
3
4
socket.on('user_login', function(info) {
 const { tokenid, userid, socketid } = info;
 addsocketid(users, { tokenid, socketid, userid });
});

addsocketid() 會向 users 數組中添加用戶信息,不同用戶通過 tokenid 進行區(qū)分,每個用戶有一個 socketids 數組,保存可能存在的多個 socketid。該函數的具體代碼可見 src/utils.js 文件。

同理,還有一個 deletesocketid() 函數用于刪除用戶信息,代碼可見同一文件。

在獲取了用戶的 tokenid 之后,就需要找到對應的 socketid,然后向特定用戶推送消息。

?
1
2
3
4
5
// 只向 id = socketid 的這一連接發(fā)送消息
io.sockets.to(socketid).emit('receive_message', {
 entitytype,
 data
});

服務器的思路大致如此,接下來介紹客戶端中是如何進行相應的處理的。

客戶端

socket.io 的初始化

首先在 html 文件中引入 socket.io 的 client 端文件,例如通過 cdn 引入:

?
1
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>

其它的引入方式:

?
1
2
3
4
<script src="/socket.io/socket.io.js"></script>
const io = require('socket.io-client');
// or with import syntax
import io from 'socket.io-client';

引入 socket.io 后就獲得了 io 函數,通過它來與消息推送服務器建立連接。

?
1
2
3
4
5
6
// 假設你將 node 服務器部署后的地址為:https://www.example.com/ws
// 則: ws_host = 'https://www.example.com'
const msgsocket = io(`${ws_host}`, {
 secure: true,
 path: '/ws/socket.io'
});

如果監(jiān)聽本地:

?
1
const msgsocket = io('http://localhost:4001');

這里如果寫成 io('https://www.example.com/ws') 會出現錯誤,需要將 /ws 寫入path中。

為了能在其它文件使用這一變量,可將 msgsocket 作為一個全局變量:

?
1
window.msgsocket = msgsocket;

用戶建立連接

?
1
2
3
4
5
6
// 用戶登錄時,向服務器發(fā)送用戶的信息。服務器會在收到信息后建立 socket 與用戶的映射。
msgsocket.emit('user_login', {
 userid,
 socketid: msgsocket.id,
 tokenid
});

接收到推送的消息后的處理

?
1
2
3
4
5
6
7
// websocket 連接建立后,監(jiān)聽名為 receive_message 的事件
msgsocket.on('receive_message', msg => {
 store.dispatch({
  type: 'new_socket_msg',
  payload: msg
 });
});

當 websocket 服務器向客戶端推送了消息之后,客戶端需要監(jiān)聽 receive_message 事件,接收到的參數中有相應待處理的信息。

由于使用了 redux 進行數據的處理,所以這里 dispatch 了一個 new_socket_msg action,后續(xù)則是常規(guī)的 redux 處理流程了。

項目的使用

github 上的項目地址:https://github.com/noiron/socket-message-push

npm run dev

即可在 devlopment 環(huán)境下進行測試,現在你就有了一個運行在4001端口的消息推送服務器了。

但是這里并沒有后端的服務器來向我們發(fā)送消息,所以我們將利用 postman 來模擬發(fā)送消息。

為了展示程序的功能,在項目的 client 文件夾下放置了一個 index.html 文件。注意這個文件并不能用在實際的項目中,只是用來顯示消息推送的效果而已。

在開啟了服務器之后,打開 client/index.html,根據提示隨意輸入一個 tokenid 即可。

現在利用 postman 向 localhost:4001/api post 如下的一條信息:

?
1
2
3
4
5
{
 // tokens 數組表示你想向哪個用戶推送消息
 "tokens": ["1", "2"],
 "data": "you shall not pass!!!"
}

利用Socket.io 實現消息實時推送功能

至此,如果一切順利,你應該能夠在 client 的控制臺中看到收到的消息了。

利用Socket.io 實現消息實時推送功能

你可以打開多個 client 頁面,輸入不同的 tokenid,然后檢查消息是否發(fā)送給了正確的用戶。

總結

以上所述是小編給大家介紹的利用socket.io 實現消息實時推送功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!

原文鏈接:http://developer.51cto.com/art/201709/550549.htm

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美成人免费草草影院视频 | 青春草在线观看精品免费视频 | 大胆国模一区二区三区伊人 | 欧美日韩中文国产一区 | 黄漫在线播放 | 国产视频久久久 | 99精品视频在线观看re | 微拍秒拍99福利精品小视频 | bl双性小说 | 扒开双腿羞辱调教play视频 | 啪一啪在线视频 | 久青草国产在线观看视频 | 男人天堂资源 | 娇妻在床上迎合男人 | 236zz宅宅最新伦理 | 成人精品一级毛片 | 成人123 | 免费国产成人 | 3d蒂法精品啪啪一区二区免费 | 麻豆资源| 欧美一区二区三区成人看不卡 | 波多野结衣黑人系列在线观看 | 国产精品永久免费自在线观看 | 四虎永久在线精品免费影视 | 韩国女主播在线大尺无遮挡 | 亚洲欧美日韩综合一区久久 | 亚洲欧美精品一区天堂久久 | 成人在线小视频 | 日日操视频 | 国产高清国内精品福利 | 欧洲网色偷偷亚洲男人的天堂 | 男人的天堂在线观看入口 | 成人福利网 | a∨79成人网 | 999jjj在线播放 | 婷婷99视频精品全部在线观看 | 久久国产乱子伦精品免费不卡 | 精品国产成人AV在线看 | 亚洲高清无在码在线电影 | 免费午夜影院 | 日韩精品亚洲专区在线影视 |