vue2.0開發聊天程序(六) 服務端的webScoket

大吉大利,今晚吃雞!
                   - PUBGphp

時隔多日,終於再次拾起這個拖了好久的項目。並非由於沒時間,也不是由於這個項目對於我來講有多困難,就是一個字————懶。
此項目的後臺,固然是選擇node.js來實現。做爲一個前端,node.js比起java、php簡單多了。html

node支持的webSocket

在npm中有不少支持webSocket的模塊,包括socket.io、node-websocket、faye-websocket-node等等,均可以實現webSocket,可是能查到的資料最多的應該算是socket.io了。
可參考粉絲日誌裏面對每種模塊的實現:http://blog.fens.me/nodejs-we...前端

本項目選用的固然是socket.io 資料多,易上手。java

socket.io

socket.io 安裝

npm install socket.io --save

安裝在項目內,而且保存在你的package.json中。node

如何使用

使用socket.io很是簡單,只需以下兩個文件
index.jsweb

var app = require('http').createServer(handler) // 使用了node自帶的http模塊
var io = require('socket.io')(app);
var fs = require('fs'); // node自帶的fs模塊

app.listen(3000); // 監聽3000端口

// 定義一個處理器,當訪問localhost:3000時,執行此函數,返回index.html文件
function handler (req, res) {
  fs.readFile(__dirname + '/index.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}
// 監聽socket鏈接
io.on('connection', function (socket) {
    //向web端推送消息
  socket.emit('news', { hello: 'world' });
   //接收web端傳遞的消息
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

index.htmlexpress

<!-- 可在node_modules/socket.io-client中獲取此文件 -->
<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io('http://localhost:3000'); // 建立webSocket鏈接
  socket.on('news', function (data) { // 監聽on
    console.log(data);
    socket.emit('my other event', { my: 'data' }); // 發送my other event
  });
</script>

若想結合express或Koa框架使用,請參閱socket.io文檔https://socket.io/docs/ 中文版: https://zhuanlan.zhihu.com/p/...npm

API

下面介紹一些socket.io經常使用的API,可分爲服務端和客戶端兩部分json

服務端

1.構造函數 Serverapi

實例化一個socket.io對象,有兩種寫法:

const io = require('socket.io')();
// or
const Server = require('socket.io');
const io = new Server();

接收兩個參數(httpServer,options)【須要綁定的服務器,配置項】,第一個例子中的var app = require('http').createServer(handler) 就是一個服務器。

2.connect和connection事件

io.on('connect', (socket) => {
  // ...
});
io.on('connection', (socket) => {
  // ...
});

當有一個來自客戶端的鏈接時觸發該事件,參數socket爲鏈接的客戶端的socket對象。

3.socket
上面提到的socket可看作一個和下行客戶端溝通的橋樑。他屬於一個特定的命名空間(默認爲"/")。

socket.id: 一個獨一無二的會話標誌,來自與下行客戶端,在發送消息給指定的客戶端的時候很是有用

//發送給指定的客戶端
    io.sockets.connected[socket.id].emit('err','user is exist');

socket.rooms: 遺傳哈希字符串,用來標誌當前客戶端所在的房間號,經過房間名稱創建索引。有了房間機制就可實現給同一組房間內的socket推送消息,(可用來實現羣聊)

io.on('connection', (socket) => {
  socket.join('room 237', () => {
    let rooms = Objects.keys(socket.rooms);
    console.log(rooms); // [ <socket.id>, 'room 237' ]
  });
});

socket.use:註冊中間件,當任何訊息流經該中間件時執行中間件中的內容,該中間件會接受參數,也能夠判斷是否阻斷後續中間件的執行

io.on('connection', (socket) => {
  socket.use((packet, next) => {
    if (packet.doge === true) return next();
    next(new Error('Not a doge error'));
  });
});

socket.send: 發送一個message事件,接收要發送的內容和回調函數爲參數

socket.send('hi', function(data) {
    console.log(data);
});
// 客戶端
 socket.on('message', function(data) {
    console.log(data);
  })

socket.emit: 重寫/強化 EventEmitter.emit方法,經過事件名來觸發事件給指定的socket,任意多的參數均可被傳入,支持全部可序列化的數據結構。
接收一下參數:

eventName (字符串)
args 因此可序列化的數據結構  包括buffer
ack (Function)
// 簡單的例子
socket.emit('print', 'hello world');

socket.emit('ferret', 'tobi', (data) => {
    console.log(data); // data will be 'woot'
  });

socket.on: 爲給定的事件註冊一個新的事件處理器。

socket.on('news', (data) => {
  console.log(data);
});
// with several arguments
socket.on('news', (arg1, arg2, arg3) => {
  // ...
});
// or with acknowledgement
socket.on('news', (data, callback) => {
  callback(0);
});

socket.join: 添加客戶端到room房間內,而且執行可選擇的回調函數。

io.on('connection', (socket) => {
  socket.join('room 237', () => {
    let rooms = Objects.keys(socket.rooms);
    console.log(rooms); // [ <socket.id>, 'room 237' ]
    io.to('room 237', 'a new user has joined the room'); // broadcast to everyone in the room
  });
});

socket.leave:從指定的房間裏移除客戶端,而且可選擇的執行一個異常回調函數,與當客戶端的鏈接丟失後,會自動的將其從房間移除

socket.leave('room 237',(res)=>{
    console.log(res)
})

socket.io中的namespace和room,可參考文章:http://blog.csdn.net/lijiecon...
以上就是經常使用的服務API,下面介紹客戶端的socket.io

客戶端
<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io('http://localhost:3000'); // 建立webSocket鏈接
  socket.on('news', function (data) { // 監聽on
    console.log(data);
    socket.emit('my other event', { my: 'data' }); // 發送my other event
  });
</script>

IO: 建立socket鏈接,還可指定命名空間

io('http://localhost/users'); 
// 則將會對http://localhost進行傳輸鏈接,而且http://Socket.IO鏈接將會對"/users"創建鏈接。

也可提供查詢參數:

io('http://localhost/users?token=abc')

還可使用多路複用、攜帶額外的請求頭
詳細文檔可參考: https://socket.io/docs/client...
connect: 監聽是否與服務器鏈接成功,接收回調函數

const socket = io('http://localhost');

socket.on('connect', () => {
  console.log('conncet ok');
});

connect_error:接錯誤觸發事件處理器

socket.on('connect_error', (error) => {
  // ...
});

disconnect:丟失鏈接時觸發時間處理器

socket.on('disconnect', (timeout) => {
  // ...
});

reconnect: 成功的重連時觸發時間處理器

socket.on('reconnect', (timeout) => {
  // ...
});

Sokect
也是一個鏈接服務端的對象,在鏈接到服務器以後也會生成與服務端socket相同的id

const socket = io('http://localhost');

console.log(socket.id); // undefined

socket.on('connect', () => {
  console.log(socket.id); // 'G5p5...'
});

socket.open()和socket.connect(): 手動打開socket,可用於在鏈接斷開後從新鏈接

socket.on('disconnect', () => {
     socket.open();
   });

socket.emit: 向服務端發送,與服務端的emit用法相同

socket.emit('ferret', 'tobi', (data) => {
     console.log(data); // data will be 'woot'
   });

socket.on:註冊一個新的響應服務器事件的事件處理器,與服務端的用法相同

socket.on('news', (data) => {
  console.log(data);
});

socket.close()和socket.disconnect(): 手動關閉客戶端對服務器的連接

相關文章
相關標籤/搜索