2015-03-09 1 views
3

Я создаю совместную платформу для веб-музыки.Как два пользователя могут совместно редактировать файл JSON?

В настоящее время у меня есть простая драм-машина, работающая локально, с файлом JSON, регистрирующим все биты. т. е. после штамповки в шаблоне, код выглядит так, когда он регистрируется на консоли. Затем функция планировщика и воспроизведения выполняет итерацию и играет в ритме, если она «включена» в текущем ритме.

"kick": [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0], 
    "snare": [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], 
    "hat": [0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1], 
    "tom1": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    "tom2": [0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0], 
    "tom3": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 

Так что в следующий я хочу сети это веб-приложение, так что два человека могут изменить картину в то же время. Я действительно борется и буду любить какую-то помощь здесь. Я посмотрел на метеор и sharejs, но стал довольно смущен.

Как я могу получить файл JSON на сервере, который редактируется двумя пользователями? (они будут поочередно редактировать шаблон, как эта игра). Этот JSON-файл должен постоянно обновляться в коде, поэтому последнюю версию трека можно воспроизводить для обоих пользователей.

Любые советы было бы здорово, я чувствую, что я усложнять себе здесь ...

Благодаря

+0

Не мог бы контролировать исходный код, например [git] (http://git-scm.com/)? Когда вы вытягиваете работу другого человека, вы можете объединить файлы вместе, чтобы у вас было самое последнее. –

+1

Я предполагаю, что OP хочет, чтобы у двух пользователей был отредактирован шаблон и сервер воспроизводил отрегулированный ритм для них как в реальном времени. – Andy

+0

Концепция похожа на эту игру; http://sharejs.org/hex.html#9TGAyPGFOy. Пользователи нажимают на пользовательский интерфейс, который изменяет JSON-файл, который они могут воспроизводить как последнюю версию. Таким образом, оба пользователя имеют контроль над основным файлом журнала магистрали на сервере. – futureRobin

ответ

2

Я бы предложил использовать Socket.io для этого проекта.

Вы могли бы иметь сервер простой сокет настроить, с помощью следующего кода:

// server.js 

// we're using filesystem stuff here 
var fs = require('fs'); 

// set up socket.io 
var io = require('socket.io').listen(80); 

// load the current json file in 
var currentJSON = fs.readFileSync('./beat.json'); 

io.on('connection', function(clientSocket) { 

    console.log('Client connected!'); 

    // tell the client that just connected what the current JSON is 
    clientSocket.emit('stateUpdate', {currentJSON: currentJSON}); 

    // listen for an "update" event from a client 
    clientSocket.on('update', function(payload) { 
     if(payload.updatedJSON) { 

      console.log('We got updated JSON!'); 

      // validate the incoming JSON here 
      validateBeatJSON(payload.updatedJSON); 

      // update the "currentJSON" variable to reflect what the client sent 
      currentJSON = payload.updatedJSON; 

      // save the json file so the server will have it when it next starts. also, try not to use *sync methods for this, as they'll block the server but ive included them cos they're shorter 
      fs.writeFileSync('/beat.json', JSON.stringify(payload.updatedJSON), 'utf8'); 

      // tell the other clients what the current state is 
      clientSocket.broadcast.emit('stateUpdate', {currentJSON: currentJSON}); 

     } 
    }); 

}); 

//client.html 
<script src="socket.io.js"></script> 
<script> 
var currentJSON = []; 
var socket = io(); // TIP: io() with no args does auto-discovery 
    socket.on('stateUpdate', function (payload) { 
    currentJSON = payload.currentJSON; 
    }); 

    // blah blah, set event for when the json is updated 
    window.addEventListener('updatedJSONLocally', function(e) { 
    socket.emit('update', {updatedJSON: currentJSON}); 
    }); 

</script> 

Я в основном только что ввели это в поле ответа - это (не забудьте npm install --save socket.io!) не тестировалось или что-то еще, но я думаю, что это дает вам представление об основах библиотеки Socket.io для вашего проекта.

Как уже упоминалось в моих комментариях, я не советую использовать * методы синхронизации при выполнении операций с файловой системой. Этот метод немного легче читать, но блокирует весь процесс, пока файл читается/записывается. Это приведет к проблемам, если в проекте задействовано более двух пользователей. Изучите методы * async для способов борьбы с этим. Их не намного сложнее реализовать.

Удачи вам!

+0

Фантастический, это очень помогло мне, спасибо. – futureRobin

+0

Не забывайте, что запись файла синхронно - это простой способ реализовать это. В реальной производственной среде нельзя блокировать целый процесс с помощью синхронной записи файлов. С асинхронной записью у вас должен быть какой-то механизм блокировки/queiing. – Capaj

+0

@futureRobin, если это было полезно - пожалуйста, не стесняйтесь принять этот ответ :) – freshnode

-2

Я думаю, простой PHP скрипт на вашем сервере будет делать трюк здесь.

У вас может быть файл JSON/txt для каждого сеанса (возможно, сгенерировать случайный идентификатор для каждого) и использовать AJAX для отправки данных от обоих пользователей на сервер, который затем обновит файл JSON.

Вы можете использовать JQuery для AJAX:

$.post("myscript.php", { data: 'json goes here' }); 

В вашем PHP, вы можете получить данные POST:

$data = $_POST['data']; 

Какой будет строка, которую можно сохранить на вашем сервере. Here - это учебник по сохранению файлов с PHP.

Чтобы вернуть данные, необходимо просто перезагрузить JSON-файл с сервера. Я бы предложил сохранить все это как строку (JSON.stringify() в Javascript), а затем с помощью JSON.parse(), чтобы декодировать ее, когда вы ее получите.

Учитывая, что пользователи будут по очереди, эта архитектура должна работать нормально.

LMK, если есть что-то, о чем я не понимаю, и удачи!

+1

OP уже использует Node.js по внешнему виду вещей - не нужно добавлять больше языков в микс. Это также не помогает с точки зрения совместной работы в реальном времени (что вы ожидаете от проекта генерации музыки). – freshnode

0

Давайте упростим это как можно больше.

Простейшим решением было бы иметь объект javascript в памяти (на вашем сервере node.js) и позволить пользователям редактировать это из одного вызова API. Мол,

app.put('/composition', updateJSONObject) 

updateJSONObject функция будет читать в памяти объектов JavaScript, отредактировать его и вернуть обновленный один.

app.get('/composition', getJSONObject) 

Этот маршрут получит последний объект JSON.

(я предполагаю, что вы используете express.js здесь)

А потом, сделать простой setInterval сохранить объектов JavaScript в файловой системе с помощью fs.createWriteStream периодически (раз в 1 минуту?). Это сохранит ваш json-объект, например filename.json, который вы можете получить, если объект json in-memory пуст. (Например, после перезапуска сервера)

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