我希望有一个应用程序可以侦听TCP套接字连接,并且可以对它们作出反应。为此,我需要在启动时启动后台线程 - 我可以在BootStrap.groovy中执行此操作。
对于背景线程,我下载了executor plugin。
代码如下所示:
class BootStrap {
def myService
def init = { servletContext ->
log.info("Bootstrapping")
development {
log.info("Doing myService async ")
myService.doSomething()
}
}
class MyService {
def doSomething() {
runAsync {
println "Running!"
}
}
}
}
此代码是来自another thread的复制粘贴,位于SO。
我收到此错误:
| Error 2014-06-06 22:30:37,317 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: Cannot invoke method doSomething() on null object
Message: Cannot invoke method doSomething() on null object
Line | Method
->> 14 | doCall in BootStrap$_closure1_closure2
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
似乎未填充myService对象。我需要编辑一些配置吗?
编辑:尝试使用executorService,但这也无济于事。
| Error 2014-06-07 00:06:36,099 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: Cannot invoke method doSomething() on null object
Message: Cannot invoke method doSomething() on null object
Line | Method
->> 14 | doCall in BootStrap$_closure1_closure2
答案 0 :(得分:2)
我在这里创建了一个简短的SocketServer示例(称为'gsocket'): https://github.com/m-schneider/gsocket 如果您不是在'BootStrap.groovy'中定义服务类的先决条件,它应该符合您的需求 - 希望;) 套接字服务器客户端(client.groovy)也在主文件夹中进行快速测试。
希望有所帮助。
答案 1 :(得分:2)
您应该将服务类移动到Grails项目中的正确文件夹。
BootStrap.groovy中
class BootStrap {
def myService
def init = { servletContext ->
log.info("Bootstrapping")
development {
log.info("Doing myService async ")
myService.doSomething()
}
}
}
MyService.groovy
class MyService {
def doSomething() {
runAsync {
println "Running!"
}
}
}
答案 2 :(得分:2)
你应该按照@Fabrizio D' Ammassa的建议将你的doSomethoing()方法转移到一个单独的服务,如果你不想将你的代码移动到单独的服务,那么你可以实现这个目标,如下所示:
class BootStrap {
def init = { servletContext ->
log.info("Bootstrapping")
development {
log.info("Doing myService async ")
doSomething()
}
}
def doSomething() {
runAsync {
println "Running!"
}
}
}
答案 3 :(得分:2)
好吧,我想你应该看看这个插件:http://grails.org/plugin/routing
该插件基于apache camel http://camel.apache.org/。它有很多可以使用的选项和组件。我在HL7集成中使用了很多,我们在TCP套接字上发送和接收响应。最简单的TCP示例是:
import org.apache.camel.builder.RouteBuilder
class MyMessageRoute extends RouteBuilder {
from('mina2:tcp://localhost:9090').to('stream:out')
}
}
因此,无论是什么,localhost 9090都会打印到您的控制台。您的主机和端口将在应用程序启动后立即启动,即使您运行集成测试,端口也将正在侦听。要运行它,您需要安装路由插件,并在BuildConfig.groovy中具有以下依赖项
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
runtime "org.apache.mina:mina-core:2.0.7"
runtime "org.apache.mina:mina-integration-spring:1.1.7"
runtime "org.apache.camel:camel-mina2:2.13.0"
compile('org.apache.poi:poi-ooxml:3.8') {
}
}
您甚至可以在netty上使用mina2。有关它们与apache camel集成的更多信息,请查看以下文档。
Netty组件:http://camel.apache.org/netty.html
Mina2组件:http://camel.apache.org/mina2.html
所有骆驼组件:http://camel.apache.org/components.html
希望这会有所帮助!!
答案 4 :(得分:1)
不,填充myService对象。
class MyService {
def executorService
def doSomething() {
executorService.submit({
println "Running!"
} as Callable)
}
}
如果您有执行程序插件,请使用此代替runsync
。
如果MyService
的依赖注入不起作用,请清理您的应用:
grails stop-app
grails clean-all
grails refresh-dependencies
grails run-app