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);
//});
});
});
相关文章推荐
- 让Mac启动的时候自动启动mysql
- 解析STM32的启动过程
- 三级导航纯CSS
- Permutation Sequence算法详解
- 一个搞ACM需要掌握的算法
- Fragment hide,show方法后,会调用什么方法
- c++处理矩阵操作:Eigen库初步学习使用
- Java swing 实现字体滚动
- SQLSERVER2008R2之SQL查询语句
- java基础--面向对象
- 乔布斯的管理之道 首先学会说“不”
- 怎样发布dll到nuget库
- php中getenv()和$_SERVER的区别
- IOS 开发学习37 的Architecture与iphone版本对应关系
- JS中字符串转化与日期的相互转化及比较时间先后
- 第二章 设计程序架构 之 分布式应用
- 使用imap协议接收邮件
- android 基础
- NSCoding协议,遵循了NSCoding协议的数据模型,就可以利用归档进行数据存储了
- 使用docker构建jenkins镜像并运行容器