3

我正在创建一个协作网络音乐平台。

目前,我有一台在本地工作的简单鼓机,带有一个记录所有节拍的 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 文件?(他们会轮流编辑图案,比如这个游戏http://sharejs.org/hex.html#9TGAyPGFOy)这个JSON文件需要在代码中随时更新,所以最新版本的赛道可以播放给两个用户。

任何提示都会很棒,我觉得我在这里过于复杂了......

谢谢

4

3 回答 3

2

我建议在这个项目中使用Socket.io

您可以使用以下代码设置一个简单的套接字服务器:

(别忘了npm install --save 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>

我基本上只是在答案框中输入了这个 - 这还没有经过测试或其他什么,但我认为它让您对项目的 Socket.io 库的基础有了一个很好的了解。

正如我在评论中提到的,我不建议在执行文件系统操作时使用 *sync 方法。这种方法更容易阅读,但会在读取/写入文件时锁定整个过程。如果有多个用户使用该项目,这将导致问题。查看 *async 方法来解决这个问题。它们实施起来并不难。

祝你好运!

于 2015-03-09T13:51:07.890 回答
0

让我们尽可能简化这一点。

最简单的解决方案是在内存中(在您的 node.js 服务器中)有一个 javascript 对象,并让用户通过单个 API 调用对其进行编辑。像,

app.put('/composition', updateJSONObject)

updateJSONObject函数将读取内存中的 javascript 对象,对其进行编辑,然后返回更新后的对象。

app.get('/composition', getJSONObject)

此路由将获取最新的 JSON 对象。

(我假设你在这里使用 express.js)

然后,定期使用(每 1 分钟一次?)setInterval将您的 javascript 对象保存到文件系统中。fs.createWriteStream这将保存您的 json 对象filename.json,如果内存中的 json 对象为空,您可以检索该对象。(例如,在服务器重新启动后)

处理碰撞是一个更大的问题。但是由于您不想使解决方案过于复杂,所以这很简单,并且可以完成工作,除非您期望每秒进行 100 次编辑。

于 2015-03-09T13:58:40.693 回答
-2

我认为你的服务器上的一个简单的 PHP 脚本可以在这里解决问题。

您可以为每个会话创建一个 JSON/txt 文件(可能为每个会话生成一个随机 ID)并使用 AJAX 将两个用户的数据发送到服务器,然后服务器将更新 JSON 文件。

您可以将 jQuery 用于 AJAX:

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

在您的 PHP 中,您可以获取 POST 数据:

$data = $_POST['data'];

这将是一个字符串,您可以将其保存到您的服务器上。 是一个使用 PHP 保存文件的教程。

要取回数据,您只需从服务器重新加载 JSON 文件。我建议将整个内容保存为一个字符串(JSON.stringify()在 Javascript 中),然后JSON.parse()在你取回它时使用它来解码它。

鉴于用户将轮流使用,这种架构应该可以正常工作。

LMK 如果有什么我不清楚的地方,祝你好运!

于 2015-03-09T13:47:41.633 回答