node.js中的Socket.IO使用实例


Posted in Javascript onNovember 04, 2014

1. 简介

首先是Socket.IO的官方网站:http://socket.io

官网非常简洁,甚至没有API文档,只有一个简单的“How to use”可以参考。因为Socket.IO就跟官网一样简洁好用易上手。

那么Socket.IO到底是什么呢?Socket.IO是一个WebSocket库,包括了客户端的js和服务器端的nodejs,它的目标是构建可以在不同浏览器和移动设备上使用的实时应用。它会自动根据浏览器从WebSocket、AJAX长轮询、Iframe流等等各种方式中选择最佳的方式来实现网络实时应用,非常方便和人性化,而且支持的浏览器最低达IE5.5,应该可以满足绝大部分需求了。

2. 安装部署

2.1 安装

首先安装非常简单,在node.js环境下只要一句:

npm install socket.io

2.2 结合express来构建服务器

express是一个小巧的Node.js的Web应用框架,在构建HTTP服务器时经常使用到,所以直接以Socket.IO和express为例子来讲解。

var express = require('express')

    , app = express()

    , server = require('http').createServer(app)

    , io = require('socket.io').listen(server);

server.listen(3001);

若不使用express,请参考socket.io/#how-to-use

3. 基本使用方法

主要分为服务器端和客户端两段代码,都非常简单。

Server(app.js):

//接上面的代码

app.get('/', function (req, res) {

    res.sendfile(__dirname + '/index.html');});
io.sockets.on('connection', function (socket) {

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

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

        console.log(data);

    });

});

首先io.sockets.on函数接受字符串"connection"作为客户端发起连接的事件,当连接成功后,调用带有socket参数的回调函数。我们在使用socket.IO的时候,基本上都在这个回调函数里面处理用户的请求。

socket最关键的是emit和on两个函数,前者提交(发出)一个事件(事件名称用字符串表示),事件名称可以自定义,也有一些默认的事件名称,紧接着是一个对象,表示向该socket发送的内容;后者接收一个事件(事件名称用字符串表示),紧接着是收到事件调用的回调函数,其中data是收到的数据。

在上面的例子中,我们发送了news事件和收到了other event事件,那么客户端应该会有对应的接收和发送事件。没错,客户端代码和服务器正好相反,而且非常相似。

Client(client.js)

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

<script>

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

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

        console.log(data);

        socket.emit('other event', { my: 'data' });

    });

</script>

有两点要注意的:socket.io.js路径要写对,这个js文件实际放在了服务器端的node_modules文件夹中,在请求这个文件时会重定向,因此不要诧异服务器端不存在这个文件但为什么还能正常工作。当然,你可以把服务器端的socket.io.js这个文件拷贝到本地,使它成为客户端的js文件,这样就不用每次都向Node服务器请求这个js文件,增强稳定性。第二点是要用var socket = io.connect('网站地址或ip');来获取socket对象,接着就可以使用socket来收发事件。关于事件处理,上面的代码表示收到“news”事件后,打印收到的数据,并向服务器发送“other event”事件。

注:内置默认的事件名例如“disconnect”表示客户端连接断开,“message”表示收到消息等等。自定义的事件名称,尽量不要跟Socket.IO中内置的默认事件名重名,以免造成不必要的麻烦。

4. 其他常用API

1).向所有客户端广播:socket.broadcast.emit('broadcast message');

2).进入一个房间(非常好用!相当于一个命名空间,可以对一个特定的房间广播而不影响在其他房间或不在房间的客户端):socket.join('your room name');

3).向一个房间广播消息(发送者收不到消息):socket.broadcast.to('your room name').emit('broadcast room message');

4).向一个房间广播消息(包括发送者都能收到消息)(这个API属于io.sockets):io.sockets.in('another room name').emit('broadcast room message');

5).强制使用WebSocket通信:(客户端)socket.send('hi'),(服务器)用socket.on('message', function(data){})来接收。

5. 使用Socket.IO构建一个聊天室

最后,我们通过一个简单的实例来结束本篇。用Socket.IO构建一个聊天室就是50行左右的代码的事情,实时聊天效果也非常好。以下贴出关键代码:

Server(socketChat.js)

//一个客户端连接的字典,当一个客户端连接到服务器时,

//会产生一个唯一的socketId,该字典保存socketId到用户信息(昵称等)的映射

var connectionList = {};
exports.startChat = function (io) {

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

        //客户端连接时,保存socketId和用户名

        var socketId = socket.id;

        connectionList[socketId] = {

            socket: socket

        };
        //用户进入聊天室事件,向其他在线用户广播其用户名

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

            socket.broadcast.emit('broadcast_join', data);

            connectionList[socketId].username = data.username;

        });
        //用户离开聊天室事件,向其他在线用户广播其离开

        socket.on('disconnect', function () {

            if (connectionList[socketId].username) {

                socket.broadcast.emit('broadcast_quit', {

                    username: connectionList[socketId].username

                });

            }

            delete connectionList[socketId];

        });
        //用户发言事件,向其他在线用户广播其发言内容

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

            socket.broadcast.emit('broadcast_say',{

                username: connectionList[socketId].username,

                text: data.text

            });

        });

    })

};

Client(socketChatClient.js)

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

//连接服务器完毕后,马上提交一个“加入”事件,把自己的用户名告诉别人

socket.emit('join', {

    username: 'Username hehe'

});
//收到加入聊天室广播后,显示消息

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

    console.log(data.username + '加入了聊天室');

});
//收到离开聊天室广播后,显示消息

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

    console.log(data.username + '离开了聊天室');

});
//收到别人发送的消息后,显示消息

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

    console.log(data.username + '说: ' + data.text);

});
//这里我们假设有一个文本框textarea和一个发送按钮.btn-send

//使用jQuery绑定事件

$('.btn-send').click(function(e) {

    //获取文本框的文本

    var text = $('textarea').val();

    //提交一个say事件,服务器收到就会广播

    socket.emit('say', {

        username: 'Username hehe'

        text: text

    });

});

这就是一个简单的聊天室DEMO,你可以根据你的需要随意扩展。Socket.IO基本上就是各种事件的提交和接收处理,思想非常简单。

Javascript 相关文章推荐
IE与FireFox中的childNodes区别
Oct 20 Javascript
js实现带搜索功能的下拉框实时搜索实时匹配
Nov 05 Javascript
JS获取select的value和text值的简单实例
Feb 26 Javascript
javascript中解析四则运算表达式的算法和示例
Aug 11 Javascript
javascript实现倒计时跳转页面
Jan 17 Javascript
用iframe实现不刷新整个页面上传图片的实例
Nov 18 Javascript
ES2015 Symbol 一种绝不重复的值
Dec 25 Javascript
使用vue.js实现联动效果的示例代码
Jan 10 Javascript
javascript设计模式之策略模式学习笔记
Feb 15 Javascript
Layui 动态禁止select下拉的例子
Sep 03 Javascript
vue使用高德地图点击下钻上浮效果的实现思路
Oct 12 Javascript
Vue使用路由钩子拦截器beforeEach和afterEach监听路由
Nov 16 Javascript
Node.js的特点和应用场景介绍
Nov 04 #Javascript
Node.js中的模块机制学习笔记
Nov 04 #Javascript
Node.js异步I/O学习笔记
Nov 04 #Javascript
JavaScript中的ubound函数使用实例
Nov 04 #Javascript
JavaScript实现检查页面上的广告是否被AdBlock屏蔽了的方法
Nov 03 #Javascript
网页中表单按回车就自动提交的问题的解决方案
Nov 03 #Javascript
详解jquery中$.ajax方法提交表单
Nov 03 #Javascript
You might like
PHP 字符串加密函数(在指定时间内加密还原字符串,超时无法还原)
2010/04/28 PHP
php天翼开放平台短信发送接口实现方法
2014/12/22 PHP
IE不出现Flash激活框的小发现的js实现方法
2007/09/07 Javascript
纯js实现遮罩层效果原理分析
2014/05/27 Javascript
js行号显示的文本框实现效果(兼容多种浏览器 )
2015/10/23 Javascript
详解javascript获取url信息的常见方法
2016/12/19 Javascript
react-router JS 控制路由跳转实例
2017/06/15 Javascript
Easy UI动态树点击文字实现展开关闭功能
2017/09/30 Javascript
node使用Koa2搭建web项目的方法
2017/10/17 Javascript
JS实现页面跳转与刷新的方法汇总
2019/08/30 Javascript
layer.open 获取不到表单信息的解决方法
2019/09/26 Javascript
如何解决vue在ios微信&quot;复制链接&quot;功能问题
2020/03/26 Javascript
javascript实现评分功能
2020/06/24 Javascript
Vue中使用Echarts仪表盘展示实时数据的实现
2020/11/01 Javascript
[00:56]2014DOTA2国际邀请赛 DK、iG 赛前探访
2014/07/10 DOTA
Django 多语言教程的实现(i18n)
2018/07/07 Python
python文件写入write()的操作
2019/05/14 Python
linux环境下Django的安装配置详解
2019/07/22 Python
python opencv鼠标事件实现画框圈定目标获取坐标信息
2020/04/18 Python
keras .h5转移动端的.tflite文件实现方式
2020/05/25 Python
mac系统下安装pycharm、永久激活、中文汉化详细教程
2020/11/24 Python
Django中ORM的基本使用教程
2020/12/22 Python
Python脚本调试工具安装过程
2021/01/11 Python
HTML5 Canvas 绘图——使用 Canvas 绘制图形图文教程 使用html5 canvas 绘制精美的图
2015/08/31 HTML / CSS
基于canvas使用贝塞尔曲线平滑拟合折线段的方法
2018/01/10 HTML / CSS
全球酒店预订网站:Hotels.com
2016/08/10 全球购物
意大利会呼吸的鞋:Geox健乐士
2017/02/12 全球购物
阿迪达斯印度官方商城:adidas India
2017/03/26 全球购物
《真想变成大大的荷叶》教学反思
2014/04/14 职场文书
个人考核材料
2014/05/15 职场文书
销售活动策划方案
2014/08/26 职场文书
2015年售票员工作总结
2015/04/29 职场文书
商务信函英语问候语
2015/11/10 职场文书
2016幼儿园毕业感言
2015/12/08 职场文书
win11无法登录onedrive错误代码0x8004def7怎么办 ?
2022/04/05 数码科技
讨论nginx location 顺序问题
2022/05/30 Servers