【问题标题】:Grails - running a TCP thread on backgroundGrails - 在后台运行 TCP 线程
【发布时间】:2014-06-06 20:39:48
【问题描述】:

我想要一个应用程序来监听 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

【问题讨论】:

    标签: hibernate grails


    【解决方案1】:

    您应该将服务类移动到 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】:

      我在这里创建了一个简短的 SocketServer 示例(称为“gsocket”): https://github.com/m-schneider/gsocket 如果您在“BootStrap.groovy”中定义服务类不是先决条件,它应该满足您的需求 - 希望是;) Socket Server 客户端 (client.groovy) 也在主文件夹中,用于快速测试。

      希望对您有所帮助。

      【讨论】:

        【解决方案3】:

        您应该按照@Fabrizio D'Ammassa 的建议将您的 doSomethoing() 方法移动到单独的服务中,如果您不想将代码移动到单独的服务中,那么您可以实现以下目标:

        class BootStrap {
        
        
        def init = { servletContext ->
            log.info("Bootstrapping")
            development {
                log.info("Doing myService async ")
                doSomething()
            }
        }
        
        
            def doSomething() {
                runAsync {
                    println "Running!"
                }
            }
        
        }
        

        【讨论】:

          【解决方案4】:

          好吧,我想你应该看看这个插件: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') {
              }
          }
          

          您甚至可以在mina2 上使用netty。有关它们与 apache camel 集成的更多信息,请查看以下文档。

          Netty 组件:http://camel.apache.org/netty.html

          Mina2 组件:http://camel.apache.org/mina2.html

          所有骆驼组件:http://camel.apache.org/components.html

          希望这会有所帮助!

          【讨论】:

            【解决方案5】:

            不,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
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-02-15
              相关资源
              最近更新 更多