Чтение HTTP-запроса с сокетами на HashLink - PullRequest
3 голосов
/ 06 апреля 2019

Я пытаюсь создать HTTP-сервер, использующий haxe (4) с HashLink (1.9.0) и сокеты, кажется, не очень хорошо работают.

import haxe.io.Error;
import sys.net.Host;
import sys.net.Socket;

class Main {
    static public function main() {

        var _aSocketDistant = new List<Socket>();

        var _oSocketMaster = new Socket();
        _oSocketMaster.bind( new Host( 'localhost' ), 8000);
        _oSocketMaster.setBlocking( false );
        _oSocketMaster.listen( 9999 );

        while(true) {

            // Accepting socket
            var oSocketDistant = _oSocketMaster.accept();
            if ( oSocketDistant != null ) {
                trace( 'opening : ' + oSocketDistant.peer() );
                oSocketDistant.setBlocking( false );
                _aSocketDistant.add( oSocketDistant );
            }

            // Trying to read from each socket 
            for ( oSocketDistant in _aSocketDistant ) {
                try {
                    trace( oSocketDistant.read() );
                } catch ( e :Dynamic ) {
                    if ( e != Error.Blocked )
                        throw e;
                }
            }

        }
    }
}

Выполнение этого бита кода, а затем вызов http://localhost:8000/ с использованием Firefox дает мне следующее:

Main.hx: 27: открытие: {хост: 127.0.0.1, порт: 65154}

В удаленном сокете никогда не будет сообщений для чтения. Разве он не должен отправить запрос?

1 Ответ

2 голосов
/ 06 апреля 2019

Кажется, проблема в использовании read().Кажется, это не предназначено для использования на неблокирующих сокетах :

Ваша фактическая проблема заключается в том, что read() будет считывать все данные.На блокирующем сокете, который будет блокироваться, пока соединение не будет закрыто.На неблокирующем сокете, который всегда будет поднимать Blocking.Вместо этого вы должны использовать input.readBytes, который вернет количество прочитанных байтов, а затем убедитесь, что вы правильно управляете данными буфера.

В этом случае использование input.readLine(), вероятно, является самым простым решением.:

trace(oSocketDistant.input.readLine());

При этом я могу видеть HTTP-запрос, как и ожидалось:

Main.hx:20: opening : {host : 127.0.0.1, port : 50231}
Main.hx:29: GET / HTTP/1.1
Main.hx:29: Host: localhost:8008
Main.hx:29: Connection: keep-alive
Main.hx:29: Upgrade-Insecure-Requests: 1
Main.hx:29: User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
Main.hx:29: DNT: 1
Main.hx:29: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Main.hx:29: Accept-Encoding: gzip, deflate, br
Main.hx:29: Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
Main.hx:29: Cookie: Idea-369662de=0cbb3289-7f2c-4f82-a094-7409dba8cfb0
Main.hx:29:
...