简介
由于最近接触了socket.io方面的知识,了解到作为基于websocket进行封装的socket.io,但是又不是完全基于websocket。在消息接受发送方面有很强的实时性,这个特性对于消息推送场景是很契合的,于是打算从这方面入手。
方案一
为了实现相互之间的解耦,以下分为几个角色,分别为主业务服务器(Server)、Socket.io通道管理服务器(Socket.io)、用户(client)。
首先,是通过客户端,就是client,发送HTTP请求到Server上,比如说用户输入了用户名和密码,发送到服务端(Server)去进行验证,验证通过之后,Server发送成功的消息到socket.io处,将与client端的通信打开,实现消息的实时推送功能。但是在实现过程中的问题在于,由于要经过http请求才能打开通信通道,在http方法里定义socket,此时消息从client到达Server速度很快,但是在从sokcet.io到client的时候,速度变得很慢,原因目前未知,方案在原理上是说得通的,只是具体实现有困难。
首先需要说明的是,这个方案利用JWT(Json Web Token),客户端先通过Server进行用户名与密码的验证,通过之后,会给客户端返回一个经过加密的token,也就是jwt。之后,用户访问Server的一个url,其中需要bearToken才能进行访问,访问之后,在其路由里定义相关动作,将成功访问的消息发送至Socket.io处,将连接建立起来,此时的连接指的是socket.io和client之间的websocket连接
方案二
这个方案具体是通过socket.io中的命名空间来实现对于各个用户的指定连接,利用第三方包socketio-auth来进行相关账户连接的认证,如果认证通过,则连接成功,否则,失败。但是由于这个方案socketio这部分和主业务服务器耦合度太高,无法实现socketio的重复利用。
具体情况是,在socket.io和client之间的连接已经建立,但是没有emit任何信息。socketio-auth里面具体的配置情况如下
socketioAuth(socket,{
authenticate: authenticate,
postAuthenticate: postAuthenticate,
timeout: 1500
})
首先先经过authenticate,如果验证成功之后,再进入下一步,即postAuthenticate,之后将验证成功的用户添加到socket.client.user中去,建立相关连接。如果验证不成功,直接执行disconnect来终止连接。
总而言之,整个流程走下来,先是在client和socketio处建立连接,但是这个连接没有保障性,没有发送任何信息。之后验证成功之后,再通过用户名建立一个更加私密的连接,也就是通过用户名来创建namespace来建立连接,之后的消息发送以及监听走的均是这个私密的连接。
方案三
为了达到解耦目的,以及免除方案一的繁琐方案,目前的方案三的大致图如下
首先,这里假设用户是已经经过验证过的用户,用户首先与Socket.io建立连接,这个连接是客户端连接到Socket.io的主域名上,连接之后,Client发送一个登陆消息,将自身的信息发送给Socket.io去保存,目前只是简单的在socket.io建立一个空的数组来保存这些信息,实际工程上应该保存在数据库上。连接成功之后。再进行下一步,即比如用户触发一个按钮,比如说点击了购买的按钮,然后Server端通过这个按钮绑定的事件,获取点击按钮的用户(Client)信息,将获取到的tokenId以及点击之后需要向用户推送的信息,经过包装之后,通过POST方式将信息发送至Socket.io服务端。之后,Socket.io通过获取到的具体tokenId。然后和保存的tokenId进行对比,如果有存在与之匹配的,就建立一对一映射关系的连接,将信息推送到客户端(Client)。
这样一来,就能很好的将主要业务服务器Server和Socket.io分离开来,Socket.io就可以给不同的服务器之间共用。