socket.io的配置和使用以及遇到的坑

先说配置的坑吧

A new Socket instance is returned for the namespace specified by the pathname in the URL, defaulting to /. For example, if the url is http://localhost/users, a transport connection will be established to http://localhost and a Socket.IO connection will be established to /users.
英语不好的同学自己谷歌下吧

服务端

对于一个Socket.io服务端来说,需要配置的一共是四项,一般是两项,画星号()的两项很少有人注意到。

  • http服务的地址。一般是http://example.com
  • socket.io服务挂载的子目录。对于使用express在域名子目录提供服务的我这种情况来说,就是/subpath。按照文档,如果没指定的话,默认值是/。express和socket.io都运行在这个子目录下
  • socket.io实际工作的目录。这就是文档中所说的path,默认值为/socket.io
  • 当然对于实际工作的时候来说,还有一个namespace,用来区分不同的命名空间

客户端

对于一个Socket.io客户端来说,需要配置的也是这些内容,以下是官方的配置样例:

1
2
3
const socket = io('http://localhost', {
path: '/myownpath'
});

这其中

  • http://localhost是http服务的地址
  • /myownpath是socket.io的工作路径path,(这点在引用中没有提到,在上边代码有)
  • /users是命名空间

关于子目录可能出现的问题

但是我遇到一个问题,如果我将http服务部署到了子目录,比如http://localhost/subpath,那我如果直接使用这个url的话会被错误的解析成命名空间/subpath

为了解决这个问题,首先我们要知道path参数指的是socket.io的工作路径,也就是相对于网站根目录的路径,在这里就是/subpath/myownpath。所以我们直接将path设定为/subpath/myownpath,然后其他设置项和官方指导一样就可以了。、

一些想法

这也是我自己的理解,并没有找到官方的支持,但毕竟程序这么跑也跑起来了没遇到bug对吧。

还有就是,很好奇为什么官方不把api设计成http://localhost/subpath/myownpath加上一个/namespace,这样不应该更符合实际使用情况么。反正命名空间的参数也是要单独提出来的,为啥不给的时候就单独给,而且反正网站根目录和子目录也是要连起来才能找到http服务的,为啥要分开给。迷。

socket.io-client-csharp的PR中和这位作者也讨论了这个问题

顺便推荐一下找了好久才找到的可用的.NET socket.io实现doghappy写的,先膜拜一个。

关于传输大文件

大文件请使用单独的服务!不要用Socket.io

引用一下Support for sending big messages,2016年的帖子了,和我现在遇到的问题应该一样,没法发大文件。其实也不大吧,就是个大几百KB或者一两兆的高清图片。对于发文字和数据来说应该已经算大的了。客户端会由于接收文件速度缓慢而超时。目前我只是限制了图片文件大小,还没有采用其他措施。以后可能采取分批发送吧。

因为这个bug差点把服务器搞死,一直在重发图片,带宽都跑满了。最后的解决方案是使用CDN服务传输文件,不用SocketIO也不用API了,效果还不错,十几MB的大图也能传。