Socket.IO入门

标签: socket io | 发表时间:2014-02-19 23:42 | 作者:hongtoushizi
出处:http://www.iteye.com

       最近用node+socket.io+mqtt+php实现了基于PC和android的聊天工具。一直也没故上总结,今天从网上看到一篇整理的特别好的文章,故转载过来,再次感觉原文作者。

 

       转载自:http://raytaylorlin.com/Tech/web/Node.js/socket-io-tutorial/

 

Socket.IO入门

2013-11-29

暑假的时候Heatmap项目组需要对在线即时通信和协作进行技术探索,于是我开始研究Web在线聊天的实现方式。在充分对Comet技术进行了研究之后(详见我之前写的一篇 Comet简介的博文),在丁基友的提示之下决定尝试使用Socket.IO。一个是考虑以后HTML5做网络通信需要用到WebSocket现在可以提前接触一下,另外一个是这个东西的服务器端要用到Node.js,之前就对node很有兴趣正好借此提升下功力。

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)

    <scriptsrc="/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

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

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

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

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

  • 强制使用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基本上就是各种事件的提交和接收处理,思想非常简单。

 

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [socket io] 推荐:

有关socket read

- - 五四陈科学院
以下内容由 [五四陈科学院]提供. 实际开发中,网络程序最可能遇到的就是数据没收到、收到错误数据这样诡异的问题.. 很多时候,都是由于对socket read的细节理解的不一致,导致了程序前后的矛盾. 下面详细阐述整个read的过程. read函数是负责从fd中读取内容.. 当读成功时, read返回实际所读的字节数.

物理IO与逻辑IO

- - 操作系统 - ITeye博客
IO性能对于一个系统的影响是至关重要的. 一个系统经过多项优化以后,瓶颈往往落在数据库;而数据库经过多种优化以后,瓶颈最终会落到IO. 而IO性能的发展,明显落后于CPU的发展. Memchached也好,NoSql也好,这些流行技术的背后都在直接或者间接地回避IO瓶颈,从而提高系统性能. 上图层次比较多,但总的就是三部分.

Socket的速率控制

- - CSDN博客互联网推荐文章
做一个以精确速率向外输出数据的数据源,要完成这个目标,最基础的是:. 1、找到一种精确的计时器,在精确的时间范围内控制数据源以指定的速度向外发送数据. 2、通过对套接字选项和线程优先级的设置减少网络因素对发送速度造成的影响,从而提高发送精度,保证数据的实际发送量尽可能的达到指定的理论发送量.      针对第一个要求,通过寻找到一种时间精度达到微秒级的精确计数器来保证,在硬件支持的情况下可以通过WindowsAPI获取时钟频率以及震荡次数,通过在事件两端分别调用函数得到震荡次数的差值并结合时钟频率可以计算出精确的时间间隔,通过指定的传输速度和精确的延时可以计算出需要发送的数据量.

ZeroMQ(java)中监控Socket

- - CSDN博客架构设计推荐文章
基本上ZeroMQ(java)中基本的代码都算是过了一遍了吧,不过觉得它在日志这一块貌似基本没有做什么工作,也就是我们通过日志来知道ZeroMQ都发生了什么事情. 而且由于ZeroMQ中将连接的建立和重连接都进行了隔离,用户不需要做什么事情来维护连接,当然这样做的好处是使程序员的编码工作变少了,但是当然也有不好的地方,那就是用户失去了对ZeroMQ整个运行阶段的控制.

java socket参数详解:BackLog

- - 开源软件 - ITeye博客
 java socket参数详解:BackLog. 输入连接指示(对连接的请求)的最大队列长度被设置为 backlog 参数. 如果队列满时收到连接指示,则拒绝该连接. backlog参数必须是大于 0 的正值. 如果传递的值等于或小于 0,则假定为默认值. 经过测试这个队列是按照 FIFO(先进先出)的原则.

HTML5 Web socket和socket.io - wishyouhappy

- - 博客园_首页
   HTML5的新特性,用于双向推送消息(例如网页聊天,手机推送消息等). client利用regular http请求webpage. 请求的webpage 执行javascript脚本,open a connection to server.. 有新的信息时服务器和客户端可以相互发送信息(Real-time traffic from the server to the client .

tcp/ip ,http,socket的关系

- - 行业应用 - ITeye博客
  物理层、数据链路层、网络层、传输层、会话层、表示层和应用层.   通过初步的了解,我知道IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层,.   三者从本质上来说没有可比性,.   socket则是对TCP/IP协议的封装和应用(程序员层面上).   也可以说,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,.

linux异步IO浅析

- Sepher - kouu&#39;s home
知道异步IO已经很久了,但是直到最近,才真正用它来解决一下实际问题(在一个CPU密集型的应用中,有一些需要处理的数据可能放在磁盘上. 预先知道这些数据的位置,所以预先发起异步IO读请求. 等到真正需要用到这些数据的时候,再等待异步IO完成. 使用了异步IO,在发起IO请求到实际使用数据这段时间内,程序还可以继续做其他事情).

java nio和io的比较

- - 互联网 - ITeye博客
第一部分:简单介绍NIO.     服务器在合理时间内处理大量客户机的请求的能力取决于服务器使用I/O流的效率,同时为成百上千的客户提供服务的服务器必须能并发的使用I/O服务.     用Java语言写的服务器,由于其线程与客户机之比几乎是一比一,因而易受到大量线程开销的影响,其结果是即导致性能问题,又缺乏伸缩性.

关于socket的一些初步研究

- iDesperadO - keakon的涂鸦馆
这些天在研究Tornado的源码,说实话它的代码过于艰深了,需要绕很多弯才能弄清. 我想其中的问题主要是我不太懂socket,于是就花了些时间学习socket,算是有了些收获,顺便记录在此. 实际上UNIX的设计者很喜欢用类似的方式来处理一类任务,其中数据传输就都被抽象成文件,包括磁盘文件、管道、FIFO和终端等.