socket.io

socket.io是實作HTML5 WebSocket的套件,透過WebSocket的連線,可以做到Server主動推播訊息到Client端的動作,讓Client與Server達到真正的互動...

官方網站

http://socket.io/

Github repository

https://github.com/Automattic/socket.io/

Installation

npm install socket.io

SocketIO Server實作三步驟

connect: 實作連線SocketIO Server後的動作

io.sockets.on('connection', function (socket) {
  //這邊可以實作當connect發生後的一些事情
})

on: 實作某個事件發生後的動作

socket.on('event name', function (data) {
  //這邊可以實作當某個名稱的event發生後的一些事情
});

emit: 實作Server主動送出某個事件跟資料

var data = ...; //希望傳送給這個socket的event
socket.emit('event name', data);

Sample Usage

下面是參考HINA網路上的Socket IO文件:http://blog.hinablue.me/entry/nodejs-first-look-socket-io 改寫呈現時間變化的頁面。

Server端實作:

var fs = require('fs')
  , http = require('http')
  // 發佈socket.io server,並且聽取8080 port
  , io = require('socket.io').listen(8080);

/**
 * 實作socket io,並在connection開啟後,於callback function中實作要處理的事件
 */
io.sockets.on('connection', function (socket) {
  /**
   * 每隔三秒鐘進行一次emit動作
   * 而emit的內容是發佈一個news
   * 內容為JSON物件,以time為key,value為emit當下的時間
   */
  setInterval(function(){
    socket.emit('news', { time: new Date() });
  }, 3000);

  /**
   * 接收client傳回的事件,並且於callback內接收該data做處理
   */
  socket.on('my other event', function (data) {
      console.log('[my other event]' + data);
  });
});

/**
 * 建立server實體,目的是方便鏈結html檔案,讓前端可以連線直接測試
 */
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});
  //任何連線都直接讀取client01.html做回覆
  res.end(fs.readFileSync(__dirname + '/client01.html', 'utf8'));
}).listen(8088, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

上面程式碼中啟動了兩個server,一個為8080的socket.io server,另一個為8088的http server,而http server僅是為了提供socket.io的client連線的目的,下面是client的範例程式...(其中socket.io server不僅提供server的功用,我們還可以直接從client code中include socket.io.js,實際位置為:http://localhost:8080/socket.io/socket.io.js)

Client端實作:

<script src="http://localhost:8080/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-2.0.2.min.js"></script>

<script>
  //連結socket.io server位置
  var socket = io.connect('http://localhost:8080');
  //聽取news event,並在callback中處理
  socket.on('news', function (data) {
      console.log('[on news]' + JSON.stringify(data));
      //將data呈現在下方id=t的h1 tag中
      $('#t').html(data.time);
      //觸發server另一個event,並且傳入data
      socket.emit('my other event', { my: 'data' });
  });
</script>

<h1 id="t"></h1>

Socket.io的應用相當多,而眾多的高手也都慢慢看到Node.js在Network上的實力,希望之後有更多的Socket.io相關應用跟大家分享!

SocketIO with Room

SocketIO連線後,Server端會回覆Socket一個unique id作為識別這個socket的依據,一般我們會實做一個hash存放socket id與用戶或session的一個對應表,讓之後我們可以針對使用者觸發一個event... 在Room的概念中,就像是實做了這個hash的功能,可以讓我們透過in或to指定一個Room ID做訊息的發送,操作的範例如下:

Server端實作

這邊我們實作個interval送訊息給Client的socket,並且是針對特定的Room發送...

這邊必須要注意,需要在disconnect event發生的時候clear這個interval事件,不然會造成每次disconnect時候,interval沒有清除的狀況...

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io').listen(server);

server.listen(8000);

app.get('/jquery.js', function (req, res) {
  res.sendfile(__dirname + '/bower_components/jquery/src/jquery.js');
});

app.get('/', function (req, res) {
  res.sendfile(__dirname + '/index.html');
});

var prefix = 'room';
io.on('connection', function (socket) {
  room = prefix + "-" + new Date().getTime();
  socket.join(room);
  var loop = setInterval(function(){
    var ts = new Date().getTime();
    io.sockets.in(room).emit('roomevent', {room: room, ts: ts, msg: 'sent to room...'})
  }, 3000);

  socket.on('event1', function (data) {
    console.log(data);
  });

  socket.on('disconnect', function(){
    clearInterval(loop);
  });

});

用戶端實作

用戶端實作比較單純,在connect事件完成後,即開始listen roomevent事件,等待Server把roomevent傳送回來...

var log = require('nodeutil').logger.getInstance('test');
var socket_host = 'http://127.0.0.1:8000/'

var io = require('socket.io-client');
var opts = { reconnect: true, connect_timeout: 5000 };

var socket = io.connect(socket_host, opts);

socket.on('connect', function(){
  log.info('connected...');
  socket.emit('event1', {
    msg: 'test...'
  });
});

socket.on('news', function(data){
  log.info('got news:', data);
});

socket.on('roomevent', function(data){
  var id = socket.io ? socket.io.engine.id : socket.socket.sessionid;
  log.info('[%s][%s]got news:', id, new Date().toString(), data);
});

進一步實作

上面的範例是由Server來決定Room ID,在現實世界裡,有可能會是Client來決定Room ID,例如在Client連線上Server後,跟Server取得認證,得到RoomID,再由Client端emit event到Server設定該RoomID...

相信大家到這邊應該有很多發想,我們暫停在這邊,給大家一個無限想像的空間 :D

其他設定

Socket.io也有支援一些細部設定的動作,例如timeout時間等等...可以參考這邊:

https://github.com/Automattic/socket.io/wiki/configuring-socket.io

設定上,需要透過socket.io instance的set method,並且在connection之前完成...

var io = require('socket.io').listen(server);
server.listen(8000);

io.set('heartbeat interval', 50);
io.on('connection', function (socket) {
  //TODO: implement your code
});

這邊針對一些timeout參數做個說明...

  • close timeout (defaults to 60 seconds)

Client連線的timeout時間,當client close這個connection,client仍有close timeout所設定的秒數的時間可以執行reconnect。這是Server端在成功連結後送給client的一個值...

  • heartbeat timeout (defaults to 60 seconds)

Heartbeat timeout是Server連線後push給client端使用的參數,Server需要在這個設定時間內得到一個heartbeat的訊號以確保連線保持著。這個參數的設定應該要大於"heartbeat interval"。

  • heartbeat interval (defaults to 25 seconds)

Heartbeat interval是Server在連線後push給client端的設定值,client端會在此設定時間傳送heartbeat訊息給server端。

results matching ""

    No results matching ""