socket.io-client报404错误爬坑与自己封装websocket

socket.io-client

重要事情要放在最前面说
如果你用socket.io系列的包,但是疯狂报404错误。
那么你需要检查前后端是否都使用了socket.io系列的包去完成websocket通信!!!
那么你需要检查前后端是否都使用了socket.io系列的包去完成websocket通信!!!
那么你需要检查前后端是否都使用了socket.io系列的包去完成websocket通信!!!

  1. 最近在公司的项目里需要用到websocket通信。于是找到了socket.io-client库用于websocket通信。这让我调试了一天也没连上后端开启的websocket。但是用原生websocket去实现又可以正常和后端进行通信。

  2. 我发现一个socket.io-client的一个坑点就是前后端要商量好都得使用他们开发的包去进行通信。比如后端是nodeJs,前段用了socket.io-client后端也得使用socket.io-client。如果后端是java,问题不大,他们还开发了socket.io-client-java去配套使用。

  3. 有人就会有疑问了?websocket应该与库无关,也就是前后端各自开启websocket实现通信实际应该是互不干扰的,没有说都要使用同一个库的要求啊。

  4. 刚开始我也是这么认为的?后面仔细阅读官网我才发现,socket.io-client实际用的更多的不是websocket而是长轮询。在更多的时候会使用长轮询,为什么要使用长轮询?在浏览器不支持websocket的替代方案,兼容性更好,或者websocket异常断开了也会使用长轮询替代websocket。在这点socket.io确实做得很好。这就是为什么如果使用socket.io-client包在某些时候会有大量的http请求。sockiet.io要求前后端要使用他们自己开发的包还有一个原因是他们的websocket和长轮询有自己的规范,传参格式只有他们自己的包能理解然后通信。
    在这里插入图片描述

  5. 这导致一个问题,就是前端用了他们的包,后端用了其他的包,或者不用包开启websocket都会疯狂报404!!!这也在官网有答案,怪我当时没仔细阅读官网(这里开启了翻译,看原文请前往官网查看英文版)。
    在这里插入图片描述

  6. 这就是让我调了一天也连不上后端开启的websocket的原因!!!我前端使用了socket.io,但是后端没有使用他们的库去完成websocket的功能(后端是其他组的,所以他也不知道我们前端使用socket.io)。调试BUG差点让我怀疑人生,因为我们组内大多数系统都使用这个库,socket.io在npm上也有极高的下载量。这都说明了这个库的可靠性,但是我却没有发现他的使用限制。后面才发现我从一开始就错了。因为我也使用过原生websocket进行过通信,感觉挺简单的,自己封装一个也完全够用,没想到会在连接上后端websocket上花费这么多时间。而且socket.io不管是从命名还是用法上都有很高的迷惑性,让我们以为他内部使用更多的是websocket通信。

自己封装websocket

  1. 既然后端已经使用了其他包打开了websocket通信,让他换成socket.io的包再开发一次不太现实,而且长时间的BUG调试我也已经不想再使用这个socket.io包了。辣鸡!!!

  2. 那我就自己封装一个用呗,也不是太难。

    1. 第一步区别开发环境,这里是Vue框架,其他框架封装应该也差不多
    // websocket.js
    function getUrl(){
    	// 开发环境加上端口
    	if(process.env.NODE_ENV ==== 'development') return 'ws://xx.com:1010/socket'
    	else return 'ws://xx.com/socket'
    }
    
    1. 第二步封装WebSocket,这里只封装我项目用到的事件,这里放在对象里,可扩展性也是非常棒的,要加事件直接以同样的格式添加对应事件即可。如果不能使用class的,直接粗暴的定义一个对象放进去也可以。
    // websocket.js
    class Socket{
    	constructor(){
    		this.socket = null
    	}
    	open(){
    		this.socket = new WebSocket(getUrl())
    	}
    	message(callback = event => {}){
    		this.socket.onmessage = event => {
    			callback(event)
    		}
    	}
    	close(callback = event => {}){
    		this.socket.onclose= event => {
    			callback(event)
    		}
    	}
    }
    export const socket = new Socket()
    
    1. 封装的websocket使用,如果是在vue的话,open和message建立websocket连接在created方法里面执行就可以了,然后在beforeDestory里面执行close关闭websocket连接即可。
    import { socket } from './websocket.js'
    // 建立websocket连接
    socket.open()
    function fetchTable(evnet){ ... }
    // 监听消息
    socket.message(fetchTable)
    // 断开连接
    socket.close()
    

总结

  其实我一直都建议如果简单尽量自己封装去使用,可控性更高一点,自己也能学习更多一点。有人会说了,你这是重复造轮子。别人造轮子跟我有什么关系呢,我使用别人的库自己能学到的还是比较局限的,得要自己多造轮子。当自己造过轮子之后,觉得自己掌握了或者造的轮子没有别人那么好,这时候再造轮子才是重复造轮子。
  万一一不小心自己造的轮子比别人好,那也能开源给其他用户使用了。为什么我之前使用原生websocket,却不自己封装,因为我想知道好的websocket库会带来怎样更好的体验,改善自己的封装的websocket结果因为自己没有仔细阅读官方文档,给自己埋了坑。
委屈.jpg

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vgbire

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值