官术网_书友最值得收藏!

4.4.3 信令服務(wù)器的實現(xiàn)

接下來看一下信令服務(wù)器的實現(xiàn)。要實現(xiàn)信令服務(wù)器,我們需要思考以下幾個問題:如何通過NodeJS實現(xiàn)一個HTTP服務(wù)?如何使用socket.io庫?如何進行信令的轉(zhuǎn)發(fā)?下面我就來回答上面的問題,當這幾個問題解答完了,信令服務(wù)器也就實現(xiàn)了。

1)如何通過NodeJS實現(xiàn)一個HTTP服務(wù)?在NodeJS上開發(fā)一個HTTP應(yīng)用只要幾行代碼即可,如代碼4.1所示。

代碼4.1 HTTP服務(wù)器


1  …
2  const http = require('http');//引入http庫
3  const express = require('express'); //引入express庫
4
5  //創(chuàng)建HTTP服務(wù),并偵聽8980端口
6  const app = express();
7  const http_server = http.createServer(app); 
8  http_server.listen(8080, '0.0.0.0');
9  …

上面的代碼中引入了兩個庫:一個是http庫,用于創(chuàng)建HTTP服務(wù);另一個是express庫,是一套開發(fā)Web應(yīng)用的框架,它提供了很多開發(fā)Web應(yīng)用的工具。

通過上面引入的兩個庫,你很容易寫出一個HTTP服務(wù)來。首先,通過express創(chuàng)建一個Web應(yīng)用,如第6行代碼所示;之后調(diào)用HTTP庫的createServer()方法創(chuàng)建HTTP對象,即http_server;最后調(diào)用http_server對象的listen()方法偵聽8080端口。通過上面的步驟就實現(xiàn)了一個HTTP服務(wù)。

2)如何使用socket.io庫?在使用socket.io庫之前,也需要像開發(fā)HTTP服務(wù)一樣,先通過require將它引入程序中,然后利用socket.io的on方法接收消息,用emit方法發(fā)送數(shù)據(jù)。下面是socket.io的幾個常見方法:

·給本次連接發(fā)送消息,如代碼4.2所示。

代碼4.2 發(fā)送消息


socket.emit('cmd') 

·給本次連接發(fā)送帶參數(shù)的消息,如代碼4.3所示。

代碼4.3 發(fā)送帶參數(shù)消息


socket.emit('cmd',arg1); // 多 個 參 數(shù) 往 后 排 

·給除本次連接外房間內(nèi)的所有人發(fā)消息,如代碼4.4所示。

代碼4.4 給房間內(nèi)的所有人發(fā)消息


socket.to(room)emit('cmd') 

·接收消息,如代碼4.5所示。

代碼4.5 接收消息


socket.on('cmd', function(){ … }) 

·接收帶參數(shù)的消息,如代碼4.6所示。

代碼4.6 接收帶參數(shù)的消息


socket.on('cmd', function(arg1){ … }) 

3)如何轉(zhuǎn)發(fā)信令?你需要根據(jù)收到的客戶端不同的信令,給它返回不同的結(jié)果,如代碼4.7所示。

代碼4.7 轉(zhuǎn)發(fā)信令


1   …
2   io.sockets.on('connection', (socket) => {
3   
4   //收到message時,進行轉(zhuǎn)發(fā)
5   socket.on('message', (message) => {
6   //給另一端轉(zhuǎn)發(fā)消息
7   socket.to(room).emit('message', message);
8   });
9   
10   //收到 join 消息
11   socket.on('join', (room) => {
12   var o = io.sockets.adapter.rooms[room];
13   
14   //得到房間里的人數(shù)
15   var nc = o ? Object.keys(o.sockets).length : 0;
16   if (nc < 2){ //如 果 房 間中 沒 有 超 過 2 人
17   socket.join(room);
18   //發(fā) 送 joined消 息
19   socket.emit('joined', room);
20   ...
21   } else { // max two clients
22   socket.emit('full', room); //發(fā) 送 full 消 息
23   }
24   }
25   ...
26   });

從上面的代碼片段中可以看到,所有消息的處理都是在客戶端與服務(wù)器建立連接之后進行的。因此,需要提前將connection消息的處理函數(shù)注冊到socket.io中(即第2行代碼的含義);然后,再分別注冊各消息(joined、message……)的處理函數(shù)。這樣,當服務(wù)器收到客戶端發(fā)來的消息時,socket.io就會根據(jù)消息類型調(diào)用注冊的處理函數(shù),從而完成對應(yīng)的業(yè)務(wù)處理。

經(jīng)過上面的講解,現(xiàn)在再看代碼4.7是不是覺得很簡單了?其具體過程如下:如果服務(wù)端收到message消息,它不做任何處理,直接進行轉(zhuǎn)發(fā)(第7行代碼);如果是join消息,則首先將用戶加入服務(wù)端管理的房間中,之后向客戶端返回joined消息(第17、第19行代碼);如果用戶加入時房間里已經(jīng)有兩個用戶了,則拒絕該用戶的加入,并返回full消息,以告之目前房間里人已經(jīng)滿了(第22行代碼);對于其他消息的處理以此類推。

經(jīng)過上面的步驟后,信令服務(wù)器開發(fā)完成。接下來介紹如何將開發(fā)好的代碼部署到服務(wù)器上。

主站蜘蛛池模板: 白朗县| 云浮市| 枝江市| 五大连池市| 江都市| 阜南县| 泊头市| 洞口县| 峨山| 佛教| 上林县| 安平县| 四子王旗| 郎溪县| 彰化市| 伽师县| 西林县| 五寨县| 青田县| 康定县| 霍林郭勒市| 浦北县| 阿荣旗| 界首市| 兴城市| 皮山县| 伊通| 新田县| 景泰县| 宝坻区| 山阳县| 永胜县| 都匀市| 顺义区| 阿拉尔市| 古蔺县| 南木林县| 兴宁市| 鸡泽县| 元朗区| 革吉县|