2013-02-27 14 views
6

(मैं डार्ट के नए lib वी 2 संस्करण का उपयोग कर रहा हूँ: कब।)मैं डार्ट में एचटीपी सर्वर के लिए एकाधिक हैंडलर कैसे पंजीकृत करूं?

मैं एक HttpServer के लिए कई संचालकों दर्ज करना चाहते हैं, विशेष रूप से एक WebSocketTransformer और अन्य मनमाना संचालकों। कुछ इस तरह:

// pseudo-code 

var server = HttpServer; 
server.register('/foo', someHandlerFunction);  // 1 
server.register('/bar', someOtherHandlerFunction); // 2 
server.register('/ws', webSocketHandler);   // 3 

यदि # 1 मैचों, तो # 2 का परीक्षण नहीं किया जाता है, और इसी तरह। तो, यह लालची है।

मैंने केवल एक हैंडलर के साथ नमूने देखे हैं। मैं कई हैंडलर कैसे पंजीकृत करूं? अग्रिम में धन्यवाद!

उत्तर

3

न्यू जवाब था

HttpServer.bind('127.0.0.1', 8889) 
    .then((HttpServer server) { 
     var sc = new StreamController(); 
     sc.stream.transform(new WebSocketTransformer()).listen(handleWebSocket); 

     server.listen((HttpRequest request) { 
     print("new connection from ${request.uri.scheme} ${request.uri}"); 

     // See https://code.google.com/p/dart/issues/detail?id=8825 
     //if (request.uri.scheme == 'ws') { 
     if (request.uri.path == '/ws') { 
      sc.add(request); 
     } else if (request.uri.path == '/foo') { 
      request.response.addString('foo'); 
      request.response.close(); 
     } else { 
      print("got 404 for ${request.uri}"); 
      request.response.statusCode = 404; 
      request.response.close(); 
     } 
     }); 
    }); 

नोटिस:

+0

है कि मैं के लिए, धन्यवाद क्या देख रहा था! –

0

यहाँ कैसे API docs एक WebSocket हैंडलर रजिस्टर करने के लिए सलाह देते हैं है:

server 
    .where((request) => request.uri.path == "/ws") 
    .transform(new WebSocketTransformer()).listen((webSocket) => ...); 

हालांकि, सर्वर एक एकल सदस्यता धारा है। एक बार listen संलग्न हो जाने पर, आप अन्य श्रोताओं को संलग्न नहीं कर सकते हैं।

जो कुछ मैं वास्तव में चाहता हूं वह किसी ईवेंट को देखने के लिए है, यह तय करें कि यह इसे संभाल सकता है, और यदि ऐसा है तो इसे किसी अन्य स्ट्रीम पर रूट करें। अन्यथा, इसे साथ पास करें। इस तरह, घटना (इस मामले में एक HttpRequest ऑब्जेक्ट) एक श्रृंखला के साथ पारित होने तक पारित किया जाता है।

मैंने TakeAndRoute कक्षा बनाई जो StreamEventTransformer फैली हुई है। TakeAndRoute यह निर्धारित करने के लिए एक फ़ंक्शन का उपयोग करता है कि क्या इसे ईवेंट को पकड़ना चाहिए और उसे किसी अन्य स्ट्रीम पर रूट करना चाहिए, या बस इसे आगे बढ़ाएं।

import 'dart:io'; 
import 'dart:async'; 

handleWebSocket(WebSocket webSocket) { 
    webSocket.listen((event) { 
    if (event is MessageEvent) { 
     /* Handle message. */ 
    } else if (event is CloseEvent) { 
     /* Handle closed. */ 
    } 
    }); 
} 

typedef bool ShouldTake(e); 
typedef void RouteTo(Stream stream); 
typedef void HandleEvent(e); 

class TakeAndRoute<S, T> extends StreamEventTransformer<S, T> { 
    ShouldTake shouldTake; 
    RouteTo routeTo; 
    StreamController controller = new StreamController(); 
    HandleEvent handler; 

    TakeAndRoute(this.shouldTake, {this.routeTo, this.handler}) { 
    if (routeTo != null) routeTo(controller.stream); 
    } 

    handleData(event, StreamSink sink) { 
    print("handling"); 
    if (shouldTake(event)) { 
     if (routeTo != null) { 
     controller.add(event); 
     } 
     if (handler != null) { 
     handler(event); 
     } 
    } else { 
     sink.add(event); 
    } 
    } 
} 

main() { 
    HttpServer.bind('127.0.0.1', 8888) 
    .then((HttpServer server) { 
     server 
     .transform(new TakeAndRoute<HttpRequest, HttpRequest>(
      (req) => req.uri.path == '/ws', 
      routeTo: (stream) => stream.transform(new WebSocketTransformer()).listen(handleWebSocket))) 
     .transform(new TakeAndRoute<HttpRequest, HttpRequest>(
      (req) => req.uri.path == '/foo', 
      handler: (req) { 
      print('got foo'); 
      req.response.addString("foo"); 
      req.response.close(); 
      })) 
     .listen((req) { 
      print("got 404 for ${req.uri}"); 
      req.response.statusCode = 404; 
      req.response.close(); 
     }); 
    }); 
} 

वैसे, यह overkill हो सकता है:

यहाँ मैं के साथ आया है। मार्ग पैकेज का उपयोग करें: कैसे मैं एक StreamController बनाने के लिए तो मैं WebSocketTransformer करने के लिए घटनाओं पंप सकता

0

यहाँ यह करने के लिए एक और अधिक मैनुअल, लेकिन छोटे तरीका है :

HttpServer.bind('127.0.0.1', 8889).then((server) { 
    var router = new Router(server) 
    ..serve('/ws').transform(new WebSocketTransformer()).listen(handleWebSocket) 
    ..serve('/foo').listen((req) { 
     req.response..addString('foo')..close(); 
    }); 
}); 
: http://pub.dartlang.org/packages/route

यहाँ अपने उदाहरण मार्ग के serve() विधि का उपयोग कर रहा है

राउटर स्वचालित रूप से अनचाहे अनुरोधों को पकड़ता है और 404 भेजता है, हालांकि जल्द ही आप defaultStream के साथ इसे ओवरराइड करने में सक्षम होंगे।

रूटर भी फिल्टर का समर्थन करता है, उपयोगी प्रवेश के लिए, प्रमाणन, संपीड़न, आदि .:

HttpServer.bind('127.0.0.1', 8889).then((server) { 
    var router = new Router(server) 
    ..filter(new RegExp(r'/.*'), (req) { 
     //log all requests 
     _logger.info("request: $req"); 
     return new Future.immediate(true); // keep processing request 
    }) 
    ..filter(new Regexp(r'/secure/.*'), (req) { 
     // check authentication asynchronously 
     return getUserFromRequest(req).then((user) { 
     if (user == null) { 
      sendRedirect('/login'); // sendRedirect coming soon 
      return false; // stop processing request 
     } else { 
      return true; // keep processing 
     } 
     }); 
    }) 
    ..serve(/* ... */); 
}); 
संबंधित मुद्दे