Javascript 使用express作为websocket的代理
我有一个数据提供商,它通过TCP连接给我提供股票价格。数据提供程序只允许静态IP连接到其服务 但是,由于在将数据发送到前端之前需要格式化数据,因此我希望使用express后端作为代理 这意味着:Javascript 使用express作为websocket的代理,javascript,node.js,express,websocket,Javascript,Node.js,Express,Websocket,我有一个数据提供商,它通过TCP连接给我提供股票价格。数据提供程序只允许静态IP连接到其服务 但是,由于在将数据发送到前端之前需要格式化数据,因此我希望使用express后端作为代理 这意味着: 我需要通过websocket(socket.io)将后端连接到数据提供程序,以获取数据(后端充当客户端) 我需要后端将接收到的数据广播到前端(后端充当服务器) 我的问题是:这有可能吗?有没有更简单的方法来实现这一点?是否有关于如何将express应用程序同时用作websocket服务器和客户端的文档
- 我需要通过websocket(socket.io)将后端连接到数据提供程序,以获取数据(后端充当客户端)
- 我需要后端将接收到的数据广播到前端(后端充当服务器)
编辑: 我现在可以用了。但是我当前的解决方案由于大量的CPU使用而杀死了我的AWS EC2实例。我就是这样实现的:
const net = require('net');
const app = require('express')();
const httpServer = require('http').createServer(app);
const client = new net.Socket();
const options = {
cors: {
origin: 'http://someorigin.org',
},
};
const io = require('socket.io')(httpServer, options);
client.connect(1337, 'some.ip', () => {
console.info('Connected to some.ip');
});
client.on('data', async (data) => {
// parse data
const parsedData = {
identifier: data.identifier,
someData: data.someData,
};
// broadcast data
io.emit('randomEmitString', parsedData);
});
client.on('close', () => {
console.info('Connection closed');
});
httpServer.listen(8081);
有人知道为什么这会导致巨大的CPU负载吗?我试图用clinicjs
分析我的代码,但没有发现明显的问题
EDIT2:更具体地说:我的数据提供者为我提供股票报价。因此,每次报价发生变化时,我都会得到新的数据。然后,我解析这些数据并通过
io.emit
将其发送出去。这可能是某种瓶颈吗
这是我运行clinicjs
后得到的配置文件:
我不知道您的AWS上有多少资源,但1000个客户端应该不是问题 我个人遇到了两个瓶颈:
socket.io
的常见问题)socket.io
库由Node提供服务,而不是Nginx/Apache。节点在保持活动状态管理方面很差some.ip
获取一次数据?好主意是聚合并过滤它或者,这段代码可能不是问题的原因,而是第一次查看的数据下载。缓冲区中是否有数据,或者是否读取
GET index.html
?为了了解您的情况,我创建了一个基本的TCP服务器,它每1ms向连接到它的每个客户端发布JSON消息。以下是服务器的代码:
var net=require('net');
var server=net.createServer(函数(套接字){
插座。管道(插座);
});
server.maxConnections=10
server.on('close',()=>console.log('server closed'))
server.on('error',(err)=>console.error(err))
server.on('正在侦听',()=>console.log('服务器正在侦听')
server.on('连接',(套接字)=>{
console.log(“-client connected”)
socket.setEncoding('utf8')
var intervalId=setInterval(()=>socket.readyState===“打开”&&
socket.write(JSON.stringify({
id:有效期内,
时间戳:Date.now(),
})+'\n'),1)
socket.on('error',(err)=>console.error(err))
socket.on('close',()=>{
clearInterval(有效期间)
console.log('-client关闭了连接')
})
})
监听(1337,‘0.0.0.0’);
如您所见,我们设置了一个setInterval
函数,该函数将每1ms向每个连接的客户端发送一条简单的JSON消息
对于客户,我使用了与您非常相似的东西。首先,我尝试将服务器接收到的每一条消息推送到浏览器和WebSocket连接。在我的例子中,它还将CPU提高到100%。我不知道确切的原因
尽管如此,即使您的数据每1毫秒更新一次,您是否需要以该速度刷新网页仍值得怀疑。大多数网站以每秒60帧的速度运行。这意味着每16毫秒更新一次数据。因此,一个简单的解决方案是每16毫秒批处理数据并将其发送到浏览器。仅此修改就大大提高了性能。您还可以通过延长批处理时间或过滤一些发送的数据来进一步改进
以下是利用批处理消息的客户端代码。请记住,这是一个非常幼稚的实现,用来展示这个想法。更好的调整是将流与库一起工作,如
//tcp-client.js
const express=require('express');
const http=require('http');
const{Server}=require(“socket.io”);
const net=require('net')
常量app=express();
const server=http.createServer(app);
const io=新服务器(服务器);
const client=new net.Socket()
应用程序获取(“/”,(请求,请求)=>{
res.setHeader('content-type','text/html')
res.send(`
TCP客户端
var socket=io();
socket.on('msg',(msg)=>document.body.textContent=msg);
`);
});
io.on('连接',(套接字)=>{
log('-user-connected');
socket.on('disconnect',()=>{
log('-user disconnected');
});
});
变量缓冲区=[]
设置间隔(()=>{
io.emit(“msg”,JSON.stringify(缓冲区))
缓冲区=[]
}, 16)
client.connect(1337,'127.0.0.1',function(){
log('-connected to server');
});
client.on('data',函数(data){
buffer.push(data.toString(“utf8”))
});
client.on('close',function()){
log('-connectiontoserver-closed');
});
服务器。听(3000,()=>{
console.log('在0.0.0.0:3000上监听');
});
当然可以。您可以使用在Socket.io中向所有连接的客户端广播消息(其中,io
是一个示例)。只需在Socket.io服务器启动后连接到数据提供程序。是否确实要(低级)套接字连接到数据