Node篇 6.使用Socket.IO实现即时通信

引言

如今几乎所有的软件产品中都加入了社交的功能。即时通信是非常重要而又常用的一个技术点。

比如电商的客服,社交软件的聊天等等。

对于新手,对于即时通信的解决方案一般就是定时器轮循用AJAX刷后台,比如每五秒请求一次啥的,模拟出个即时的效果。 但显然这并不是一个非常好的方案。首先,这是有延迟的,你五秒去请求一次,聊天对方得等急死。想起08年最开始玩QQ的时候,经常是对方打了好几行字,我才回两三个字,非常的尴尬。。。现在打字快了,但如果我的消息经常是五秒之后才能让对方看到,显然体验也是很不好的。

那有同学就要讲了。五秒会有延迟,那我改成1秒不就行了吗?再不济,我TM每毫秒去请求一次总行了吧。

行,确实行。这样理论上确实能实现即时聊天了。但有没有想过一点,你每毫秒一次,一秒钟就是1000次,一分钟就是60000次,一小时就是三百六十万次。如果有一百个人同时在线,就是。。。 不敢想对不对,服务器和数据库能同时承受那么多请求吗?显然不能,就算能,这样也是一听就很不合理的。难道我们用的QQ都这么发请求?几亿个人都在用,还不得炸?

所以呢,上面这种方案,做一做大学毕设还行,真的做项目是不靠谱的。

所以H5之前大家一般用Flash之类的技术,完成通信,至今很多网站的客服系统还是用这个做的。 但H5出来之后你懂的,让通信一下子变得很简单。

H5:不是针对谁,我只是说在座各位都是XX。

好了,废话扯完,正文开始。

对于即时通信,各个语言都有自己的实现,一般这个技术被称为Socket套接字编程。

在NodeJS中也有,这套库叫Socket.IO。

今天我们就用socket.io来实现一下简单的聊天的效果,无须借助数据库和AJAX什么的

Socket.IO

socket.io本身就是可以通过这个域名访问的,大家可以自习上去深入研究,在这里简单的介绍一下,她的优势在于,将各种通信机制封装起来了,会根据浏览器的兼容性自动做出调整,官方是这么说的,具体我也没试过。谁还会用IE8呢是不是。。。

好了,老样子,先建项目,

app.js

public/index.html

其实就是画个框框、文本框、按钮而已,模仿聊天界面

页面效果:

运行,打开浏览器访问localhost:999

会发现输出了一条信息: 有客户端连接

浏览器再打开个新窗口,控制台中又会出现一条:有客户端连接,所以你已经知道之前写的代码是干嘛的了,其实就是监听连接事件。

那么既然有连接事件,显然也有断开连接事件。我们来看一下:

是的,后续所有的事件都是写在连接事件的回调函数里面的,也很好理解,因为连接是其他所有操作的前提嘛。

我们重启一下服务,对了前面好像忘了说,从cmd控制台退出是ctrl+c,然后按键就可以自动找到前面输入过的命令了。这样就没必要每次都得关掉控制台重新来。

如果刚才的浏览器没关,重启后会自动输出两条:

此时如果我们关掉一个浏览器页面,控制台就会输出:有客户端断开,就和我们上面写的一样。

而如果是刷新某个页面,则会输出两条,先是断开,然后是连接。

好了,连接事件就这么简单,我们来看看聊天怎么搞:

然后页面上也要改一下

其实很简单,我们见文思义,点击发送按钮时触发这个发送,然后socket监听chat事件,如果触发了,则在si_messages中追加一条消息。要注意的是,这个chat事件并不是系统内置的事件,而是我们自定义的,只要我们前后台的事件名称对应,就能够触发。

我们来看下这个流程: 客户端执行一个chat事件,服务器监听到,然后服务器也执行了一次chat,但其实就是把内容原封不动的转发了一下。转发给谁呢?给所有客户端,这时候,又走到了客户端页面中的on("chat")中,就执行了追加消息内容的回调函数。

一定要知道,我们的消息不是直接发送给对方的,而是发送到服务器,经过服务器的处理之后由服务器转发给对方的。

客户端服务器

How are you?I'm fine!客户端服务器

我们重启服务并刷新页面,然后在文本框中输入一些文字,然后点击发送,你会发现本页面的div中出现了那条消息,然后切换到另一个浏览器页面中,你会发现,不需要刷新,她也自动追加了这条消息。

窗口1

窗口2

好了,现在我们简单的群聊搞完了,是不是还少个私聊?私聊就麻烦了,因为私聊其实就是把消息发给特定用户,而不是像之前那样随便一扔就算了。那这个特定用户从哪边来呢?显然每个用户要有自己的唯一标识嘛?假设现在就是网名。

我们来给用户加个起网名的功能。同样也是自定义事件

要注意,既然大家都有名字了,那服务器端肯定要有存用户列表的地方:

大家看这代码也很简单,其实就是判断下重复注册,然后通知到客户端,我们回顾了两个ES5的高级函数,一个是some,判断是否存在,一个是map,将数组中的元素组合成新的对象。JS刚开始入门的时候我们就讲过哦,这里回顾一下。

还有一点是,我们如何让名字和客户端连接对应上呢?socket对象中有个id是唯一标识,所以我们可以让id和name组成一个对象塞到数组中。这样每次就可以通过name查到id,然后发送消息了。

然后看下页面,

js部分

这个users其实就是个下拉框而已,我们把设置过名字的用户放进去,代表好友列表。

现在页面效果是这样的,设置名字之后,消息框会有提示,而且控制台会输出用户列表

好了,名字设置成功了,可以做私聊了。我们把私聊部分单独画个DIV来做:

画完的页面效果是这样的:

然后是客户端JS代码:

显然服务器端要监听对应事件,这个稍微复杂一点:

其实也很好懂,通过name到数组中找到对应的用户,然后通过用户id找到对应的连接,然后使用那个连接来发送消息,注意这里不是用io而是socket来发送咯

我们重启下看下页面效果,先设置网名,然后私聊里面找到对应的好友,发送消息,你会发现,只有被发送的那个人的页面,才出现了消息记录,效果实现了!

但其实我们看QQ等聊天软件,一般自己这边也会有自己发送的消息记录,这样看清晰一点。所以我们可以加上去,十分简单:

我们看下效果,聊聊天:

Simba:

Roger:

好了,到目前为止,一个简单的聊天程序已经基本完成了。我们如果把数据库加入进去,就真的可以使用了。

其实难度不大,真正的难的地方已经被这个Socket组件封装好了。我们只是做个调用而已,只要事件对应了,就OK了。

非常的粗糙,更深入更完善的程序,还是得各位自己去研究咯。

如果你觉得对你有帮助,不妨转发一下,让更多人一起学习。

祝万事顺遂。

最后还是那句话:学软件请联系我。

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180104G0U40Z00?refer=cp_1026

扫码关注云+社区