socket.io

学习资料

第一部分: 基本介绍

  

  socket.io是对websocket以及node的封装,狭隘的说,socket.io是对于websocket的封装,其中包含node,是因为这样可以方便我们在前端和后端对websocket的统一调用。而websocket就是和http协议不同的一种新的协议,他可以实现全双工通信,很好地解决了http协议中使用轮训、commet等的不足。 另外,我们通过兼容性问题可以看到websocket并不是支持所有的浏览器的,所以在socket.io中针对不支持websocket的浏览器提供了其他类似的解决方案。 (说明:我们可以通过caniuse.com来查询一个技术是否可以使用。)

  socket.io分为client端和node端,但是在实际使用时,我们只需要npm install socket.io即可,其中就已经包含了 socket.io-client 了,这样方便安装。

  

  值得注意的是: 通过websocket发送的数据只能是字符串,和localStorage类似,虽然是字符串,但是我们可以通过JSON.stringify()将之序列化,如此,我们就可以发送更加复杂的数据了。并且二进制数据也是支持的。

第二部分: 相关知识点介绍 & 相关问题记录

  1. socket事件的触发和接受。

   socket.emit() 为触发一个 socket事件,这个触发可以是在服务器端,也可以是在客户端。 第一个参数为事件名称,后面的一个或多个参数为希望通过触发传递的值。 

   sockets.on() 为接受一个被触发的事件,这个接受同样可以在服务器端,也可以在客户端 。 第一个参数为事件名称,第二个参数为一个回调函数,这个回调函数的参数就是通过on传递过来的值。 

  说明: 在提及emit和on都可以在B/S端触发和接收一个事件,是因为websocket是全双工通信,所以双方都可以作为发送方也可以作为接收方。  

   2. B、S端刚刚连接的事件触发是怎样的? 

  刚刚链接时, 在客户端就会触发 socket.on('connect', function () {}); 我们可以在回调函数中做一些链接之后的事情。 

  刚刚链接时, 在服务器端会触发 sockets.on('connetion', function (socket) {}); 即在回调函数中会产生一个socket供我们调用。 

  注意到: 客户端为 socket, 但是服务器端我们写成了 sockets, 然后通过链接才得到的 socket 实例, 也就是说, 服务器端可以链接多个 sockets。 这时很显然的,客户端打开一个网站就只有一个用户,所以是socket,而服务器端在连接用户的过程中可能需要。

   3. 用socket做一个聊天室的思路是怎么样的? 

  首先服务器端创建一个users数组,用于存储这个聊天室的用户。 如果需要有多个聊天室,那么创建多个数组即可。 

  进入页面后,客户端就触发了 connet 事件,这样socket就连接成功了(如果连接失败,客户端就会触发 error 事件,我们就可以将回调函数中的 error 打印出来给用户相应提示),接着用户选择一个名字,点击进入,这时用户用户端发出(emit)一个login事件,并通过socket向后台传输昵称,服务器端的login事件触发,开始检测该用户是否存在于当前聊天室,如果存在,服务器端发出 nicknameExisted 事件,这时客户端接收到之后就会通知用户昵称重复并重新输入。 如果输入成功,那么服务器端的socket上添加一个name属性,属性值为客户端发送来的昵称, 并且触发 loginSuccess 事件, 这时客户端就可以做一些个性化的工作,比如将用户名显示在页面上了。 

  当用户断开连接时(logout或者直接关闭页面),则会在后台触发 disconnet 事件,这样,后台就可以将 users数组 中相应的用户删除,通过发出 system事件 并且返回给客户端现在的user长度信息、用户名等, 接着客户端通过触发这个这个事件对所有用户做出相应的通知。 

  

  除此之外,用户还可以通过回车或点击发送按钮将textarea框中的信息通过 发出postMsg事件 发送到后台, 接着node端的socket触发 postMsg事件 然后发出 newMsg事件 将用户名称、短信息通过broadcast(广播) 的方式发送给每一个用户。

  

  但是我们的页面中应该如何显示出来呢? 我们可以创建一个显示函数,当后台信息发送过来时,我们传入用户名、用户信息等参数即可。 

  

  当然,为了更好的交互性,我们还可以将图片(通过input的file形式获取)发送、发送表情(实际上就是大小比较小的图片或者用小的gif图也是可以的)。这里需要使用 FileReader() 构造函数。 这个构造函数得到的实例就是文件实例reader, reader.onload = function (e) {} 这里的参数e,我们可以使用e.target.result 得到这个图片的编码,然后在使用的时候,使用img的src属性为这个编码即可显示图片。 

  

  ok! 整体思路就是这样了。 

  

 第三部分: 相关API && 重要知识

  • socket.io 提供了三种默认的事件,客户端和服务器端都有,即connect 、message 、disconnect 。当与对方建立连接后自动触发 connect 事件,当收到对方发来的数据后触发 message 事件(通常为 socket.send() 触发),当对方关闭连接后触发 disconnect 事件

  在服务器端需要区分下面的几种情况:

  1. socket.emit() --- 向建立该条连接的一个客户端触发。
  2. socket.broadcast.emit() --- 向除了建立该条连接的其他所有连接着的客户端触发。
  3. io.sockets.emit() --- 向所有客户端触发,即上面两者的加和。

  

  相关博客: http://www.cnblogs.com/zhuzhenwei918/p/6607646.html

  推荐博客:http://www.cnblogs.com/Wayou/p/hichat_built_with_nodejs_socket.html

原文地址:https://www.cnblogs.com/zhuzhenwei918/p/7235165.html