更新http服务器 剔除反射功能
This commit is contained in:
14
build.yaml
Normal file
14
build.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
targets:
|
||||||
|
$default:
|
||||||
|
builders:
|
||||||
|
EasyDartModule|route_generator:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
builders:
|
||||||
|
route_generator:
|
||||||
|
target: ":route_generator"
|
||||||
|
import: "package:EasyDartModule/base/webserver/impl/RouteGenerator.dart"
|
||||||
|
builder_factories: ["routeGenerator"]
|
||||||
|
build_extensions: { ".dart": [".route.dart"] }
|
||||||
|
auto_apply: root_package
|
||||||
|
build_to: source
|
||||||
@@ -15,6 +15,7 @@ import 'package:EasyDartModule/base/webserver/WebServer.dart';
|
|||||||
import 'package:EasyDartModule/base/webserver/impl/ShelfWebServer.dart'
|
import 'package:EasyDartModule/base/webserver/impl/ShelfWebServer.dart'
|
||||||
if (dart.library.html) 'package:EasyDartModule/base/webserver/impl/ShelfWebServer_none.dart';
|
if (dart.library.html) 'package:EasyDartModule/base/webserver/impl/ShelfWebServer_none.dart';
|
||||||
import 'package:EasyDartModule/base/websocket/WebSocket.dart';
|
import 'package:EasyDartModule/base/websocket/WebSocket.dart';
|
||||||
|
import 'package:event_bus/event_bus.dart';
|
||||||
|
|
||||||
export 'package:shelf/shelf.dart';
|
export 'package:shelf/shelf.dart';
|
||||||
export 'package:mongo_dart/mongo_dart.dart';
|
export 'package:mongo_dart/mongo_dart.dart';
|
||||||
@@ -29,6 +30,9 @@ class EasyDartModule {
|
|||||||
static Storage get storage => Storage.getInstance();
|
static Storage get storage => Storage.getInstance();
|
||||||
static Redis get redis => Redis.getInstance();
|
static Redis get redis => Redis.getInstance();
|
||||||
static WebSocket get websocket => WebSocket.getInstance();
|
static WebSocket get websocket => WebSocket.getInstance();
|
||||||
|
// 全局事件总线
|
||||||
|
static final EventBus _eventBus = EventBus();
|
||||||
|
static EventBus get eventBus => _eventBus;
|
||||||
|
|
||||||
static bool init({
|
static bool init({
|
||||||
DiscoveryConfig? discoveryConfig,
|
DiscoveryConfig? discoveryConfig,
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class TraceDio {
|
|||||||
"请求错误: url:${e.requestOptions.path} 请求方法:${e.requestOptions.method} 请求数据:${e.requestOptions.data} 响应代码:${e.response?.statusCode} 响应消息:${e.response?.statusMessage} 响应内容:${e.response?.data}";
|
"请求错误: url:${e.requestOptions.path} 请求方法:${e.requestOptions.method} 请求数据:${e.requestOptions.data} 响应代码:${e.response?.statusCode} 响应消息:${e.response?.statusMessage} 响应内容:${e.response?.data}";
|
||||||
} else {
|
} else {
|
||||||
errMsg =
|
errMsg =
|
||||||
"请求错误: url:${e.requestOptions.path} 请求方法:${e.requestOptions.method} 请求数据:${e.requestOptions.data} 错误消息:${e.error}";
|
"请求错误: url:${e.requestOptions.path} 请求方法:${e.requestOptions.method} 请求数据:${e.requestOptions.data} 错误消息:${e.message ?? e.error}";
|
||||||
}
|
}
|
||||||
|
|
||||||
print(errMsg);
|
print(errMsg);
|
||||||
@@ -103,18 +103,12 @@ class TraceDio {
|
|||||||
sf.Request? request,
|
sf.Request? request,
|
||||||
ResponseType? responseType,
|
ResponseType? responseType,
|
||||||
Duration? receiveTimeout}) async {
|
Duration? receiveTimeout}) async {
|
||||||
try {
|
return await _dio.get(url,
|
||||||
return await _dio.get(url,
|
queryParameters: queryParameters,
|
||||||
queryParameters: queryParameters,
|
options: Options(
|
||||||
options: Options(
|
receiveTimeout: receiveTimeout,
|
||||||
receiveTimeout: receiveTimeout,
|
headers: getHeader(request: request),
|
||||||
headers: getHeader(request: request),
|
responseType: responseType));
|
||||||
responseType: responseType));
|
|
||||||
} catch (e) {
|
|
||||||
//api接口报错
|
|
||||||
var a = e as DioException;
|
|
||||||
return a.response!;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发起 POST 请求
|
// 发起 POST 请求
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:mqtt5_client/mqtt5_client.dart';
|
import 'package:mqtt5_client/mqtt5_client.dart';
|
||||||
import 'package:mqtt5_client/mqtt5_server_client.dart';
|
import 'package:mqtt5_client/mqtt5_server_client.dart';
|
||||||
@@ -29,7 +30,14 @@ class Mqtt {
|
|||||||
_config.port);
|
_config.port);
|
||||||
_client?.autoReconnect = true;
|
_client?.autoReconnect = true;
|
||||||
|
|
||||||
var state = await _client?.connect(_config.username, _config.password);
|
MqttConnectionStatus? state;
|
||||||
|
try {
|
||||||
|
state = await _client?.connect(_config.username, _config.password);
|
||||||
|
} catch (e) {
|
||||||
|
//连接错误
|
||||||
|
print("mqtt连接失败: 地址:${_config.host} 原因:$e");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (state!.state != MqttConnectionState.connected) {
|
if (state!.state != MqttConnectionState.connected) {
|
||||||
//连接失败
|
//连接失败
|
||||||
print("mqtt连接失败: 地址:${_config.host} 原因:$state");
|
print("mqtt连接失败: 地址:${_config.host} 原因:$state");
|
||||||
@@ -39,10 +47,20 @@ class Mqtt {
|
|||||||
|
|
||||||
_client?.updates.listen((List<MqttReceivedMessage<MqttMessage>> message) {
|
_client?.updates.listen((List<MqttReceivedMessage<MqttMessage>> message) {
|
||||||
final recMess = message[0].payload as MqttPublishMessage;
|
final recMess = message[0].payload as MqttPublishMessage;
|
||||||
final payload = Utf8Decoder().convert(recMess.payload.message!);
|
try {
|
||||||
// final payload =
|
if (_config.messgae != null) {
|
||||||
// MqttUtilities.bytesToStringAsString(recMess.payload.message!);
|
final payload = Utf8Decoder().convert(recMess.payload.message!);
|
||||||
_config.messgae(message[0].topic!, payload);
|
// final payload =
|
||||||
|
// MqttUtilities.bytesToStringAsString(recMess.payload.message!);
|
||||||
|
_config.messgae!(message[0].topic!, payload);
|
||||||
|
} else if (_config.buffMessage != null) {
|
||||||
|
_config.buffMessage!(
|
||||||
|
message[0].topic!, recMess.payload.message!.buffer.asUint8List());
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
//转字符串失败
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
_config.topic?.forEach((topic) {
|
_config.topic?.forEach((topic) {
|
||||||
subscribe(topic, _config.qos);
|
subscribe(topic, _config.qos);
|
||||||
@@ -80,13 +98,17 @@ class MqttConfig {
|
|||||||
String? password;
|
String? password;
|
||||||
List<String>? topic;
|
List<String>? topic;
|
||||||
int qos;
|
int qos;
|
||||||
Function(String topic, String message) messgae;
|
//文本消息
|
||||||
|
Function(String topic, String message)? messgae;
|
||||||
|
//二进制消息
|
||||||
|
Function(String topic, Uint8List buff)? buffMessage;
|
||||||
|
|
||||||
MqttConfig(
|
MqttConfig(
|
||||||
{required this.host,
|
{required this.host,
|
||||||
this.port = 1883,
|
this.port = 1883,
|
||||||
required this.clientId,
|
required this.clientId,
|
||||||
required this.messgae,
|
this.messgae,
|
||||||
|
this.buffMessage,
|
||||||
this.topic,
|
this.topic,
|
||||||
this.qos = 0,
|
this.qos = 0,
|
||||||
this.username,
|
this.username,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
abstract class WebServer {
|
abstract class WebServer {
|
||||||
static late WebServer _webServer;
|
static late WebServer _webServer;
|
||||||
@@ -11,7 +10,7 @@ abstract class WebServer {
|
|||||||
_webServer = server;
|
_webServer = server;
|
||||||
}
|
}
|
||||||
|
|
||||||
void start(int port);
|
void start(int port, {Function? interceptor});
|
||||||
void stop();
|
void stop();
|
||||||
void addHandler(handler);
|
void addHandler(handler);
|
||||||
}
|
}
|
||||||
@@ -24,6 +23,14 @@ enum HttpMethod {
|
|||||||
ALL,
|
ALL,
|
||||||
WS,
|
WS,
|
||||||
;
|
;
|
||||||
|
|
||||||
|
static HttpMethod valueOf(String type) {
|
||||||
|
var tmp = HttpMethod.values.where((t) => t.name == type).toList();
|
||||||
|
if (tmp.isEmpty) {
|
||||||
|
return HttpMethod.ALL;
|
||||||
|
}
|
||||||
|
return tmp[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum HttpResponseType {
|
enum HttpResponseType {
|
||||||
@@ -37,6 +44,14 @@ enum HttpResponseType {
|
|||||||
final String type;
|
final String type;
|
||||||
|
|
||||||
const HttpResponseType(this.type);
|
const HttpResponseType(this.type);
|
||||||
|
|
||||||
|
static HttpResponseType valueOf(String type) {
|
||||||
|
var tmp = HttpResponseType.values.where((t) => t.type == type).toList();
|
||||||
|
if (tmp.isEmpty) {
|
||||||
|
return HttpResponseType.JSON;
|
||||||
|
}
|
||||||
|
return tmp[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RequestMapping {
|
class RequestMapping {
|
||||||
|
|||||||
85
lib/base/webserver/impl/RouteGenerator.dart
Normal file
85
lib/base/webserver/impl/RouteGenerator.dart
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import 'package:EasyDartModule/base/webserver/WebServer.dart';
|
||||||
|
import 'package:build/build.dart';
|
||||||
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
|
import 'package:source_gen/source_gen.dart';
|
||||||
|
import 'package:path/path.dart';
|
||||||
|
|
||||||
|
Builder routeGenerator(BuilderOptions options) {
|
||||||
|
return LibraryBuilder(
|
||||||
|
RouteGenerator(),
|
||||||
|
generatedExtension: '.route.dart',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class RouteGenerator extends GeneratorForAnnotation<RequestMapping> {
|
||||||
|
call(String name) {}
|
||||||
|
@override
|
||||||
|
generateForAnnotatedElement(
|
||||||
|
Element element, ConstantReader annotation, BuildStep buildStep) {
|
||||||
|
// 读取注解字段
|
||||||
|
String path = annotation.read('path').stringValue;
|
||||||
|
String method = annotation.read('method').read("_name").stringValue;
|
||||||
|
// String response = annotation.read("responseType").read("_name").stringValue;
|
||||||
|
// print("url:$path $method");
|
||||||
|
//0:路径 1:响应类型 2:调用函数 3:参数数量
|
||||||
|
Map<HttpMethod, List> routes = {};
|
||||||
|
if (method != HttpMethod.WS.name) {
|
||||||
|
if (path.endsWith("/")) {
|
||||||
|
path = path.substring(0, path.length - 1);
|
||||||
|
}
|
||||||
|
for (final method in element.children) {
|
||||||
|
for (final metaData in method.metadata) {
|
||||||
|
var anno = ConstantReader(metaData.computeConstantValue());
|
||||||
|
if (!anno.instanceOf(typeChecker)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pl = (method as MethodElement).parameters.length;
|
||||||
|
// print(
|
||||||
|
// "url:$path-${anno.read("path").stringValue} method:${anno.read("method").read("_name").stringValue} response:${anno.read("responseType").read("_name").stringValue}");
|
||||||
|
//转换为枚举类型
|
||||||
|
|
||||||
|
var p = anno.read("path").stringValue;
|
||||||
|
if (!p.startsWith("/")) {
|
||||||
|
p = "$path/$p";
|
||||||
|
} else {
|
||||||
|
p = path + p;
|
||||||
|
}
|
||||||
|
//加入调用缓存
|
||||||
|
routes[HttpMethod.valueOf(
|
||||||
|
anno.read("method").read("_name").stringValue)] = [
|
||||||
|
p,
|
||||||
|
HttpResponseType.valueOf(
|
||||||
|
anno.read("responseType").read("_name").stringValue),
|
||||||
|
() {
|
||||||
|
return method.name;
|
||||||
|
},
|
||||||
|
pl >= 2 ? 2 : 1
|
||||||
|
];
|
||||||
|
}
|
||||||
|
// print("构建完毕");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//单独处理ws
|
||||||
|
routes[HttpMethod.valueOf(method)] = [path];
|
||||||
|
}
|
||||||
|
// 生成路由映射代码
|
||||||
|
// var data = jsonEncode(routes);
|
||||||
|
final routesMapString = routes.entries.map((entry) {
|
||||||
|
return '${entry.key}: [[${entry.value.map((e) {
|
||||||
|
if (e is String) {
|
||||||
|
return '"$e"';
|
||||||
|
} else if (e is Function) {
|
||||||
|
return "_callHandler.${e()}";
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}).join(",")}]],';
|
||||||
|
}).join('\n');
|
||||||
|
// print(routes);
|
||||||
|
return '''
|
||||||
|
part of '${basename(buildStep.inputId.path)}';
|
||||||
|
late var _callHandler;
|
||||||
|
final Map<HttpMethod, List<List>> routes = {$routesMapString};
|
||||||
|
''';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:mirrors';
|
|
||||||
|
|
||||||
import 'package:EasyDartModule/EasyDartModule.dart';
|
import 'package:EasyDartModule/EasyDartModule.dart';
|
||||||
import 'package:EasyDartModule/base/logger/Logger.dart';
|
import 'package:EasyDartModule/base/logger/Logger.dart';
|
||||||
@@ -50,7 +49,7 @@ class ShelfWebServer implements WebServer {
|
|||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
if (e is HijackException) {
|
if (e is HijackException) {
|
||||||
//不能处理该异常直接抛出
|
//不能处理该异常直接抛出
|
||||||
throw e;
|
rethrow;
|
||||||
}
|
}
|
||||||
stopwatch.stop();
|
stopwatch.stop();
|
||||||
logger.error("| 服务器错误 | ${e.toString()} ${s.toString()}",
|
logger.error("| 服务器错误 | ${e.toString()} ${s.toString()}",
|
||||||
@@ -135,12 +134,24 @@ class ShelfWebServer implements WebServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void start(int port) async {
|
void start(int port, {Function? interceptor}) async {
|
||||||
//反射获取全部路由地址
|
//反射获取全部路由地址
|
||||||
final handler = Pipeline()
|
var pipeline = Pipeline()
|
||||||
.addMiddleware(requestIdMiddleware())
|
.addMiddleware(requestIdMiddleware())
|
||||||
.addMiddleware(logRequests())
|
.addMiddleware(logRequests());
|
||||||
.addHandler(_routerHandler);
|
//判断拦截器类型
|
||||||
|
if (interceptor != null) {
|
||||||
|
pipeline = pipeline.addMiddleware((Handler innerHandler) {
|
||||||
|
return (Request request) async {
|
||||||
|
var response = interceptor(request);
|
||||||
|
if (response == null) {
|
||||||
|
return innerHandler(request);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
final handler = pipeline.addHandler(_routerHandler);
|
||||||
_server = await serve(handler, InternetAddress.anyIPv4, port);
|
_server = await serve(handler, InternetAddress.anyIPv4, port);
|
||||||
print('Server listening on port ${_server?.port}');
|
print('Server listening on port ${_server?.port}');
|
||||||
}
|
}
|
||||||
@@ -152,88 +163,63 @@ class ShelfWebServer implements WebServer {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void addHandler(handler) {
|
void addHandler(handler) {
|
||||||
ClassMirror cm = reflectClass(handler.runtimeType);
|
try {
|
||||||
var im = reflect(handler);
|
handler.callHandler = handler;
|
||||||
String path = "";
|
} catch (e) {
|
||||||
for (var metadata in cm.metadata) {
|
print(
|
||||||
// 检查元数据是否为RequestMapping类型
|
"请在 ${handler.runtimeType} 中实现set方法 set callHandler(handler) => _callHandler = handler;");
|
||||||
if (metadata.reflectee is RequestMapping) {
|
return;
|
||||||
// 获取实例
|
}
|
||||||
RequestMapping annotation = metadata.reflectee;
|
try {
|
||||||
path = annotation.path;
|
handler.routeMap.forEach((k, v) {
|
||||||
if (path.endsWith("/")) {
|
for (var p in v) {
|
||||||
path = path.substring(0, path.length - 1);
|
if (k == HttpMethod.WS) {
|
||||||
|
addRouter(k, p[0], handler);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
addRouter(k, p[0], (req, [a, b, c, d, e, f]) async {
|
||||||
|
//从request中获取token并解码传入
|
||||||
|
String? token = req.headers["token"];
|
||||||
|
dynamic payload;
|
||||||
|
if (token != null) {
|
||||||
|
try {
|
||||||
|
payload = JWT.decode(token).payload;
|
||||||
|
} catch (e) {
|
||||||
|
//jwt解码失败
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var response;
|
||||||
|
if (p[3] == 2) {
|
||||||
|
response = await p[2](req, payload ?? <String, dynamic>{});
|
||||||
|
} else {
|
||||||
|
response = await p[2](req);
|
||||||
|
}
|
||||||
|
Map<String, String> headers = {...response.headers};
|
||||||
|
headers['Access-Control-Allow-Origin'] = '*';
|
||||||
|
headers['Access-Control-Allow-Headers'] =
|
||||||
|
'Content-Type,X-Span-ID,X-Trace-ID,token';
|
||||||
|
headers["Access-Control-Expose-Headers"] =
|
||||||
|
"Content-Type,X-Span-ID,X-Trace-ID,token";
|
||||||
|
headers['Access-Control-Allow-Methods'] =
|
||||||
|
'GET, POST, PUT, DELETE, OPTIONS';
|
||||||
|
headers["content-type"] = p[1].type;
|
||||||
|
|
||||||
|
response = response.change(headers: headers);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (annotation.method == HttpMethod.WS) {
|
});
|
||||||
//wwebsocket处理句柄直接加入路由
|
} catch (e) {
|
||||||
addRouter(annotation.method, path, handler);
|
if (e is NoSuchMethodError) {
|
||||||
return;
|
print(
|
||||||
}
|
"请在 ${handler.runtimeType} 中实现get方法 Map<HttpMethod, List<List>> get routeMap => routes;");
|
||||||
break;
|
return;
|
||||||
|
} else {
|
||||||
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
im.type.declarations.forEach((k, v) {
|
|
||||||
if (v is MethodMirror) {
|
|
||||||
for (var m in v.metadata) {
|
|
||||||
if (m.reflectee is RequestMapping) {
|
|
||||||
var mp = m.reflectee.path as String;
|
|
||||||
|
|
||||||
if (mp.startsWith("/")) {
|
|
||||||
mp = mp.substring(1, mp.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
String p = "$path/$mp";
|
|
||||||
// print("method: ${m.reflectee.method} $p");
|
|
||||||
//把地址加入路由
|
|
||||||
|
|
||||||
addRouter(m.reflectee.method, p, (req, [a, b, c, d, e, f]) async {
|
|
||||||
//从request中获取token并解码传入
|
|
||||||
String? token = req.headers["token"];
|
|
||||||
dynamic payload;
|
|
||||||
if (token != null) {
|
|
||||||
try {
|
|
||||||
payload = JWT.decode(token).payload;
|
|
||||||
} catch (e) {
|
|
||||||
//jwt解码失败
|
|
||||||
print(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List args;
|
|
||||||
if (v.parameters.length == 2) {
|
|
||||||
args = [req, payload ?? <String, dynamic>{}];
|
|
||||||
} else {
|
|
||||||
args = [req];
|
|
||||||
}
|
|
||||||
Response response =
|
|
||||||
await im.invoke(v.simpleName, args).reflectee as Response;
|
|
||||||
//判断contenttype是否定义
|
|
||||||
// var t = response.headers["content-type"];
|
|
||||||
// print(t);
|
|
||||||
Map<String, String> headers = {...response.headers};
|
|
||||||
// if (t == null) {
|
|
||||||
//设置默认contenttype
|
|
||||||
// response = response.change(headers: {
|
|
||||||
// ...response.headers,
|
|
||||||
// "content-type": m.reflectee.responseType.type
|
|
||||||
// });
|
|
||||||
// } else {
|
|
||||||
headers['Access-Control-Allow-Origin'] = '*';
|
|
||||||
headers['Access-Control-Allow-Headers'] =
|
|
||||||
'Content-Type,X-Span-ID,X-Trace-ID';
|
|
||||||
headers['Access-Control-Allow-Methods'] =
|
|
||||||
'GET, POST, PUT, DELETE, OPTIONS';
|
|
||||||
headers["content-type"] = m.reflectee.responseType.type;
|
|
||||||
|
|
||||||
// }
|
|
||||||
response = response.change(headers: headers);
|
|
||||||
|
|
||||||
return response;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addRouter(HttpMethod method, String path, dynamic handler) {
|
void addRouter(HttpMethod method, String path, dynamic handler) {
|
||||||
@@ -255,7 +241,7 @@ class ShelfWebServer implements WebServer {
|
|||||||
_router.options(path, (r) {
|
_router.options(path, (r) {
|
||||||
return Response.ok('', headers: {
|
return Response.ok('', headers: {
|
||||||
'Access-Control-Allow-Origin': '*',
|
'Access-Control-Allow-Origin': '*',
|
||||||
'Access-Control-Allow-Headers': 'Content-Type,X-Span-ID,X-Trace-ID',
|
'Access-Control-Allow-Headers': 'Content-Type,X-Span-ID,X-Trace-ID,token',
|
||||||
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ class ShelfWebServer implements WebServer {
|
|||||||
final String tag = "webserver";
|
final String tag = "webserver";
|
||||||
ShelfWebServer(this.logger);
|
ShelfWebServer(this.logger);
|
||||||
@override
|
@override
|
||||||
void start(int port) async {}
|
void start(int port, {Function? interceptor}) async {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void stop() {}
|
void stop() {}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ dependencies:
|
|||||||
redis: ^4.0.0
|
redis: ^4.0.0
|
||||||
dart_jsonwebtoken: ^2.14.2
|
dart_jsonwebtoken: ^2.14.2
|
||||||
web_socket_channel: ^3.0.1
|
web_socket_channel: ^3.0.1
|
||||||
|
source_gen: ^1.5.0
|
||||||
|
build: ^2.4.1
|
||||||
|
analyzer: ^6.8.0
|
||||||
|
event_bus: ^2.0.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
lints: ^4.0.0
|
lints: ^4.0.0
|
||||||
|
|||||||
Reference in New Issue
Block a user