Node.js中的客户端 - 服务器通信?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (174)

我最近一直在使用node.js进行在线游戏(用于教育)。通过阅读各种教程,我提出了如下所示的简单代码。使用我拥有的代码,我能够进行客户端 - 服务器通信,这主要是我为了制作游戏而需要的。只有一个问题,只有客户端可以启动对话,而服务器只能响应。除此之外,我还需要在任何时刻将当前游戏状态从服务器发送到客户端。例如,在2人游戏中,当玩家发送改变游戏状态的命令时,需要将新游戏状态转发给BOTH玩家。

在node.js中有一个简单的方法可以做到这一点吗?我知道你不能简单地向客户端发送消息,因为不能指望客户端为服务器打开一个端口,但也许有一种方法让客户端留下连接供服务器使用?我是那种通过实例学习的人,因此可以欣赏一些简单的工作代码。

顺便说一下,我正在firebase上主持游戏,以防万一。

index.js:

const functions = require('firebase-functions');
const express = require('express');

const app = express();

app.post('/game', (request, response) => {
    request.body.randomNumber = Math.random();
    console.log(request.body);
    response.json(request.body);
});

exports.app = functions.https.onRequest(app);

index.html的:

<!DOCTYPE html>
<html>
  <head>
    <title>Page Title</title>
  </head>
  <body>

    <input type="text" id="commandbox" onkeypress="send(this)">
    <br>
    <div id="display"></div>

    <script>
      const send = (ele) => {
        if (event.key === 'Enter') {
          console.log(ele.value);
          const json = {
            name: "John",
            gender: "male",
            age: 25, 
            message: ele.value
          };
          postToGame(json);
        }
      };
    </script>

    <script>
      const postToGame = (json) => {
        const xhr = new XMLHttpRequest();
        xhr.open("POST", '/game', true);
        xhr.setRequestHeader("Content-type", "application/json");
        xhr.onload = () => {
          if (xhr.readyState == 4 && xhr.status == 200) {
            document.getElementById("display").innerHTML = xhr.responseText;
          }
        };
        xhr.send(JSON.stringify(json));
      }
    </script>

  </body>
</html>
提问于
用户回答回答于

我会为此使用websockets。设置连接后,您可以从任一方发起消息。该WS NPM包使这很容易。

服务器示例(使用ws npm包):

    const WebSocket = require('ws');

    // Set up server
    const wss = new WebSocket.Server({ port: 8080 });

    // Wire up some logic for the connection event (when a client connects) 
    wss.on('connection', function connection(ws) {

      // Wire up logic for the message event (when a client sends something)
      ws.on('message', function incoming(message) {
        console.log('received: %s', message);
      });

      // Send a message
      ws.send('Hello client!');
    });

客户端示例(这里不需要任何软件包,它内置于大多数浏览器中):

// Create WebSocket connection.
const socket = new WebSocket('ws://localhost:8080');

// Connection opened
socket.addEventListener('open', function (event) {
    socket.send('Hello Server!');
});

// Listen for messages
socket.addEventListener('message', function (event) {
    console.log('Message from server ', event.data);
});

如果您不能使用websockets,例如轮询(客户端定期调用服务器以查看是否有消息),还有长轮询(服务器在人为的长时间内保持http请求打开的位置),则有其他选择直到消息准备就绪)。

用户回答回答于

Firebase实时数据库是另一种选择。

https://github.com/firebase/quickstart-js/blob/master/database/scripts/main.js

<!-- index.html file in client browser -->
<script src="/__/firebase/5.5.0/firebase-app.js"></script>
<script src="/__/firebase/5.5.0/firebase-auth.js"></script>
<script src="/__/firebase/5.5.0/firebase-database.js"></script>
<script src="/__/firebase/init.js"></script>

<script src="scripts/main.js"></script>

<!-- main.js file in client browser -->
// Create new comment.
// createNewComment, commentInput, addCommentForm is defined in the main.js
addCommentForm.onsubmit = function(e) {
    e.preventDefault();
    createNewComment(postId, firebase.auth().currentUser.displayName, uid, commentInput.value);
    commentInput.value = '';
    commentInput.parentElement.MaterialTextfield.boundUpdateClassesHandler();
};
// Listen for comments.
// addCommentElement, postElement is defined in the main.js
var commentsRef = firebase.database().ref('post-comments/' + postId);
commentsRef.on('child_added', function(data) {
    addCommentElement(postElement, data.key, data.val().text, data.val().author);
});

扫码关注云+社区

领取腾讯云代金券