Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用express作为websocket的代理_Javascript_Node.js_Express_Websocket - Fatal编程技术网

Javascript 使用express作为websocket的代理

Javascript 使用express作为websocket的代理,javascript,node.js,express,websocket,Javascript,Node.js,Express,Websocket,我有一个数据提供商,它通过TCP连接给我提供股票价格。数据提供程序只允许静态IP连接到其服务 但是,由于在将数据发送到前端之前需要格式化数据,因此我希望使用express后端作为代理 这意味着: 我需要通过websocket(socket.io)将后端连接到数据提供程序,以获取数据(后端充当客户端) 我需要后端将接收到的数据广播到前端(后端充当服务器) 我的问题是:这有可能吗?有没有更简单的方法来实现这一点?是否有关于如何将express应用程序同时用作websocket服务器和客户端的文档

我有一个数据提供商,它通过TCP连接给我提供股票价格。数据提供程序只允许静态IP连接到其服务

但是,由于在将数据发送到前端之前需要格式化数据,因此我希望使用express后端作为代理

这意味着:

  • 我需要通过websocket(socket.io)将后端连接到数据提供程序,以获取数据(后端充当客户端)
  • 我需要后端将接收到的数据广播到前端(后端充当服务器)
我的问题是:这有可能吗?有没有更简单的方法来实现这一点?是否有关于如何将express应用程序同时用作websocket服务器和客户端的文档


编辑:

我现在可以用了。但是我当前的解决方案由于大量的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个客户端应该不是问题

我个人遇到了两个瓶颈:

  • 使用Ajax而不是WS连接的客户端(这曾经是旧的
    socket.io
    的常见问题)
  • socket.io
    库由Node提供服务,而不是Nginx/Apache。节点在保持活动状态管理方面很差
  • 同时检查:

  • 您多久从
    some.ip
    获取一次数据?好主意是聚合并过滤它
  • 您是否需要通知所有客户所有事项?仅仅通知有兴趣的人就够了吗?(活动区)
  • 也许值得将服务移动到serviceWorker.js或推送事件
  • 作为实验的一部分,记录自己的事件。接收数据,连接和断开客户端。观察服务器日志

    作为调试过程的一部分,记录事件。接收数据,连接和断开客户端观察服务器日志。


    或者,这段代码可能不是问题的原因,而是第一次查看的数据下载。缓冲区中是否有数据,或者是否读取
    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服务器启动后连接到数据提供程序。是否确实要(低级)套接字连接到数据