您的位置:首页 > 博客中心 > 互联网 >

推送服务之socket.io

时间:2022-05-01 09:11

一、作者自述

  从事软件开发3年了,出于各种原因(其实是因为我懒,啊哈哈~),第一次决定动手写点什么。第一呢,给自己一个总结的机会,梳理下自己的知识库。第二呢,同第一点。。。

  自从大学毕业后,一直处于一种“极度”的繁忙之中。从刚开始入行时各种学习的“饥渴”状态,到后来工作需要的“填鸭”状态,一直在学,一直在用,边用边学。刚开始接触的知识面比较窄,但随着工作的变换,能力的提升,接触的东西越来越多了。慢慢的,自己越来越感觉知识杂乱,缺乏梳理。因此,决定开通博客,时不时的记录下自己新学的知识,整理下已经学过的知识,偶尔来灵感了,也可以总结一下。

二、推送服务之socket.io

  目前来说,接触到的推送服务也有几个了。比如signalr,socket.io,super websocket。除此之外还有其他第三方推送服务。对于一个前后端都得啃的苦逼猿来说,总体感觉原理都是差不多的。最大的不同可能就是其实现方式的不同了。在此不多做追述,有兴趣的童鞋可以自行百度。

  今天来重点说下。接触socket.io是因为公司要开发一款棋牌游戏,决定使用socket.io作为推送服务。和前面说的另外两个推送不一样,socket.io是跑在node环境下的服务。不得不说,JS编程确实快捷简单。没用过node的童鞋,可以找度娘。废话不多说,直接上代码。

socket.io服务端代码:

 1 var app = require(‘http‘).createServer(handler)
 2 var io = require(‘socket.io‘)(app);
 3 var fs = require(‘fs‘);
 4 
 5 app.listen(80);
 6 
 7 io.on(‘connection‘, function (socket) {
 8   socket.emit(‘news‘, { hello: ‘world‘ });
 9   socket.on(‘my other event‘, function (data) {
10     console.log(data);
11   });
12 });

socket.io客户端代码:

1 
2 

简单解释下

该行代码用来指示socket.io服务所在地址。若服务端与客户端不在同一项目内,则需要添加上服务所在具体域名或者IP和端口。

至此,我们的推送服务带客户端简单交互已经完成了。当然,相当的简陋。此例就是官方给出的demo,非常的简单,直白。但是我们在实际的运用当中,需求肯定不会如此的简单。

先说下socket.io的部分API,1.0版本之前的API和1.0之后版本的API已经有所不同了(其实我感觉这里描述为事件更贴切)。这里简单列下1.0版本之后的API。

socket.io 提供了默认事件(如:connect, message, disconnect)。另外,socket.io允许发送并接收自定义事件。

自定义事件:

1 socket.on(‘send message‘, function(data) {
2   console.log(‘send message:::::::::‘, data);
3 });

事件的定义基本不变。所有的事件基本都是这个格式。

执行事件:

socket.emit("send message", {msg: ‘test send messsage‘});

这是个最基本的事件执行代码。其作用是返回一段提示信息给自己。其他人无法接收到。如果我们要给别人发送消息怎么办呢??

io.sockets.connected[socket.id].emit(‘send message‘, {msg: ‘test specific message‘});

此行代码的作用就是给特定socket发送消息。只需要知道目标的socketId即可。因此,服务端最好要实现处理用户和socke关系的业务。

socket.broadcast.to(socket.id).emit(‘send message‘, {msg: ‘test specific message by room‘});

这行代码的效果和上面一样是一样的。用户在建立socket链接后,默认都会加入一个room,该room的ID就是socket的ID。相当于一个特定的房间内只有一个用户。我们想该房间通知消息,该用户就可以接收到。不同的是上面的代码可以给自己发送消息,而本行代码不行,只能给别人发送消息。

广播消息:

1 //全局广播消息(不包含自己)
2 socket.broadcast.emit(‘broadcast message‘, {msg: ‘test broadcast message‘});
3 //房间内广播消息(不包括自己)
4 socket.broadcast.to(‘cg room‘).emit(‘broadcast message to room‘, {msg: ‘test broadcast message to room‘});
5 //全局广播消息(包括自己)
6 io.sockets.emit(‘broadcast message all‘, {msg: ‘test broadcast message to all‘});
7 //房间内广播消息(包括自己)
8 io.sockets.to(‘cg room‘).emit(‘broadcast message all in room‘, {msg: ‘test broadcast message to all in room‘});

这几行代码的作用是向某一范围内,所有已链接的socket发送消息。网上看到想房间内发送消息的时候,有的用in,有的用to,区别是in自己可以接收到,to自己接收不到。但我测试的结果是这俩其实是一样的。想房间内通知消息,是否需要屏蔽自己,也不是通过in和to来区分的。这可能是老版本和新版本的区别吧。

  推送,其实就是客户端A向服务器主动发送一条消息,服务器收到并根据要求进行转发,此时B客户端作为接收方,被动的接收服务器转发过来的数据。当然,中间涉及到用户状态的变更和维护。这里不做描述。而某些情况下,我们需要知道服务器或者客户端是否收到了发送过去的数据,我们可以发送带有确认机制的消息:

//Sending and getting data (acknowledgements)
socket.emit(‘ack message‘, {msg: ‘test ack message‘}, function (data){
    //回掉返回的确认消息,可以为任意JS支持的类型
    console.log(data);
});

其对应的事件定义方式需要改动一下:

socket.on(‘ack message‘, function(data, fn) {
    console.log(‘ack message:::::::::‘, data);
    fn(true);
});

此外,socket.io还提供一种消息发送机制volatile messages。意思大概是说,当服务器发送数据时,客户端因为各种原因不能正常接收,比如网络问题、或者正处于长连接的建立连接阶段。此时会让我们的应用变得 suffer(意会一下),那就需要考虑发送 volatile 数据。即使客户端没连线,一样可以这样发送,服务器会自动丢弃发送失败的数据。这里提供一个官方demo:

 1 var io = require(‘socket.io‘)(80);
 2 
 3 io.on(‘connection‘, function (socket) {
 4   var tweets = setInterval(function () {
 5     getBieberTweet(function (tweet) {
 6       socket.volatile.emit(‘bieber tweet‘, tweet);
 7     });
 8   }, 100);
 9 
10   socket.on(‘disconnect‘, function () {
11     clearInterval(tweets);
12   });
13 });

 

房间和命名空间

  这里不再具体赘述,官网给的demo已经和详细了。有需求的同学可以自行查看文档。

最后

  第一次写博客,很多地方都写的比较简陋,望请谅解!

 

本类排行

今日推荐

热门手游