Делитесь файлами с помощью socket.io

Я использую Node.js и Socket.io для своего веб-приложения.

Я хочу транслировать файл, который может быть каким-то большим (> 15 МБ) на все подключенные сокеты, а затем использовать его в своих клиентах. Есть ли способ сделать это?

PS: если у вас есть демо с babylon.js + socket.io, это было бы здорово

EDIT:
В соответствии с запросом мой серверный код:

import { createServer } from 'http';
import { createSocketServer} from "./socket";
import cookieParser from "cookie-parser";
import express from "express";
import morgan from "morgan";
import path from "path";

const port = 3000;

// Create a new express application instance
const app: express.Application = express();

app.use(cookieParser());
app.use(morgan('dev'));

const server = createServer(app);

// create a socket.io server
createSocketServer(server);

app.use('/', express.static(path.join(__dirname, 'public')));

server.listen(port,'0.0.0.0', function () {
  console.log('Server is listening on port ' + port + ' !');
});

Код загрузки активов Babylon:

this.assetsManager = new BABYLON.AssetsManager(this.scene);

this.assetsManager.addMeshTask('obj task', '',
      'http://192.168.0.100:3000/babylon-files/dir1/', 'objectFile.obj');
this.assetsManager.addMeshTask('mtl task', '',
      'http://192.168.0.100:3000/babylon-files/dir1/', 'materialFile.mtl');
this.assetsManager.addTextureTask('text1 task',
      'http://192.168.0.100:3000/babylon-files/dir1/texture1.jpg');
this.assetsManager.addTextureTask('text2 task',
      'http://192.168.0.100:3000/babylon-files/dir1/texture2.jpg');

this.assetsManager.onFinish = ((tasks) => {
      this.engine.runRenderLoop(() => {
        this.scene.render();
      });
}).bind(this);

this.assetsManager.load();

person Observablerxjs    schedule 27.03.2020    source источник
comment
обязательно загружайте файлы с помощью FileReader и испускайте как обычно, socket.io может обрабатывать двоичные файлы, буферы массивов и т. д. np   -  person Lawrence Cherone    schedule 27.03.2020
comment
Если вы собираетесь отправлять их клиенту, а клиент их нигде не хранит, то да, они будут в оперативной памяти. Может ли ваш клиентский код babylon использовать их из оперативной памяти, полностью зависит от этого кода и от того, поддерживает ли он такой тип доступа. Что именно вы отправляете клиенту? Это код? Или это данные? Если данные, то какой тип данных?   -  person jfriend00    schedule 27.03.2020
comment
@jfriend00, например, я отправлю файлы 3D-объектов, поэтому в основном в каталоге будет файл .obj, файл .mat и несколько файлов текстур .jpg.   -  person Observablerxjs    schedule 27.03.2020
comment
Если BabylonJS позволяет вам загружать объектные файлы из строки или из какого-либо типизированного массива вместо файла, то это должно быть выполнимо.   -  person jfriend00    schedule 27.03.2020
comment
@Observablerxjs Почему вы не говорите BabylonJS через socket.io загрузить файл? В BabylonJS есть загрузчик ресурсов   -  person Marc    schedule 31.03.2020
comment
@Marc, так что ваша идея состоит в том, чтобы сохранить модель в репозитории github, а затем сказать babylon.js загрузить файл из репозитория github? Потому что сейчас моя модель не на github, а в файловой системе сервера.   -  person Observablerxjs    schedule 31.03.2020
comment
@Observablerxjs Нет. Где вы размещаете свое приложение Babylon? Сохраните ваши файлы *.obj и *.mtl на одном сервере и скажите Bayblon через socket.io загрузить ресурсы: x, y и z.   -  person Marc    schedule 31.03.2020
comment
@Marc Не могли бы вы опубликовать ответ о том, как это сделать? Это именно то, что я ищу   -  person Observablerxjs    schedule 31.03.2020
comment
@Observablerxjs pastebin.com/6ee48vfk   -  person Marc    schedule 02.04.2020
comment
@Marc Чтобы ваш код работал, клиент должен иметь файл в своей файловой системе, чтобы babylon мог получить к нему доступ по своему имени файла, иначе, когда я вызову BABYLON.SceneLoader.Load, babylon не найдет его. Сервер - единственный, у кого есть файлы, поэтому я хочу передать их другим клиентам.   -  person Observablerxjs    schedule 02.04.2020
comment
@Observablerxjs клиент/браузер не имеет доступа к файловой системе пользователя, и это хорошо! Вам нужно загрузить файлы через http с веб-сервера, взгляните на мой ответ ниже и оставьте комментарий, если у вас есть вопросы.   -  person Marc    schedule 02.04.2020


Ответы (1)


Вы должны хранить файлы *.obj и *.mtl на одном сервере.

Обратите внимание, что ваш код узла и веб-сервера не может работать на одном и том же порту. Вы должны использовать обратный прокси-сервер или прослушивать разные порты.

Это предотвращает межсайтовые проблемы. Например: создайте на своем веб-сервере общедоступный каталог: http://example.com/assets/babylon-files

Теперь в коде node вы можете инициировать загрузку клиентами файлов по этому пути:


// socket.io logic above
// waiting for connetions, auth, etc...

// tell conencted clients what the should load from 
// http://example.com/assets/babylon-files
socket.broadcast.emit('loadAsset', 'house.obj');
socket.broadcast.emit('loadAsset', 'car.obj');
socket.broadcast.emit('loadAsset', 'wall.obj');

Клиент должен выглядеть примерно так:


// listen for socket.io events from server here
io.on("loadAsset", (filename) => {

  // tell babylon to load assets
  BABYLON.SceneLoader.Load("/assets/babylon-files", filename, engine, function (scene) {
   // do something with the scene
  });

  // - or -

  // tell babylon to append assets
  BABYLON.SceneLoader.Append("/assets/babylon-files", filename, function (scene) {
    // do something with the scene
  });


});

Точно так же вы можете отправлять бинарные данные клиентам:


fs.readFile("/path/to/obj<or>mtl/file", (err, buff) => {

    if (err) {
        res.status(500).end();
        return;
    }

    socket.binary(true).emit("loadAsset", buff);

});
person Marc    schedule 02.04.2020
comment
Как только я отправляю двоичные данные клиентам, я преобразовываю их в const data = new Uint8Array(buff);, а затем, как я могу загрузить эти данные в Babylon? - person Observablerxjs; 03.04.2020
comment
В том-то и дело, что я не знаю, поддерживает ли Babylon это! Я до сих пор не понимаю, почему вы не используете запросы XHR из загрузчика ресурсов Babylon. По какой причине вы не хотите его использовать?! - person Marc; 03.04.2020
comment
Для этого мне нужно разместить мои файлы активов на веб-сервере, и я не хочу этого делать. - person Observablerxjs; 03.04.2020
comment
@Observablerxjs, а где вы размещаете свое приложение node, где вы обслуживаете свои файлы html/js/css и babylon/? Тебе нужно! веб-сервер, даже если вы пишете его в node. Если это так, обслуживайте файлы оттуда... - person Marc; 03.04.2020
comment
хорошо, например, давайте предположим, что IP-адрес моего веб-сервера (веб-сервера node.js): 10.0.1.1 какой URL-адрес я передам в вавилон? - person Observablerxjs; 03.04.2020
comment
@Observablerxjs Это зависит от кода вашего сервера, можете ли вы также опубликовать код сервера? Но вообще, просто замените example.com своим IP-адресом. ПРИМЕЧАНИЕ: вам необходимо настроить пути к ресурсам. Если вы обслуживаете свое приложение Babylon из 10.0.1.1, тогда мой код попытается получить ресурсы из 10.0.1.1/ активы/вавилон-файлы. Причина этого в том, что babylon делает запросы к window.location и объединяет заданный путь. У вас есть публичный репозиторий? - person Marc; 03.04.2020
comment
Код моего сервера очень простой, я только что отредактировал свой пост. Также я не уверен, что такое общедоступный репозиторий или как его создать. - person Observablerxjs; 03.04.2020
comment
@Observablerxjs 1) Вы обслуживаете приложение Babylon через экспресс? Если это так: создайте папку babylon-files внутри вашей общей папки, туда вы поместите все свои файлы, которые вы хотите, чтобы babylon загружал через socket.io, готово к работе! ПРИМЕЧАНИЕ, чтобы удалить папку ресурсов в пути из клиентского кода - person Marc; 03.04.2020
comment
хорошо, последнее, я не нашел, как использовать sceneLoader, который вы предложили в своем ответе, поэтому я пошел за assetsManager, все, кажется, отправляется клиенту правильно, я вижу это в инструментах разработчика браузера, но как-то babylon.js не загружает мою модель. Я отредактировал свой пост с кодом assetsLoading - person Observablerxjs; 04.04.2020
comment
@Observablerxjs, не могли бы вы предоставить полный рабочий пример, сервер + клиент включает все файлы ресурсов (obj, mtl, jpg). лучше всего загрузить их на github. - person Marc; 04.04.2020
comment
К сожалению, я не могу поделиться всем приложением, но вот ссылка на пример модели, которую я хочу сгенерировать с помощью babylon: drive.google.com/file/d/1n6tI6AQGkCqaYfFnrJpGZRc86dPPmAaH/view , а также в отношении assetsManager, правильно ли я его реализовал? - person Observablerxjs; 04.04.2020
comment
@Observablerxjs Извините, но я не могу вам помочь без всего приложения. doc.babylonjs.com/how_to/ BABYLON.SceneLoader.Append(...) должен работать с правильными плагинами ПРИМЕЧАНИЕ: stackoverflow.com/help/minimal-reproducible-example - person Marc; 04.04.2020
comment
Давайте продолжим это обсуждение в чате. - person Observablerxjs; 04.04.2020