Как получить значения ключей Redis на сервере Dart с помощью Angel - PullRequest
0 голосов
/ 02 мая 2020

Переместив разработку мобильных приложений во Flutter, я сейчас экспериментирую с использованием Dart в качестве основного языка на стороне сервера. Преимущества производительности при использовании одного языка кодирования как в приложении, так и на сервере, значительны. Для этого я настроил сервер с интерфейсом Nginx, который передает все динамические c веб-запросы на сервер Angel / Dart .

Ангел - удивительно хорошо написанный пакет, и у меня рабочий сервер был написан в кратчайшие сроки. Однако, чтобы иметь полностью функциональный бэкэнд, мне нужно иметь возможность использовать Redis и PostgreSQL из моего кода Dart на стороне сервера. Я использую пакет resp_client для доступа к Redis. Проблема, с которой я столкнулся, связана с тем, что RespCommand.get является асинхронным. С моим новым ie знанием как Дарт, так и Ангела я не могу найти способ получить значение ключа Redis через RespCommand.get в обработчике маршрута Angel, а затем каким-то образом использовать это значение в ответе, который он возвращает.

Весь мой код внутреннего сервера Dart показан ниже

import 'package:angel_framework/angel_framework.dart';
import 'package:angel_framework/http.dart';
import 'package:postgres/postgres.dart';
import 'package:resp_client/resp_client.dart';
import 'package:resp_client/resp_commands.dart';


class DartWeb
{
 static Angel angel;
 static AngelHttp http;
 static RespCommands redis;
 static PostgreSQLConnection db;

 static init() async
 {
  angel = Angel();
  http = AngelHttp(angel);
  angel.get('/',rootRoute);
  await prepareRedis();
  await http.startServer('localhost',3000); 
 }

 static prepareRedis() async
 {
  RespServerConnection rsc =  await connectSocket('localhost');
  RespClient client =  RespClient(rsc);
  redis = RespCommands(client); 
 } 

 static preparePostgres() async
 {
  db = new PostgreSQLConnection('serverurl',portNo,'database',username:'user',password:'password');
  await db.open(); 
 }

 static void rootRoute(RequestContext req,ResponseContext res)
 {
  try
  { 
   await redis.set('test','foobar',expire:Duration(seconds:10));
   String testVal = await redis.get('test');
   res.write('Done $testVal'); 
  } catch(e) {res.write('++ $e ++');}
 }
} 

main() async {await DartWeb.init();}

Если я запускаю этот сервер и затем получаю к нему доступ через свой веб-браузер, я получаю сообщение 502 Bad Gateway. Неудивительно. dart2native main.dart -o mainCompiled возвращает сообщение об ошибке await can only be used in async....

Поэтому я попытался вместо этого

try
{ 
 res.write('Before');
 redis.set('test','foobar',expire:Duration(seconds:10)).then((bool done)
 {
  res.write('DONE $done'); 
 });
 res.write('After');
} catch(e) {res.write('++ $e ++');}

, который просто выводил BeforeAfter в моем браузере с битом DONE не показывается, хотя быстрый тест с помощью redis-cli показывает, что ключ test действительно был создан.

Мои знания о Дарт и Ангеле все еще находятся в зачаточном состоянии, поэтому я предполагаю, что что-то делаю неправильно Вот. Мне не хватает всей детализации моих вопросов по существу -

  • как мне вызвать и получить результат от async методов в диспетчере маршрутов Angel?
  • , учитывая, что я редактирую мой код Dart в VSCode на моем локальном компьютере Windows, который обращается к соответствующим файлам dart на моем сервере Ubuntu, я теряю преимущества отчетов об ошибках, предоставляемых плагином VSCode Dart. dart2native, как я здесь использовал, помогает, но было бы лучше, если бы я мог каким-то образом получить отчет об ошибке в VSCode, как при локальном создании приложений Flutter. Как я могу выполнить sh это - если это вообще возможно?

1 Ответ

1 голос
/ 04 мая 2020

Оказывается, что Dart / Angel не накладывает чрезмерно строгих ограничений на сигнатуру обработчика маршрута. Таким образом, вы можете совершенно безопасно объявить такой обработчик маршрута, как этот

 static Future<void> rootRoute(RequestContext req,ResponseContext res) async
 {
  try
  { 
   res.write('!! Before '); 
   await redis.set('test','foobar',expire:Duration(seconds:10));
   String test = await redis.get('test');
   res.write('After $test !!');
  } catch(e) {res.write('++ $e ++');} 
 }

. Когда маршрут просто возвращает будущее, теперь мы можем безопасно делать все, что захотим, включая вызов других асинхронных методов: в этом случае, чтобы получить Значение ключа Redis.

...