尝试学习 Groovy,到目前为止,这是一次有趣的冒险,只是有点令人困惑。我目前正在尝试做的是启动一个服务器,wget
向它发出请求,当收到该请求时,执行某个操作 - 在这种情况下,只需创建一个新文件:
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()
使用上面的代码,当我执行 a 时wget http://localhost:5000
,它“有效”,因为文件是按照我想要的方式创建的,但wget
输出不满意:
--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
因此,我们可以推断出没有返回正确的响应,即使我有return HttpResponse
aftersockerServer.accept ...
逻辑。我对如何解决这个问题的想法(主要是因为我来自 Python 背景)是以某种方式模仿yield
Python 中的响应(基本上,在不破坏holdupServer()
逻辑的情况下返回响应,从而中断服务器连接)。有没有办法在 Groovy 中实现这一点,或者有没有一种不同的方法可以用来基本上返回有效HttpResponse
而不退出holdupServer()
块?
您可以使用函数 callback,它在 Groovy 中转换为闭包回调。基本上,您将要返回的值传递给另一个延迟当前方法上的堆栈的函数/方法。这种方法基本上适用于所有语言。例如,在 java(不支持 lambda 的版本)中,您必须传递一个对象,稍后您将在其中调用方法。
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
您必须提供一些标题。至少Content-Type
并且Content-Length
应该与正确格式化的数据和 HTTP 状态(在这种情况下为 HTTP/1.1 200)一起提供。此外,您应该将ServerSocket.accept
调用包装在一个 while 循环中。
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 <--
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句