Dart邮件程序将成功或错误返回给客户端

时间:2014-01-31 11:51:06

标签: dart dart-io

我正在学习飞镖并创建了一个简单的联系表格 - 基于飞镖网站上的表格教程,使用邮件发送邮件。

到目前为止一切顺利 - 客户发布消息,服务器获取发布数据,创建信封并发送邮件......但我想向填写表单的人显示一条令人欣慰的消息,或者发出警告如果没有发送它们。

问题是http响应是在发送电子邮件的未来发送之前发送的 -

Chris Storm谈到使用完成者来解决这个问题,我想 - 在这里:testing error conditions with dart再一次在Dart for Hipsters的一章中,但我发现很难弄清楚如何在这里应用它。

这是完整的服务器代码 - sendMail函数中的注释显示问题。

import 'dart:io';
import 'dart:convert';
import 'package:mailer/mailer.dart';

final HOST = '127.0.0.1'; // eg: localhost
final PORT = 4040;        // a port, must match the client program

void main() {
    HttpServer.bind(HOST, PORT).then(gotMessage, onError: printError);
}

void gotMessage(_server) {
    _server.listen((HttpRequest request) {
    switch (request.method) {
      case 'POST':
        handlePost(request);
        break;
     case 'OPTIONS':
        handleOptions(request);
        break;
     default: defaultHandler(request);
     }
   },
  onError: printError); // .listen failed
  print('Listening for GET and POST on http://$HOST:$PORT');
}

/**
 * Handle POST requests
 *
 */


void handlePost(HttpRequest req) {
  HttpResponse res = req.response;
  print('${req.method}: ${req.uri.path}');

  addCorsHeaders(res);

  req.listen((List<int> buffer) {
     // Create a new string from the characters in the buffer and convert this into a map
    Map postData = JSON.decode(new String.fromCharCodes(buffer));
    res.write(sendMail(postData));
    res.close();
  },

  onError: printError);
}

/**
 * Add Cross-site headers to enable accessing this server from pages
 * not served by this server
 *
 * See: http://www.html5rocks.com/en/tutorials/cors/
 * and http://enable-cors.org/server.html
 */
void addCorsHeaders(HttpResponse res) {
  res.headers.add('Access-Control-Allow-Origin', '*, ');
  res.headers.add('Access-Control-Allow-Methods', 'POST, OPTIONS');
  res.headers.add('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
}

void handleOptions(HttpRequest req) {
  HttpResponse res = req.response;
  addCorsHeaders(res);
  print('${req.method}: ${req.uri.path}');
  res.statusCode = HttpStatus.NO_CONTENT;
  res.close();
}

void defaultHandler(HttpRequest req) {
  HttpResponse res = req.response;
  addCorsHeaders(res);
  res.statusCode = HttpStatus.NOT_FOUND;
  res.write('Not found: ${req.method}, ${req.uri.path}');
  res.close();
}

void printError(error) => print(error);

sendMail(postData) {

  String sentMsg = 'I am waiting for a result to report'; //initialised value

  var options = new GmailSmtpOptions()
  ..username = 'my.mailt@gmail.com' //shove real values in here to test
  ..password = 'my_password';

  var transport = new SmtpTransport(options);

  // Create the envelope to send.
  var envelope = new Envelope()
  ..fromName = postData['name']
  ..from = postData['fromEmail']
  ..recipients = ['the_recipient@somedomain.com']
  ..subject = 'Message from contact form'
  ..text = postData['contactMessage'];


  transport.send(envelope)
    .then((success) => sentMsg = 'Message sent, thank you.' ) //this will not be returned...
    .catchError((e) => sentMsg = 'Message not sent; the reported error was: $e'); // nor will this

  return sentMsg; // Sadly the initial value will be returned as the future (transport.send) will not have completed

}

2 个答案:

答案 0 :(得分:0)

您的代码看起来不错:)

据我所知,并没有多少遗漏(尽管没有尝试过执行)。

  request.response.write('Hello, world'); 
  request.response.close();

位于handlePost()(您可以req可用的地方) 返回您要从handlePost()返回到gotMessage()的客户端的结果,并在其中添加以上行。

另请查看An Introduction to the dart:io Library - Writing web servers

答案 1 :(得分:0)

如果我做对了,你想根据transport.send()的结果发送回复。如果是这样,你可以返回它,比如

  return transport.send(envelope)
    .then((success) => sentMsg = 'Message sent, thank you.' )
    .catchError((e) => sentMsg = 'Message not sent; the reported error was: $e');

或使用Completer

  var c = new Completer();

  transport.send(envelope)
    .then((success) => sentMsg = 'Message sent, thank you.' )
    .then(c.complete)
    .catchError((e) => sentMsg = 'Message not sent; the reported error was: $e');

  return c.future;

由于您要返回Future,您必须更改向客户发送回复的方式,

res.write(sendMail(postData));
res.close();

sendMail(postData)
  .then((result) {
    res.write(result);
    res.close();
  });