Trying to learn Groovy, and it's been a fun and only slightly confusing adventure so far. What I'm currently trying to do is stand up a server, make a wget
request to it and when that request is received, have a certain action be executed - in this case, just creating a new file:
import java.net.http.HttpResponse
class ServerLogic {
static def holdupServer() {
println('Standing up server..\n')
def socketServer = new ServerSocket(5000)
// server is up
socketServer.accept { socket ->
// the lines below only execute when a connection is made to the server
socket.withStreams { input, output ->
println("[${new Date()}] HELLO\n")
def newFile = new File("/home/nick/IdeaProjects/groovy_learning/resources/new.txt")
newFile.createNewFile()
newFile.text = 'Hello!!!'
println("NEW FILE SHOULD HAVE BEEN CREATED.")
println ">> READ: ${input.newReader().readLine()}"
}
}
return HttpResponse
}
}
ServerLogic.holdupServer()
With the above code, when I execute a wget http://localhost:5000
, it "works" in the sense that the file is created like I want it to be, but the wget
output is unhappy:
--2021-07-17 15:42:32-- http://localhost:5000/
Resolving localhost (localhost)... 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:5000... connected.
HTTP request sent, awaiting response... No data received.
Retrying.
--2021-07-17 15:42:33-- (try: 2) http://localhost:5000/
Connecting to localhost (localhost)|127.0.0.1|:5000... failed: Connection refused.
Resolving localhost (localhost)... 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:5000... failed: Connection refused.
// these occur because the server has shut down after the last println call, when the `return HttpResponse` triggers
So from that, we can reason out that there isn't a proper response being returned, even though I have the return HttpResponse
after the sockerServer.accept ...
logic. My thought on how to solve the problem (primarily because I come from a Python background) would be to somehow mimic yield
ing a response in Python (basically, return a response without breaking out of the holdupServer()
logic and thus breaking the server connection). Is there a way to achieve this in Groovy, or is there a different approach I could use to essentially return a valid HttpResponse
without exiting the holdupServer()
block?
You can use a function callback , which in Groovy translates to a closure callback. Basically, you pass the value you want to return to another function/method defering the stack on the current method. This approach works essentially on all languages. In java (the versions which don't support lambda), for instance, you would have to pass an object in which you would call a method later.
import java.net.http.HttpResponse
class ServerLogic {
static def holdupServer(Closure closure) {
(0..2).each {
closure.call(HttpResponse)
}
}
}
ServerLogic.holdupServer { httpResponse ->
println httpResponse
}
interface java.net.http.HttpResponse
interface java.net.http.HttpResponse
interface java.net.http.HttpResponse
You have to provide some headers. At least Content-Type
and Content-Length
should've been provided along with the data and HTTP status (HTTP/1.1 200, in this case) properly formatted. Also, you should've wrapped the ServerSocket.accept
calls in a while loop.
See the MDN Overview on HTTP .
class ServerLogic {
static HEADERS = [
"HTTP/1.1 200",
"Content-Type: text/html; charset=utf-8",
"Connection: Keep-Alive",
"Keep-Alive: timeout=5, max=1000",
"Content-Length: %d\r\n",
"%s"
].join("\r\n")
static def holdupServer(Closure callback) {
println('Standing up server..\n')
def socketServer = new ServerSocket(5000)
// server is up
while(true) { // Continue to accept connections
socketServer.accept { socket ->
// the lines below only execute when a connection is made to the server
callback.call(socket) // call function
}
}
}
}
ServerLogic.holdupServer { Socket socket ->
String data = "RESPONSE <--\n"
def response = String.format(ServerLogic.HEADERS, data.size(), data)
println response
socket << response
}
RESPONSE <--
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.