为了解决这个困扰我的问题,我已经在Google和SO上搜索了两个星期。首先,我将概述我的目标是什么,然后,我将尝试解释我距离解决该目标有多近。
要在大型应用程序及其数据API之间注入小型express
服务器,其唯一目的是操纵来自服务器的数据响应(或管理自定义响应来代替服务器响应的响应) )。
我们正在使用socket.io
将客户端与服务器连接,实际上我实际上要修改的事件很少。我想在客户端和服务器之间来回代理的大多数事件都保持不变。
但是,有一些我想将自定义响应发送回客户端进行测试的珍贵事件
我已经尝试将一台基本的快速服务器同时用作socket.io-client
和socket.io
服务器。我不知道如何相互代理我的请求,尤其是对于跟踪多个客户端的可能性特别警惕。链接到这里是关键,我很困惑
我也尝试过使用http-proxy,这使我非常接近,但是到目前为止,我唯一能做的就是使用内部的socket.on('data', (data) => { /* do something */ });
检查有效载荷的来回情况我的proxy.on('open', socket => {});
事件。
因此,尽管我可以看到大量数据来去去去,但我仍然需要机会来操纵它。
这是任何人以前做过的事情吗?有没有关于如何通过将客户端连接连接到服务器来使Express Server充当代理的好资源?
预先感谢您的专业知识。我担心这可能太先进了。
答案 0 :(得分:0)
好吧,正如我所承诺的,我提出了理想解决方案的一半。理想情况下,我想来回地代理 all 事件,并且只听一些关键事件,但是我还没有弄清楚那部分内容。如果有人可以帮助我,我将永远感激不已。
相反,我只是映射了套接字两端发出的所有事件,并将它们埋在已连接的调用中。
这是我如何做我想要的事情的细节-您正常创建一个server
,并在其连接上,然后从client
内部启动一个.on('connection', () => {});
连接呼叫。一旦处于此范围内,您就可以相对确定两个连接都是打开的,并开始来回传递事件。理想情况下,您将检查活动连接,但是如果您的服务器和/或客户端具备处理断开连接的能力,则可能还可以。
在下面的简单示例中,您将看到如何来回传递事件以及如何完成工作。就像我说的,如果有人可以通过通配符之类的方法(由于某种原因而无法工作)来帮助我,请告诉我!
// GLOBAL CONFIGS
const serverConfig = {}; // Feel free to add your desired options here
// Some of these options pertain more to me than they will to you; don't feel like
// you have to copy these configs
const clientConfig = {
// We don't want to pre-emptivly try to connect to data-api,
// because we need our client to give us data first.
autoConnect: false,
multiplex: false,
// Disables/bypasses long polling which causes the connection to
// be severed then re-connected (for my api at least)
transports: ["websocket"]
};
const PORT = 3000;
const PROXY_HOST = '<api-endpoint-goes-here>'
const NAMESPACE = '<the name of your namespace, if applicable>';
// SERVER STUFF - this will connect to your client
const app = require('express')();
const server = require('http').Server(app);
const cors = require('cors');
const io = require('socket.io')(server, serverConfig);
const nsp = io.of(`/${NAMESPACE}`);
// CLIENT STUFF - this will connect to your api server as a client
const client = require('socket.io-client');
const ioClient = client(`${PROXY_HOST}/${NAMESPACE}`, clientConfig);
// Self explanatory I hope
app.use(cors());
// I am going to call this a root socket - meaning no namespace. Not entirely useful for now unless
// we want to inspect transitions in and out of our namespace, but just putting it here FYI
io.on('connection', socket => {
console.log(`A connection to the root socket made ${socket.handshake.headers.origin}`);
socket.on('disconnect', () => {
console.log(`A client disconnected from the root socket.`);
});
});
// Serve up a basic html file so that we can interact with our socket.io instance in the
// console. This index.html has a similar setup with a socket connection to both the data
// api and this test server, so I can ping events via console and test how this is working
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname + '/index.html'));
});
// Run the server
server.listen(PORT, () => console.log('Test data server is running'));
// Here's where the real solution reveals itself for me :)
// Listen for connections to the namespace we are looking for - this is the meat & potatoes of our app
nsp.on('connection', socket => {
console.log(`the ${NAMESPACE} namespace was connected`);
// Time to initiate a connection to the ioClient because we need it for the app now
ioClient.connect();
// Now check to make sure ioCLient is connected. Once we get inside here, we can be
// reasonably sure that we have a connection to both the client, and the data-api
ioClient.on('connect', () => {
// Acknowledge we have connected to the data-api
console.log('Connected to data-api via socket.io');
// Events sent from data-api
ioClient.on('<your event>', data => {
socket.emit('<your event>', data);
});
ioClient.on('<your event with two params>', (data1, data2) => {
socket.emit('<your event with two params>', data1, data2);
});
// ... etc
// Other event catchers for ioClient
ioClient.on('disconnect', () => {
console.log('Disconnected from the data-api');
});
ioClient.on('error', err => {
console.error('Error with the data-api connection: ', err);
});
// Events sent from the app client
socket.on('<your event>', data => {
ioClient.emit('<your event>', data);
});
socket.on('<your event with two params>', (data1, data2) => {
ioClient.emit('<your event with two params>', data1, data2);
});
// ... etc
});
});