Node.js и связь сокетов LÖVE2D

Я пытаюсь заставить сервер node.js и клиент LÖVE2D общаться через сокеты. (Просто простой тест «Hello World».) И node.js, и LÖVE2D работают на одном ПК.

Мне удалось отправить сообщение от LÖVE2D на node.js, но я не могу прочитать ответ сервера.

Код моего сервера node.js выглядит так:

var net = require('net');
var mySocket;

var server = net.createServer(function(socket) {
    mySocket = socket;
    mySocket.on("connect", onConnect);
    mySocket.on("data", onData);
});

function onConnect() {
    console.log("Connected to LOVE2D");
}

function onData(d) {
    if(d == "exit\0") {
        console.log("exit");
        mySocket.end();
        server.close();
    }
    else {
        console.log("Message from LOVE2D: " + d);
        mySocket.write("Message received!", 'utf8');
    }
}

server.listen(50000, "localhost");

А клиентский код в LÖVE2D выглядит так:

local host, port = "localhost", 50000
local socket = require("socket")
local tcp = assert(socket.tcp())

tcp:connect(host, port)
tcp:send("hello there")
tcp:close()

function love.draw()
    love.graphics.print("can't read server answer!", 400, 300)
end

Ну, предыдущий код просто отправляет сообщение. Какой синтаксис следует использовать для чтения ответа с сервера node.js? Например, это просто дает мне ошибку:

local host, port = "localhost", 50000
local socket = require("socket")
local tcp = assert(socket.tcp())

tcp:connect(host, port)
local answer = tcp:send("hello there")
tcp:close()

function love.draw()
    love.graphics.print(answer, 400, 300)
end

Вот некоторая документация по работе с сетью в LÖVE2D и LuaSocket, но документация мне в этом не помогла:

http://love2d.org/wiki/Tutorial:Networking_with_UDP

http://w3.impa.br/~diego/software/luasocket/

(Извините за «нубский» вопрос, я действительно новичок в HTTP-протоколах и прочем.)


person apk    schedule 29.09.2014    source источник


Ответы (1)


Вам также необходимо использовать вызов receive:

tcp:connect(host, port)
tcp:send("hello there\n")
local answer = tcp:receive()
tcp:close()

function love.draw()
    love.graphics.print(answer, 400, 300)
end

Будьте осторожны с новыми строками в ваших сообщениях; «шаблон» по умолчанию для receive заключается в чтении одной строки (завершаемой CR?LF), поэтому, если символы конца строки отсутствуют, операция приема будет заблокирована в ожидании их. Альтернативой может быть чтение определенного количества символов, но, поскольку вы не знаете длину сообщения, вам нужно будет придумать какой-то заголовок (например, сначала отправить два байта, которые кодируют длину следующего сообщения).

Также можно использовать комбинацию: сначала отправьте одну строку и включите количество байтов в полезной нагрузке, которая последует (если есть). Например, «200 OK 135» или «500 ERROR», а затем используйте эту длину (135 в сообщении OK), чтобы прочитать: tcp:receive(135).

Если вы в конечном итоге используете протокол на основе TCP, вам, вероятно, потребуется сделать его неблокирующим, иначе любая сетевая задержка заблокирует вашу игру; см. этот SO ответ для некоторых указателей.

person Paul Kulchenko    schedule 29.09.2014
comment
Спасибо! Теперь работает как шарм. Хорошо, что вы упомянули символ конца строки. LÖVE2D действительно зависал до того, как я изменил эту строку: mySocket.write(Сообщение получено!\n, 'utf8'); - person apk; 29.09.2014