如何在camel-scala中构建从文件到websocket客户端的路由?

时间:2016-02-15 10:19:43

标签: apache scala apache-camel

我需要从/ files目录下的文件中读取,然后在websocket客户端上显示该文件的内容。这就是我在MyRouteBuilder.scala中所做的事情:

import org.apache.camel.component.websocket.WebsocketComponent
import org.apache.camel.{LoggingLevel, CamelContext, Exchange}
import org.apache.camel.scala.dsl.builder.ScalaRouteBuilder

/**
 * A Camel Router using the Scala DSL
 */
class MyRouteBuilder(override val context : CamelContext) extends ScalaRouteBuilder(context) {

  // an example of a Processor method
  val myProcessorMethod = (exchange: Exchange) => {
    exchange.getIn.setBody("block test")
  }

  val ws = context.getComponent("websocket", classOf[WebsocketComponent]);
  ws.setPort(8444);
  ws.setHost("127.0.0.1")
  // we can serve static resources from the classpath: or file: system
  ws.setStaticResources("classpath:.");

  "file://files?noop=true" ==> {
    setBody(convertBodyTo(classOf[String]))
    to("websocket://127.0.0.1:8444/")
  }
}

但是,当我运行它时会给出以下stacktrace:

堆栈跟踪

java.lang.IllegalArgumentException:无法向单个连接发送消息;连接键未设置。     at org.apache.camel.component.websocket.WebsocketProducer.process(WebsocketProducer.java:57)     at org.apache.camel.util.AsyncProcessorConverterHelper $ ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)     在org.apache.camel.processor.SendProcessor.process(SendProcessor.java:141)     在org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)     at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)     在org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)     在org.apache.camel.processor.Pipeline.process(Pipeline.java:121)     在org.apache.camel.processor.Pipeline.process(Pipeline.java:83)     在org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)     at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:442)     at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:214)     在org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:178)     在org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:174)     在org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:101)     at java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:511)     at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)     at java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.access $ 301(ScheduledThreadPoolExecutor.java:180)     at java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)     在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)     at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617)     在java.lang.Thread.run(Thread.java:745) [el-2] thread#0 - file:// files] GenericFileOnCompletion WARN回滚文件策略:org.apache.camel.component.file.strategy.GenericFileRenameProcessStrategy@72611f35 for file:GenericFile [audience.json] [el-2] thread#0 - file:// files] DefaultErrorHandler ERROR在ExchangeId上传递失败(MessageId:ID-vaisakh-ubuntu-45785-1455531433908-1-11:ID-vaisakh-ubuntu-45785-1455531433908-1 -12)。交付尝试后用尽:1捕获:java.lang.IllegalArgumentException:无法向单个连接发送消息;连接键未设置。

消息历史记录

RouteId ProcessorId处理器已用完(ms) [route1] [route1] [file:// files?noop = true] [2] [route1] [convertBodyTo1] [convertBodyTo [java.lang.String]] [1] [route1] [setBody1] [setBody [{org.apache.camel.scala.ScalaExpression@f736069}]] [0] [route1] [to1] [websocket://127.0.0.1:8444 /] [1]

交换

交换[     Id ID-vaisakh-ubuntu-45785-1455531433908-1-12     ExchangePattern InOnly     标题{breadcrumbId = ID-vaisakh-ubuntu-45785-1455531433908-1-11,CamelFileAbsolute = false,CamelFileAbsolutePath = / home / sagar / IdeaProjects / SampleIntegrationService / files / audience.json,CamelFileContentType = text / plain,CamelFileLastModified = 1455526488000,CamelFileLength = 150,CamelFileName = audience.json,CamelFileNameConsumed = audience.json,CamelFileNameOnly = audience.json,CamelFileParent = files,CamelFilePath = files / audience.json,CamelFileRelativePath = audience.json,CamelRedelivered = false,CamelRedeliveryCounter = 0}     BodyType org.apache.camel.scala.dsl.SRouteDefinition     Body SRouteDefinition(Route(route1)[[From [file:// files?noop = true]] - > [ConvertBodyTo [java.lang.String],SetBody [{org.apache.camel.scala.ScalaExpression@f736069} ],[[websocket://127.0.0.1:8444 /]]],com.mediaiqdigital.sampleIntegrationService.MyRouteBuilder @ 67a27caa) ]

1 个答案:

答案 0 :(得分:1)

通过从标头设置连接密钥属性解决了该问题。

 from(websocketUrl) ==> {

     setProperty("wsConnKey", header("websocket.connectionkey"))
     to("file://files?noop=true")
 }

 "file://files?noop=true" ==> {

     setBody(convertBodyTo(classOf[String]))
     to(WEBSOCKET_RESPONSE_ENDPOINT)
 }

 from(WEBSOCKET_REPONSE_ENDPOINT) ==> {

     process(new Processor() {
         void process(Exchange exchange) {
             Object connectionKey = exchange.getproperty("wsConnKey");
             Object exchangeBody = exchange.getIn().getBody();
             exchange.getOut().setHeader("wsConnKey", connectionKey);
             exchange.getOut().setBody(exchangeBody);
         }
     })
    to(websocketUrl)
 }