使用 HTTP 协议提供内容的服务器,比如网页。
注意:HttpServer 提供底层的 HTTP 功能。我们建议用户评估 编写 HTTP 服务器 中讨论的高级 API,网址为 dart.dev。
HttpServer
是一个 Stream,它提供 HttpRequest 对象。每个 HttpRequest
都有一个关联的 HttpResponse 对象。服务器通过写入此 HttpResponse 对象响应请求。以下示例展示了如何将一个 HttpServer
绑定到端口 80(HTTP 服务器的标准端口)上的 IPv6 InternetAddress,以及如何侦听请求。端口 80 是默认的 HTTP 端口。但是,在大多数系统上,访问它需要超级用户权限。对于本地测试,考虑使用一个非保留端口(1024 及以上)。
import 'dart:io';
void main() async {
var server = await HttpServer.bind(InternetAddress.anyIPv6, 80);
await server.forEach((HttpRequest request) {
request.response.write('Hello, world!');
request.response.close();
});
}
忽略不完整的请求,即缺少全部或部分标头,并且不对其生成异常或 HttpRequest 对象。同样,写入 HttpResponse 时,将忽略任何 Socket 异常,并且之后的任何写入都将被忽略。
HttpRequest 公开了请求头,如果请求正文存在,则作为数据流提供该正文。如果正文未读,则在服务器写入HttpResponse或关闭它时,将对其进行管理。
使用安全的 HTTPS 连接进行绑定
使用 bindSecure 创建一个 HTTPS 服务器。
服务器向客户端提供证书。证书链和私钥设置在传递给 bindSecure 的 SecurityContext 对象中。
import 'dart:io';
void main() async {
var chain =
Platform.script.resolve('certificates/server_chain.pem').toFilePath();
var key = Platform.script.resolve('certificates/server_key.pem').toFilePath();
var context = SecurityContext()
..useCertificateChain(chain)
..usePrivateKey(key, password: 'dartdart');
var server =
await HttpServer.bindSecure(InternetAddress.anyIPv6, 443, context);
await server.forEach((HttpRequest request) {
request.response.write('Hello, world!');
request.response.close();
});
}
证书和密钥是 PEM 文件,可以使用 OpenSSL 中的工具创建和管理。
- 实现的类型
构造函数
- HttpServer.listenOn(ServerSocket serverSocket)
- 将 HTTP 服务器附加到现有的 ServerSocket。当关闭 HttpServer 时,HttpServer 将只是将其自身分离出来,关闭当前连接,但不会关闭
serverSocket
。工厂
属性
- address → InternetAddress
- 服务器监听的地址。没有 setter
- autoCompress ↔ bool
- 是否 HttpServer 应尽可能地压缩内容。获取/设置对
- defaultResponseHeaders → HttpHeaders
- 添加到所有响应对象中的默认头集合。没有 setter
-
first → Future<
HttpRequest> - 此流的第一个元素。无 setter继承
- hashCode → int
- 此对象的哈希代码。无 setter继承
- idleTimeout ↔ Duration?
- 获取或设置用于空闲的长连接的超时。如果在前一个请求完成后,idleTimeout 内未看到进一步的请求,则该连接将被中断。获取/设置对
- isBroadcast → bool
- 此流是否是广播流。无 setter继承
-
isEmpty → Future<
bool> - 此流是否包含任何元素。无 setter继承
-
last → Future<
HttpRequest> - 此流的最后一个元素。无 setter继承
-
length → Future<
int> - 此流中的元素数量。无 setter继承
- port → int
- 服务器监听的端口。没有 setter
- runtimeType → Type
- 对象运行时类型的表示形式。无 setter继承
- serverHeader ↔ String?
- 获取并设置此 HttpServer 生成的所有响应的
Server
标头的默认值。获取/设置对 - sessionTimeout ← int
- 设置此 HttpServer 会话的超时(以秒为单位)。无 getter
-
single → Future<
HttpRequest> - 此流的单个元素。无 setter继承
方法
-
any(
bool test(HttpRequest element)) → Future< bool> - 检查
test
是否接受此流提供的任何元素。继承的 -
asBroadcastStream(
{void onListen(StreamSubscription< HttpRequest> subscription)?, void onCancel(StreamSubscription<HttpRequest> subscription)?}) → Stream<HttpRequest> - 返回一个多订阅流,该流生成与此相同的事件。继承的
-
asyncExpand<
E> (Stream< E> ? convert(HttpRequest event)) → Stream<E> - 将每个元素转换为异步事件序列。继承的
-
asyncMap<
E> (FutureOr< E> convert(HttpRequest event)) → Stream<E> - 异步地将此数据流的每个数据事件映射到一个新事件,创建一个新的数据流。继承的
-
cast<
R> () → Stream< R> - 将此数据流自适应为
Stream<R>
。继承的 -
close(
{bool force = false}) → Future - 永久阻止此 HttpServer 侦听新连接。此操作会使用完成事件关闭 Stream(包括 HttpRequest)。当服务器停止时,返回的 Future 完成。对于使用 bind 或 bindSecure 启动的服务器,这意味着不再使用侦听过的端口。
-
connectionsInfo(
) → HttpConnectionsInfo - HttpConnectionsInfo 对象,总结服务器处理的当前连接数。
-
contains(
Object? needle) → Future< bool> - 返回此数据流提供的元素中是否出现
needle
。继承的 -
distinct(
[bool equals(HttpRequest previous, HttpRequest next)?]) → Stream< HttpRequest> - 如果数据事件等于之前的事件,则将跳过该事件。继承的
-
drain<
E> ([E? futureValue]) → Future< E> - 丢弃此数据流上的所有数据,但在完成时或发生错误时发送信号。继承的
-
elementAt(
int index) → Future< HttpRequest> - 返回此数据流的第
index
个数据事件的值。继承的 -
every(
bool test(HttpRequest element)) → Future< bool> - 检查
test
是否接受此数据流提供的所有元素。继承的 -
expand<
S> (Iterable< S> convert(HttpRequest element)) → Stream<S> - 将此数据流中的每个元素转换为一系列元素。继承的
-
firstWhere(
bool test(HttpRequest element), {HttpRequest orElse()?}) → Future< HttpRequest> - 查找与此数据流匹配的第一个元素
test
。继承的 -
fold<
S> (S initialValue, S combine(S previous, HttpRequest element)) → Future< S> - 使用 wiederholt 施加 `combine` 来组合一系列值。继承的
-
forEach(
void action(HttpRequest element)) → Future< void> - 对此流的每个元素执行 `action`。继承的
-
handleError(
Function onError, {bool test(dynamic error)?}) → Stream< HttpRequest> - 创建一个拦截此流中某些错误的包装流。继承的
-
join(
[String separator = ""]) → Future< String> - 将元素的字符串表示形式组合成一个字符串。继承的
-
lastWhere(
bool test(HttpRequest element), {HttpRequest orElse()?}) → Future< HttpRequest> - 在此流中查找与 `testing` 匹配的最后一个元素。继承的
-
listen(
void onData(HttpRequest event)?, {Function? onError, void onDone()?, bool? cancelOnError}) → StreamSubscription< HttpRequest> - 向此流添加订阅。继承的
-
map<
S> (S convert(HttpRequest event)) → Stream< S> - 将此流的每个元素转换为新的流事件。继承的
-
noSuchMethod(
Invocation invocation) → dynamic - 当访问不存在的方法或属性时调用。继承的
-
pipe(
StreamConsumer< HttpRequest> streamConsumer) → Future - 将此流的事件连接到
streamConsumer
。继承的 -
reduce(
HttpRequest combine(HttpRequest previous, HttpRequest element)) → Future< HttpRequest> - 使用 wiederholt 施加 `combine` 来组合一系列值。继承的
-
singleWhere(
bool test(HttpRequest element), {HttpRequest orElse()?}) → Future< HttpRequest> - 查找与此数据流匹配的单个元素
test
.继承的 -
skip(
int count) → Stream< HttpRequest> - 从该数据流中跳过前
count
个数据事件.继承的 -
skipWhile(
bool test(HttpRequest element)) → Stream< HttpRequest> - 当
test
匹配时,从该数据流跳过数据事件.继承的 -
take(
int count) → Stream< HttpRequest> - 提供此数据流的前
count
个数据事件.继承的 -
takeWhile(
bool test(HttpRequest element)) → Stream< HttpRequest> - 当
test
成功时转发数据事件.继承的 -
timeout(
Duration timeLimit, {void onTimeout(EventSink< HttpRequest> sink)?}) → Stream<HttpRequest> - 使用与该流事件相同的事件创建一个新流。继承的
-
toList(
) → Future< List< HttpRequest> > - 在
List
中收集该流的所有元素。继承的 -
toSet(
) → Future< Set< HttpRequest> > - 在
Set
中收集该流的数据。继承的 -
toString(
) → String - 该对象的字符串表示形式。继承的
-
transform<
S> (StreamTransformer< HttpRequest, S> streamTransformer) → Stream<S> - 将
streamTransformer
应用于该流。继承的 -
where(
bool test(HttpRequest event)) → Stream< HttpRequest> - 通过舍弃某些元素,从该流创建新流。继承的
运算符
静态方法
-
绑定(
dynamic address, int port, {int backlog = 0, bool v6Only = false, ) → Future< HttpServer> - 开始在指定的
address
和port
上监听 HTTP 请求。 -
安全绑定(
dynamic address, int port, SecurityContext context, {int backlog = 0, bool v6Only = false, bool requestClientCertificate = false, ) → Future< HttpServer> address
可以是 String 或 InternetAddress。如果address
是 String,bind 就会执行 InternetAddress.lookup,并使用列表中的第一个值。要在回路适配器上侦听(只允许来自本地主机的传入连接),请使用值 InternetAddress.loopbackIPv4 或 InternetAddress.loopbackIPv6。要允许来自网络的传入连接,请使用 InternetAddress.anyIPv4 或 InternetAddress.anyIPv6 之一绑定到所有接口,或使用特定接口的 IP 地址。