您的位置:首页 > 其它

socket.io用法与实例

2015-06-24 18:07 344 查看


socket.io学习笔记

socket.io
 
nodejs


由于个人能力,所写内容较为懒散,请多见谅。

socket.io学习笔记
服务器信息传输
不分组,数据传输
分组数据传输
Socket.io难点大放送(暂时没有搞定)


服务器信息传输

// send to current request socket client

socket.emit('message', "this is a test");


// sending to all clients except sender

socket.broadcast.emit('message', "this is a test");


// sending to all clients in 'game' room(channel) except sender

socket.broadcast.to('game').emit('message', 'nice game');


// sending to all clients, include sender

io.sockets.emit('message', "this is a test");


// sending to all clients in 'game' room(channel), include sender

io.sockets.in('game').emit('message', 'cool game');


// sending to individual socketid

io.sockets.socket(socketid).emit('message', 'for your eyes only');


上述集中方式为socket.io常用的数据传输方式,

io.sockets.on('connection', function (socket) {


});


回调函数的socket参数为一个
client
与服务器的连接标示,不同的
client
会有不同的连接标示。


不分组,数据传输

socket.emit 
socket.emit
信息传输对象为当前
socket
对应的
client
,各个
client
socket
相互不影响。

socket.broadcast.emit 
socket.broadcast.emit
信息传输对象为所有
client
,排除当前
socket
对应的
client


io.sockets.emit 

信息传输对象为所有
client



分组数据传输

类似于之前提过的
of
方法生成命名空间来管理用户,
socket.io
可以使用分组方法,
socket.join()
,以及与之对应的
socket.leave()


io.sockets.on('connection', function (socket) {

socket.on('firefox', function (data) {

socket.join('firefox');

});

socket.on('chrome',function(data){

socket.join('chrome');

});

});


假设有两个聊天室,一个名为firefox,另一个为chrome,客户端操作

socket.emit('firefox')
,就可以加入
firefox
聊天室; 
socket.emit('chrome')
,就可以加入
chrome
聊天室;

向一个分组传输消息,有两种方式:

socket.broadcast.to('chrome').emit('event_name', data);

//emit to 'room' except this socket client

io.sockets.in('chrome').emit('event_name', data)

//emit to all socket client in the room


broadcast
方法允许当前
socket
client
不在该分组内。

可能有一个疑问,一个
socket
是否可以同时存在于几个分组,等效于一个用户会同时在几个聊天室活跃,答案是”可以“,
socket.join()
添加进去就可以了。官方提供了订阅模式的示例:

socket.on('subscribe', function(data) {

socket.join(data.room);

})


socket.on('unsubscribe', function(data) {

socket.leave(data.room);

})


后台处理订阅/退订事件

socket = io.connect('http://127.0.0.1:1338/');

socket.emit('subscribe',{"room" : "chrome"};

socket.emit('unsubscribe',{"room" : "chrome"};


前端触发订阅/退订事件,就可以加入对应的聊天室。 通过
of
方法也可以通过划分命名空间的方式,实现聊天室功能,但不如分组管理来的方便。


Socket.io难点大放送(暂时没有搞定)

授权验证 
socket
连接需要添加权限验证,让已登录的用户
socket
连接到服务器,未登录的用户无条件拒绝。全局授权管理如下:

io.sockets.authorization(function (handshakeData, callback) {

callback(null, true);

}).


callback
函数有两个参数,第一个为
error
,第二个参数为是否授权bool值,通过授权回调函数应为
callback(null,true)
,其它情况下都为拒绝建立连接。

按照web的开发方式,检测是否登录首选
cookie-session
来实现,问题也是出在这里。
websocket
握手阶段属于
HTTP
协议,简单来说是可以读到cookie,就可以实现session。 

+ 精准单用户推送 

理论上来说

// sending to individual socketid

io.sockets.socket(socketid).emit('message', 'for your eyes only');


就可以向一个特定用户推送消息,但是如何获得这个
socketId
,就是生成一个哈希数组,key为username,值为socket.id,这样就可以通过用户名获取对应的id,进而可以向特定client推送消息。

由于我将Express框架和socket.io库两个进程,而且没有使用redis共享数据,所以暂时不能做到
session
读取,大概5天后补上。

===============================

index.html

<script src="/socket.io/socket.io.js"></script>

<script>

  var socket = io.connect('http://localhost:8888');

    

    socket.on("notice", function(data){

        var msg = document.getElementById('all').value;

        document.getElementById('all').innerText = msg + "\n" + data.message;

   });

    var chat_fn = function(){

        var msg = document.getElementById("message").value;

        var nickname = document.getElementById("nickname").value;

        if(nickname == ''){

            nickname = 'guess';

        }

        socket.emit("chat", {message: nickname+" : "+msg});

    };

    var change_nickname = function(){

        var nickname = document.getElementById("nickname").value;

        socket.emit('set nickname', nickname);

    };

</script>

<textarea id="all" cols=40 rows=20></textarea>

<br />

<label>Message:</label>

<input id="message" type="text" name="message" cols=120/>

<input id="chat_btn" type="button" value="chat" onclick="javascript:chat_fn()" />

<label>NickName:</label>

<input id="nickname" typee="text" name="nickname" />

<input id="chang_name" type="button" value="nickname" onclick="javascript:change_nickname()" />

app.js

var app = require('http').createServer(handler);

var io = require('socket.io').listen(app);

var fs = require('fs');

app.listen(8888);

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);

 });

}

io.sockets.on('connection', function (socket) {

  // socket.emit('news', { hello: 'world'});

  // socket.on('my other event', function (data) {

  //   console.log(data);

  //});

  //socket.set('nickname', 'nickname', function(){

  //});

  socket.on('set nickname', function(name){

    //socket.set('nickname', name, function(){

      console.log("change nickname=>" + name);

      socket.emit('nickname ready');

    //});

 });

  socket.on('chat', function(data){

    //socket.get('nickname', function(err, name){

    socket.emit("notice", {message: data.message});

    socket.broadcast.emit("notice", {message: data.message});

    console.log("chat: " + data.message);

    //});

 });

});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: