classAppChannelextendsApplicationChannel{@overrideFutureprepare()async{// All controllers will use this policy by defaultCORSPolicy.defaultPolicy.allowedOrigins=["https://mywebsite.com"];}@overrideControllergetentryPoint{finalrouter=Router();router.route("/things").linkFunction((request)async{returnResponse.ok(["Widget","Doodad","Transformer"]);});returnrouter;}}
Streaming Responses (Server Side Events with text/event-stream)
classAppChannelextendsApplicationChannel{finalStreamController<String>controller=newStreamController<String>();@overrideFutureprepare()async{varcount=0;Timer.periodic(newDuration(seconds:1),(_){count++;controller.add("This server has been up for $count seconds\n");});}@overrideControllergetentryPoint{finalrouter=newRouter();router.route("/stream").linkFunction((req)async{returnResponse.ok(controller.stream)..bufferOutput=false..contentType=newContentType("text","event-stream",charset:"utf-8");});returnrouter;}}
A websocket server
classAppChannelextendsApplicationChannel{List<WebSocket>websockets=[];@overrideFutureprepare()async{// When another isolate gets a websocket message, echo it to// websockets connected on this isolate.messageHub.listen(sendBytesToConnectedClients);}@overrideControllergetentryPoint{finalrouter=Router();// Allow websocket clients to connect to ws://host/connectrouter.route("/connect").linkFunction((request)async{varwebsocket=awaitWebSocketTransformer.upgrade(request.raw);websocket.listen(echo,onDone:(){websockets.remove(websocket);},cancelOnError:true);websockets.add(websocket);// Take request out of channelreturnnull;});returnrouter;}voidsendBytesToConnectedClients(List<int>bytes){websockets.forEach((ws){ws.add(bytes);});}voidecho(List<int>bytes){sendBytesToConnectedClients(bytes);// Send to other isolatesmessageHub.add(bytes);}}
Setting Content-Type and Encoding a Response Body
classAppChannelextendsApplicationChannel{finalContentTypeCSV=ContentType("text","csv",charset:"utf-8");@overrideFutureprepare()async{// CsvCodec extends dart:convert.CodecCodecRegistry.defaultInstance.add(CSV,newCsvCodec());}@overrideControllergetentryPoint{finalrouter=Router();router.route("/csv").linkFunction((req)async{// These values will get converted by CsvCodec into a comma-separated stringreturnResponse.ok([[1,2,3],["a","b","c"]])..contentType=CSV;});returnrouter;}}
Proxy a File From Another Server
classAppChannelextendsApplicationChannel{@overrideControllergetentryPoint{finalrouter=Router();router.route("/proxy/*").linkFunction((req)async{varfileURL="https://otherserver/${req.path.remainingPath}";varfileRequest=awaitclient.getUrl(url);varfileResponse=awaitreq.close();if(fileResponse.statusCode!=200){returnnewResponse.notFound();}// A dart:io.HttpResponse is a Stream<List<int>> of its body bytes.returnnewResponse.ok(fileResponse)..contentType=fileResponse.headers.contentType// let the data just pass through because it has already been encoded// according to content-type; applying encoding again would cause// an issue..encodeBody=false;});returnrouter;}}