2016-09-14 2 views
0

Я хотел написать для своих тестов OUnit небольшой сервер, который, когда клиент подключается к сокету, передает данные клиенту и завершает работу.OCaml: ожидалось выражение Lwt от единицы типа Lwt.t

Поскольку я хотел использовать это в своих тестах, мне показалось, что я должен создать сервер в потоке и создать клиент в потоке. Так вот код:

open Sys 
open Unix 
open Lwt 

(* a simple server that send a message when a client connects 
* compile with 
* ocamlfind ocamlc -o lwt_server -package lwt,lwt.unix,unix -linkpkg -g lwt_server.ml 
* http://baturin.org/code/lwt-counter-server/ 
* https://mirage.io/wiki/tutorial-lwt 
* http://aubedesheros.blogspot.fr/2011/05/ocaml-lwt-mini-tutorial.html 
*) 

let host = Unix.inet_addr_loopback (* 127.0.0.1 *) 
let port = 6600 
let max_pending_request = 10 

(* Initialize logging capabilities at INFO level *) 

let() = Lwt_log.add_rule "*" Lwt_log.Info 

let send_message oc = 
    Lwt_io.write_line oc "test" 

let accept_connection conn = 
    let fd, _ = conn in 
    let oc = Lwt_io.of_fd Lwt_io.Output fd in 
    Lwt.on_failure (send_message oc) (fun e -> Lwt_log.ign_error (Printexc.to_string e)); 
    Lwt_log.info "New connection" >>= return 

let create_server sock = 
    let serve() = 
    Lwt_unix.accept sock >>= accept_connection 
    in serve 

let sock_recv sock maxlen = 
    let str = Bytes.create maxlen in 
    let recvlen = recv sock str 0 maxlen [] in 
    String.sub str 0 recvlen 

let sock_read sock = 
    let answer = sock_recv sock 512 in 
    Lwt_io.write_line Lwt_io.stdout answer 

let create_socket() = 
    let sock = Lwt_unix.socket PF_INET SOCK_STREAM 0 in 
    Lwt_unix.bind sock @@ ADDR_INET(host, port); 
    Lwt_unix.listen sock max_pending_request; 
    sock 


let() = 
    let sock = create_socket() in 
    let threads = Lwt.join [create_server sock; sock_read sock] in 
     Lwt_main.run threads 

Здесь команда я использую в Одер, чтобы скомпилировать и сообщение об ошибке

ocamlfind ocamlc -o lwt_server -package lwt,lwt.unix,unix -linkpkg -g lwt_server.ml 
File "lwt_server.ml", line 53, characters 28-46: 
Error: This expression has type unit -> unit Lwt.t 
     but an expression was expected of type unit Lwt.t 

Линия 53 относится к (не шутка, я проверил дважды):

 let threads = Lwt.join [create_server sock; sock_read sock] in 

это первый раз я использую LWT, я не уверен, что это решение следует использовать с OUnit.

ответ

1

Вопрос заключается в том, что create_server sock возвращает другую функцию типа unit -> unit Lwt.t, а не в потоке LWT (unit Lwt.t), как указано в сообщении об ошибке типа:

let create_server sock = 
    let serve() = 
    Lwt_unix.accept sock >>= accept_connection 
    in serve (* serve is a function, not a thread *) 

Вы можете переписать это вернуть поток, а не в зависимости от исправьте этот тип ошибки:

let create_server sock = 
    Lwt_unix.accept sock >>= accept_connection 

Я не тестировал код в целом, но это должно исправить ошибку типа.

Смежные вопросы