Code Monkey home page Code Monkey logo

Comments (21)

nodeful avatar nodeful commented on May 4, 2024 4

First of all, hats off to the creator of this library. This is the only Swift "client-side server" (I want to run a small API server on my user's machine) I was able to find.
But it desperately needs some async support, especially as a majority of workflows when writing servers are async and most users using a library will have limited knowledge of how to extend it to fit their needs :)

from swifter.

Laban1 avatar Laban1 commented on May 4, 2024 3

Any ETA on this?

from swifter.

fdstevex avatar fdstevex commented on May 4, 2024 2

I ran into this as well, looking to implement a simple proxy server. I want to have Swifter listen and handle the connection, and then my handler will make a connection to somewhere else (different protocol) and stream the data back to the Swifter connection.

I've done this now by creating my own HttpHandlers extension. The reading I'm doing from the other side is asynchronous, so I have to run it asynchronously.

I've implemented this by handing off the socket to the stream handler, similar to what the WebSocket handler does, but then HttpServerIO.handleConnection closes the socket as soon as the handler is set up. I hacked it so that if the socket is passed off to the handler it is not closed in handleConnection. That works for me, but it'd be nice to have support for this baked in.

from swifter.

julien-c avatar julien-c commented on May 4, 2024 1

I think it is pretty reasonable for an HTTP server today to be asynchronous-first, given that every non-trivial server is going to hit some kind of persistence engine or make network calls itself.

What would you guys think about something like:

server["/hello"] = { request, response in
    DB.ExampleAsyncCall.find {
        response.status = .OK
        response.body = .HTML("You asked for " + request.url)
        response.send()
    }
}

or

server["/hello"] = { request, response in
    DB.ExampleAsyncCall.find {
        response.status = .OK
        response.send(.HTML("You asked for " + request.url))
    }
}

from swifter.

VFUC avatar VFUC commented on May 4, 2024

How about just writing your own handler, which then deals with the HttpResponse any way you like?

from swifter.

vittoriom avatar vittoriom commented on May 4, 2024

Because if I understand correctly how it works, even if I write my own handler I have to return a response in the closure and I don't have one yet.
Can you elaborate some more on how I could do that?

from swifter.

VFUC avatar VFUC commented on May 4, 2024

Well if you're saying you don't have the necessary information to return a response yet, could you not perform the steps to obtain that information in the handler?
I'm thinking about something like the following, in this scenario the missing information would be a String:

func customHandler( informationGetter: () -> String ) -> ( HttpRequest -> HttpResponse) {
 return { request in    
   let externalInformation = informationGetter()
   return HttpResponse.OK(HttpResponseBody.Text("Response: \(externalInformation)"))
  }
}

from swifter.

vittoriom avatar vittoriom commented on May 4, 2024

Maybe I didn't make myself clear enough, but that's what I meant with "asynchronous". When I get a request, I have to perform some stuff before I know what I will have to return.

In the scenario you wrote, there is no asynchronous stuff going on, it should be more like:

func customHandler( informationGetter: () -> String ) -> ( HttpRequest -> HttpResponse) {
 return { request in    
   let externalInformation = informationGetter().onCompletion { informationNeeded in
      //what now? The following line wouldn't work of course
      //return HttpResponse.OK(HttpResponseBody.Text("Response: \(externalInformation)"))
   }
   return //return what?
  }
}

while I expect a server library to support something more similar to:

func customHandler( informationGetter: () -> String ) -> ( HttpRequest -> HttpResponse) {
 return { (request, completion) in    
   let externalInformation = informationGetter().onCompletion { informationNeeded in
      //perform some stuff
      completion(myResponse)
   }
  }
}

from swifter.

VFUC avatar VFUC commented on May 4, 2024

Oh, I see what you mean. You're right, my proposal is still synchronous.

from swifter.

damian-kolakowski avatar damian-kolakowski commented on May 4, 2024

@vittoriom hi man

For now you could use dispatch_semaphore to wait for the end of informationGetter().onCompletion :
https://developer.apple.com/library/mac/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html#//apple_ref/doc/uid/TP40008091-CH102-SW24

Swifter should expose some kind of promises chaining.

best
dk

from swifter.

vittoriom avatar vittoriom commented on May 4, 2024

Hi @glock45
I appreciate your reply, but writing semaphore-based request handlers is not an option at the moment.
Thanks anyway!

from swifter.

C0deH4cker avatar C0deH4cker commented on May 4, 2024

This sounds like the perfect use case for promises, since you don't yet have the response body but return a promise that you will create it later

from swifter.

Francescu avatar Francescu commented on May 4, 2024

I agree with @julien-c

from swifter.

damian-kolakowski avatar damian-kolakowski commented on May 4, 2024

👍 ...also.. with @julien-c proposition we will solve #1

from swifter.

vittoriom avatar vittoriom commented on May 4, 2024

Not sure what DB.ExampleAsyncCall.find is supposed to be, but I would use an established pattern like Promises and Futures, so the handler closure only takes the request and returns a response future.

from swifter.

julien-c avatar julien-c commented on May 4, 2024

My DB.ExampleAsyncCall.find() is your informationGetter().onCompletion() 😁

It's way simpler to do completion callbacks, à la Express.js – but nothing prevents you from dropping a Promise implementation there if you need (I know of FutureKit, PromiseKit, BrightFutures). He who can do more, can do less.

from swifter.

yipsang avatar yipsang commented on May 4, 2024

@julien-c Is your suggestion implemented in Swifter so far? I am doing similar proxy server as @fdstevex 's in my project. If asynchronous handler is not modified yet, I may switch to @fdstevex 's approach. Anyway, thanks for you guys' contribution for making this easy to use httpserver for swift

from swifter.

chaitanyabaranwal avatar chaitanyabaranwal commented on May 4, 2024

Any update on async support? I think this library is more lightweight than GCDWebServer but would be really great if we could get async support baked in.

from swifter.

nodeful avatar nodeful commented on May 4, 2024

I ended up switching to https://github.com/thecatalinstan/Criollo

from swifter.

chaitanyabaranwal avatar chaitanyabaranwal commented on May 4, 2024

I ended up switching to https://github.com/thecatalinstan/Criollo

Hey! Thanks for this, I will check this out :D

from swifter.

isaced avatar isaced commented on May 4, 2024

I finally wrote an asynchronous, lightweight HTTP Server based on Socket in pure Swift, which can run well on iOS/macOS/tvOS: https://github.com/isaced/Aoxiang

from swifter.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.