问题还是要接回上次的socket.io上,之前socket.io直接写死了了url,所以在到处去部署网站的时候可能要改掉写死的地址重新build比较耗时,由于工程中原本已经用了
http-proxy-middleware的代理,所以就想要统一都用这个代理,不把url写死了。
socket.io的服务方式
根据socket.io的官方文档,有两种方式可以获得到socket对象,一种是直接由io方法得到,一种是根据manager方法得到
//io方法
import io from 'socket.io-client'
const SOCKET=io('http://localhost:8088/namespace')
用io方法获取socket对象的时候,URI必须给定,而且固定将"/"后面的内容认作namespace。此处的URI如果不给定,或者只给了“/”后的内容,则会默认地址为窗口ip及端口号。
//部分源码如下
interface SocketIOClientStatic {
/**
* Looks up an existing 'Manager' for multiplexing. If the user summons:
* 'io( 'http://localhost/a' );'
* 'io( 'http://localhost/b' );'
*
* We reuse the existing instance based on the same scheme/port/host, and
* we initialize sockets for each namespace. If autoConnect isn't set to
* false in the options, then we'll automatically connect
* @param uri The uri that we'll connect to, including the namespace, where '/' is the default one (e.g. http://localhost:4000/somenamespace)
* @opts Any connect options that we want to pass along
* @return A Socket object
*/
( uri: string, opts?: SocketIOClient.ConnectOpts ): SocketIOClient.Socket;
用manager方法获取socket对象的时候,此处的URI也必须给定,但并不固定"/"后面的内容认作namespace,这就给代理或者多个namespace带来操作可能。
//manager方法
const { Manager } = require("socket.io-client");
const manager = new Manager("http://localhost:8088");
const SOCKET = manager.socket("/namespace");
http-proxy-middleware的代理设置
http-proxy-middleware是本质是转发时重写http://localhost:port/api的内容为目标内容(`target`),所以只要保证我们的请求URL能够保留这个格式就可以了。
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
createProxyMiddleware("/api", {
target: 'http://localhost:9887/',
pathRewrite: {
"^/api": "",
},
changeOrigin: true,
secure: false, // 是否验证证书
ws: true, // 启用websocket
})
);
};
socket.io使用代理
根据之前所说的http-proxy-middleware的内容,我们只需要保证URL有ip:port/api即可,如下:
const { Manager } = require("socket.io-client");
const manager = new Manager("", {
reconnectionDelayMax: 10000,
path: "/api/socket.io",
});
const SOCKETIO = manager.socket("/namespace");
这里/api是http-proxy-middleware设置的,path参数可以保证浏览器发出socket.io请求的时候,设置的地址端口后面可以添加我们想要的路径。最后得到socket对象时需要给予之前确定好的命名空间,这样就可以顺利连接上了。此时我们的申请URL如下:
Request URL:
http://192.168.6.141:8088/api/socket.io/EIO=3&transport=polling&t=NWMqLrc&sid=88ea80c6276f41ef90cf10fec49e5c08
//这里前面是的请求URL内容为 协议://ip地址:端口/api/socket.io/巴拉巴拉
其实这里的逻辑就是:
- manager可以设置我们想要的ip与端口,并且可以给定后续添加的路径,保证可以正常连接
- 用manager的方法设置命名空间,保证可以正常通信