├── feeder ├── src │ └── main │ │ ├── config │ │ ├── org.fusesource.mq.fabric.server-default.cfg │ │ ├── login.config │ │ ├── users.properties │ │ ├── activemq-websocket.xml │ │ └── fuseamq-websocket.xml │ │ ├── java │ │ └── com │ │ │ └── fusesource │ │ │ └── examples │ │ │ └── activemq │ │ │ └── websocket │ │ │ ├── marketdata │ │ │ ├── News.java │ │ │ ├── Stock.java │ │ │ └── Portfolio.java │ │ │ └── feed │ │ │ ├── JavaFeed.java │ │ │ ├── JSONFeed.java │ │ │ ├── XmlFeed.java │ │ │ └── FeedThread.java │ │ └── resources │ │ ├── log4j.properties │ │ ├── portfolio.xml │ │ └── news.xml └── pom.xml ├── camel-ws-ssl ├── src │ └── main │ │ ├── resources │ │ ├── jsse │ │ │ ├── keystore │ │ │ ├── server.jks │ │ │ ├── CertName.jks │ │ │ ├── keystore.jks │ │ │ ├── localhost.ks │ │ │ └── websocket.jks │ │ ├── webapp │ │ │ ├── images │ │ │ │ ├── stock_index_up.jpg │ │ │ │ └── stock_index_down.jpg │ │ │ ├── css │ │ │ │ ├── images │ │ │ │ │ ├── ui-icons_004276_256x240.png │ │ │ │ │ ├── ui-icons_cc0000_256x240.png │ │ │ │ │ ├── ui-icons_ffffff_256x240.png │ │ │ │ │ ├── ui-bg_flat_0_333333_40x100.png │ │ │ │ │ ├── ui-bg_flat_65_ffffff_40x100.png │ │ │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ │ │ │ ├── ui-bg_glass_55_fbf8ee_1x400.png │ │ │ │ │ ├── ui-bg_dots-small_65_a6a6a6_2x2.png │ │ │ │ │ ├── ui-bg_diagonals-thick_75_f3d8d8_40x40.png │ │ │ │ │ ├── ui-bg_highlight-hard_100_eeeeee_1x100.png │ │ │ │ │ ├── ui-bg_highlight-hard_100_f6f6f6_1x100.png │ │ │ │ │ └── ui-bg_highlight-soft_15_cc0000_1x100.png │ │ │ │ └── style.css │ │ │ ├── index.html │ │ │ ├── WEB-INF │ │ │ │ └── web.xml │ │ │ ├── news-camel-wss.html │ │ │ └── js │ │ │ │ ├── news-camel-wss.js │ │ │ │ └── stomp.js │ │ ├── twitter-options.properties │ │ ├── log4j.properties │ │ ├── spring │ │ │ └── broker-camel.xml │ │ └── META-INF │ │ │ └── spring │ │ │ └── camel-context-ssl.xml │ │ └── java │ │ └── com │ │ └── fusesource │ │ └── examples │ │ └── camel │ │ └── websocket │ │ └── secure │ │ └── WebSocketWSSNewsRoute.java └── pom.xml ├── web ├── src │ └── main │ │ └── webapp │ │ ├── images │ │ ├── stock_index_down.jpg │ │ └── stock_index_up.jpg │ │ ├── css │ │ ├── images │ │ │ ├── ui-icons_004276_256x240.png │ │ │ ├── ui-icons_cc0000_256x240.png │ │ │ ├── ui-icons_ffffff_256x240.png │ │ │ ├── ui-bg_flat_0_333333_40x100.png │ │ │ ├── ui-bg_flat_65_ffffff_40x100.png │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ │ ├── ui-bg_glass_55_fbf8ee_1x400.png │ │ │ ├── ui-bg_dots-small_65_a6a6a6_2x2.png │ │ │ ├── ui-bg_diagonals-thick_75_f3d8d8_40x40.png │ │ │ ├── ui-bg_highlight-hard_100_eeeeee_1x100.png │ │ │ ├── ui-bg_highlight-hard_100_f6f6f6_1x100.png │ │ │ └── ui-bg_highlight-soft_15_cc0000_1x100.png │ │ └── style.css │ │ ├── WEB-INF │ │ └── web.xml │ │ ├── stocks-activemq.html │ │ └── js │ │ ├── stock-quote.js │ │ └── stomp.js └── pom.xml ├── camel-ws ├── src │ ├── main │ │ ├── resources │ │ │ ├── webapp │ │ │ │ ├── images │ │ │ │ │ ├── stock_index_down.jpg │ │ │ │ │ └── stock_index_up.jpg │ │ │ │ ├── css │ │ │ │ │ ├── images │ │ │ │ │ │ ├── ui-icons_004276_256x240.png │ │ │ │ │ │ ├── ui-icons_cc0000_256x240.png │ │ │ │ │ │ ├── ui-icons_ffffff_256x240.png │ │ │ │ │ │ ├── ui-bg_flat_0_333333_40x100.png │ │ │ │ │ │ ├── ui-bg_flat_65_ffffff_40x100.png │ │ │ │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ │ │ │ │ ├── ui-bg_glass_55_fbf8ee_1x400.png │ │ │ │ │ │ ├── ui-bg_dots-small_65_a6a6a6_2x2.png │ │ │ │ │ │ ├── ui-bg_diagonals-thick_75_f3d8d8_40x40.png │ │ │ │ │ │ ├── ui-bg_highlight-hard_100_eeeeee_1x100.png │ │ │ │ │ │ ├── ui-bg_highlight-hard_100_f6f6f6_1x100.png │ │ │ │ │ │ └── ui-bg_highlight-soft_15_cc0000_1x100.png │ │ │ │ │ └── style.css │ │ │ │ ├── index.html │ │ │ │ ├── WEB-INF │ │ │ │ │ └── web.xml │ │ │ │ ├── stocks-camel.html │ │ │ │ ├── js │ │ │ │ │ ├── news-camel-wss.js │ │ │ │ │ ├── news-camel.js │ │ │ │ │ ├── stock-quote-camel.js │ │ │ │ │ ├── stock-quote.js │ │ │ │ │ └── stomp.js │ │ │ │ ├── news-camel.html │ │ │ │ ├── stocks-activemq.html │ │ │ │ └── chat-camel.html │ │ │ ├── twitter-options.properties │ │ │ ├── log4j.properties │ │ │ ├── spring │ │ │ │ └── broker-camel.xml │ │ │ └── META-INF │ │ │ │ └── spring │ │ │ │ └── camel-context.xml │ │ └── java │ │ │ └── com │ │ │ └── fusesource │ │ │ └── examples │ │ │ └── camel │ │ │ └── websocket │ │ │ ├── Helper.java │ │ │ ├── WebSocketChatRoute.java │ │ │ ├── WebSocketNewsRoute.java │ │ │ ├── WebSocketStockPricesRoute.java │ │ │ └── TwitterRoute.java │ └── test │ │ └── resources │ │ └── twitter4j.properties └── pom.xml ├── features ├── src │ └── main │ │ └── resources │ │ └── features.xml └── pom.xml ├── pom.xml └── README.md /feeder/src/main/config/org.fusesource.mq.fabric.server-default.cfg: -------------------------------------------------------------------------------- 1 | config = ${karaf.home}/etc/fuseamq-websocket.xml -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/jsse/keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/jsse/keystore -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/jsse/server.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/jsse/server.jks -------------------------------------------------------------------------------- /web/src/main/webapp/images/stock_index_down.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/web/src/main/webapp/images/stock_index_down.jpg -------------------------------------------------------------------------------- /web/src/main/webapp/images/stock_index_up.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/web/src/main/webapp/images/stock_index_up.jpg -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/jsse/CertName.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/jsse/CertName.jks -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/jsse/keystore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/jsse/keystore.jks -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/jsse/localhost.ks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/jsse/localhost.ks -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/jsse/websocket.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/jsse/websocket.jks -------------------------------------------------------------------------------- /web/src/main/webapp/css/images/ui-icons_004276_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/web/src/main/webapp/css/images/ui-icons_004276_256x240.png -------------------------------------------------------------------------------- /web/src/main/webapp/css/images/ui-icons_cc0000_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/web/src/main/webapp/css/images/ui-icons_cc0000_256x240.png -------------------------------------------------------------------------------- /web/src/main/webapp/css/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/web/src/main/webapp/css/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/images/stock_index_down.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws/src/main/resources/webapp/images/stock_index_down.jpg -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/images/stock_index_up.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws/src/main/resources/webapp/images/stock_index_up.jpg -------------------------------------------------------------------------------- /web/src/main/webapp/css/images/ui-bg_flat_0_333333_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/web/src/main/webapp/css/images/ui-bg_flat_0_333333_40x100.png -------------------------------------------------------------------------------- /web/src/main/webapp/css/images/ui-bg_flat_65_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/web/src/main/webapp/css/images/ui-bg_flat_65_ffffff_40x100.png -------------------------------------------------------------------------------- /web/src/main/webapp/css/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/web/src/main/webapp/css/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /web/src/main/webapp/css/images/ui-bg_glass_55_fbf8ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/web/src/main/webapp/css/images/ui-bg_glass_55_fbf8ee_1x400.png -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/images/stock_index_up.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/webapp/images/stock_index_up.jpg -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/images/stock_index_down.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/webapp/images/stock_index_down.jpg -------------------------------------------------------------------------------- /web/src/main/webapp/css/images/ui-bg_dots-small_65_a6a6a6_2x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/web/src/main/webapp/css/images/ui-bg_dots-small_65_a6a6a6_2x2.png -------------------------------------------------------------------------------- /web/src/main/webapp/css/images/ui-bg_diagonals-thick_75_f3d8d8_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/web/src/main/webapp/css/images/ui-bg_diagonals-thick_75_f3d8d8_40x40.png -------------------------------------------------------------------------------- /web/src/main/webapp/css/images/ui-bg_highlight-hard_100_eeeeee_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/web/src/main/webapp/css/images/ui-bg_highlight-hard_100_eeeeee_1x100.png -------------------------------------------------------------------------------- /web/src/main/webapp/css/images/ui-bg_highlight-hard_100_f6f6f6_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/web/src/main/webapp/css/images/ui-bg_highlight-hard_100_f6f6f6_1x100.png -------------------------------------------------------------------------------- /web/src/main/webapp/css/images/ui-bg_highlight-soft_15_cc0000_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/web/src/main/webapp/css/images/ui-bg_highlight-soft_15_cc0000_1x100.png -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/css/images/ui-icons_004276_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws/src/main/resources/webapp/css/images/ui-icons_004276_256x240.png -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/css/images/ui-icons_cc0000_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws/src/main/resources/webapp/css/images/ui-icons_cc0000_256x240.png -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/css/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws/src/main/resources/webapp/css/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/css/images/ui-icons_004276_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/webapp/css/images/ui-icons_004276_256x240.png -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/css/images/ui-icons_cc0000_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/webapp/css/images/ui-icons_cc0000_256x240.png -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/css/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/webapp/css/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/css/images/ui-bg_flat_0_333333_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws/src/main/resources/webapp/css/images/ui-bg_flat_0_333333_40x100.png -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/css/images/ui-bg_flat_65_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws/src/main/resources/webapp/css/images/ui-bg_flat_65_ffffff_40x100.png -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/css/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws/src/main/resources/webapp/css/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/css/images/ui-bg_glass_55_fbf8ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws/src/main/resources/webapp/css/images/ui-bg_glass_55_fbf8ee_1x400.png -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_flat_0_333333_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_flat_0_333333_40x100.png -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_flat_65_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_flat_65_ffffff_40x100.png -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_glass_55_fbf8ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_glass_55_fbf8ee_1x400.png -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/css/images/ui-bg_dots-small_65_a6a6a6_2x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws/src/main/resources/webapp/css/images/ui-bg_dots-small_65_a6a6a6_2x2.png -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_dots-small_65_a6a6a6_2x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_dots-small_65_a6a6a6_2x2.png -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/css/images/ui-bg_diagonals-thick_75_f3d8d8_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws/src/main/resources/webapp/css/images/ui-bg_diagonals-thick_75_f3d8d8_40x40.png -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/css/images/ui-bg_highlight-hard_100_eeeeee_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws/src/main/resources/webapp/css/images/ui-bg_highlight-hard_100_eeeeee_1x100.png -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/css/images/ui-bg_highlight-hard_100_f6f6f6_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws/src/main/resources/webapp/css/images/ui-bg_highlight-hard_100_f6f6f6_1x100.png -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/css/images/ui-bg_highlight-soft_15_cc0000_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws/src/main/resources/webapp/css/images/ui-bg_highlight-soft_15_cc0000_1x100.png -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_diagonals-thick_75_f3d8d8_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_diagonals-thick_75_f3d8d8_40x40.png -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_highlight-hard_100_eeeeee_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_highlight-hard_100_eeeeee_1x100.png -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_highlight-hard_100_f6f6f6_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_highlight-hard_100_f6f6f6_1x100.png -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_highlight-soft_15_cc0000_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FuseByExample/websocket-activemq-camel/HEAD/camel-ws-ssl/src/main/resources/webapp/css/images/ui-bg_highlight-soft_15_cc0000_1x100.png -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | Hello Android 9 | 10 | -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | Hello Android 9 | 10 | -------------------------------------------------------------------------------- /camel-ws/src/test/resources/twitter4j.properties: -------------------------------------------------------------------------------- 1 | # My account 2 | oauth.consumerKey=rtPIDQIqbGsEK1TEQA5g 3 | oauth.consumerSecret=HyoWW3B4wJHesm0tvf4IVI9C9aRHX40TuyEz8qrk 4 | oauth.accessToken=79766620-DoreB85PQt3bCDMpQQYUsBTzRprjOAAulD2RmG0IP 5 | oauth.accessTokenSecret=VNjI9IrPNA2XHEnlGF37QZAzOuRzHY3esg0B8jWGs 6 | debug=true 7 | http.prettyDebug=true -------------------------------------------------------------------------------- /camel-ws/src/main/resources/twitter-options.properties: -------------------------------------------------------------------------------- 1 | # This uses the Twitter 'cameltweet' account for testing purposes. 2 | consumer.key=NMqaca1bzXsOcZhP2XlwA 3 | consumer.secret=VxNQiRLwwKVD0K9mmfxlTTbVdgRpriORypnUbHhxeQw 4 | access.token=26693234-W0YjxL9cMJrC0VZZ4xdgFMymxIQ10LeL1K8YlbBY 5 | access.token.secret=BZD51BgzbOdFstWZYsqB5p5dbuuDV12vrOdatzhY4E -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/twitter-options.properties: -------------------------------------------------------------------------------- 1 | #This uses the Twitter 'cameltweet' account for testing purposes. 2 | consumer.key=NMqaca1bzXsOcZhP2XlwA 3 | consumer.secret=VxNQiRLwwKVD0K9mmfxlTTbVdgRpriORypnUbHhxeQw 4 | access.token=26693234-W0YjxL9cMJrC0VZZ4xdgFMymxIQ10LeL1K8YlbBY 5 | access.token.secret=BZD51BgzbOdFstWZYsqB5p5dbuuDV12vrOdatzhY4E -------------------------------------------------------------------------------- /web/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # 2 | # The logging properties used 3 | # 4 | log4j.rootLogger=INFO, out 5 | 6 | # uncomment the following line to turn on Camel debugging 7 | log4j.logger.org.apache.camel.component.websocket=DEBUG 8 | log4j.logger.org.eclipse.jetty.websocket=DEBUG 9 | log4j.logger.org.eclipse.jetty=DEBUG 10 | 11 | 12 | # CONSOLE appender not used by default 13 | log4j.appender.out=org.apache.log4j.ConsoleAppender 14 | log4j.appender.out.layout=org.apache.log4j.PatternLayout 15 | log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n 16 | #log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n 17 | 18 | log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer 19 | -------------------------------------------------------------------------------- /feeder/src/main/config/login.config: -------------------------------------------------------------------------------- 1 | activemq-domain { 2 | org.apache.activemq.jaas.PropertiesLoginModule sufficient 3 | debug=true 4 | org.apache.activemq.jaas.properties.user="users.properties" 5 | org.apache.activemq.jaas.properties.group="groups.properties"; 6 | 7 | org.apache.activemq.jaas.GuestLoginModule sufficient 8 | debug=true 9 | org.apache.activemq.jaas.guest.user="guest" 10 | org.apache.activemq.jaas.guest.group="guests"; 11 | }; 12 | 13 | activemq-ssl-domain { 14 | org.apache.activemq.jaas.TextFileCertificateLoginModule required 15 | debug=true 16 | org.apache.activemq.jaas.textfiledn.user="dns.properties" 17 | org.apache.activemq.jaas.textfiledn.group="groups.properties"; 18 | }; -------------------------------------------------------------------------------- /camel-ws/src/main/java/com/fusesource/examples/camel/websocket/Helper.java: -------------------------------------------------------------------------------- 1 | package com.fusesource.examples.camel.websocket; 2 | 3 | import javax.jms.ConnectionFactory; 4 | 5 | import org.apache.activemq.ActiveMQConnectionFactory; 6 | 7 | public class Helper { 8 | 9 | public static ConnectionFactory createConnectionFactory(String options) { 10 | 11 | String url = "tcp://localhost:61616"; 12 | 13 | ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("guest","password",url); 14 | // optimize AMQ to be as fast as possible so unit testing is quicker 15 | connectionFactory.setCopyMessageOnSend(false); 16 | connectionFactory.setOptimizeAcknowledge(true); 17 | connectionFactory.setOptimizedMessageDispatch(true); 18 | 19 | return connectionFactory; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/spring/broker-camel.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /feeder/src/main/java/com/fusesource/examples/activemq/websocket/marketdata/News.java: -------------------------------------------------------------------------------- 1 | package com.fusesource.examples.activemq.websocket.marketdata; 2 | 3 | import java.io.Serializable; 4 | 5 | public class News implements Serializable { 6 | 7 | private static final long serialVersionUID = 1L; 8 | 9 | protected String symbol; 10 | protected String title; 11 | protected String info; 12 | protected String picture; 13 | 14 | public String getSymbol() { 15 | return symbol; 16 | } 17 | 18 | public void setSymbol(String symbol) { 19 | this.symbol = symbol; 20 | } 21 | 22 | public String getTitle() { 23 | return title; 24 | } 25 | 26 | public void setTitle(String title) { 27 | this.title = title; 28 | } 29 | 30 | public String getInfo() { 31 | return info; 32 | } 33 | 34 | public void setInfo(String info) { 35 | this.info = info; 36 | } 37 | 38 | 39 | public String getPicture() { 40 | return picture; 41 | } 42 | 43 | public void setPicture(String picture) { 44 | this.picture = picture; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /camel-ws/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # 2 | # The logging properties used 3 | # 4 | log4j.rootLogger=DEBUG, out, file 5 | 6 | # uncomment the following line to turn on Camel debugging 7 | log4j.logger.org.apache.camel.component.websocket=DEBUG 8 | log4j.logger.org.apache.camel.component.twitter=TRACE 9 | log4j.logger.org.eclipse.jetty.websocket=DEBUG 10 | log4j.logger.org.eclipse.jetty=DEBUG 11 | log4j.logger.twitter4j=DEBUG 12 | 13 | 14 | # CONSOLE appender not used by default 15 | log4j.appender.out=org.apache.log4j.ConsoleAppender 16 | log4j.appender.out.layout=org.apache.log4j.PatternLayout 17 | log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n 18 | #log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n 19 | 20 | log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer 21 | 22 | # File appender 23 | log4j.appender.file=org.apache.log4j.FileAppender 24 | log4j.appender.file.layout=org.apache.log4j.PatternLayout 25 | log4j.appender.file.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n 26 | log4j.appender.file.file=target/camel-twitter-test.log 27 | log4j.appender.file.append=true -------------------------------------------------------------------------------- /features/src/main/resources/features.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | mvn:org.apache.camel.karaf/apache-camel/${camel-version}/xml/features 4 | mvn:org.apache.activemq/activemq-karaf/${activemq-version}/xml/features 5 | 6 | 7 | 8 | activemq-broker 9 | 10 | camel-jms 11 | wrap:mvn:org.apache.activemq/activemq-camel/${activemq-version} 12 | 13 | 14 | 15 | 16 | broker 17 | camel 18 | camel-twitter 19 | camel-websocket 20 | mvn:com.fusesource.examples.websocket/camel-ws/${project.version} 21 | 22 | 23 | -------------------------------------------------------------------------------- /camel-ws/src/main/java/com/fusesource/examples/camel/websocket/WebSocketChatRoute.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.fusesource.examples.camel.websocket; 18 | 19 | import org.apache.camel.LoggingLevel; 20 | import org.apache.camel.builder.RouteBuilder; 21 | 22 | public class WebSocketChatRoute extends RouteBuilder { 23 | 24 | @Override 25 | public void configure() throws Exception { 26 | 27 | from("websocket://0.0.0.0:9090/chat-room").routeId("fromWebSocketChattoWebSocketChat") 28 | .log(LoggingLevel.INFO,">> Message received : ${body}") 29 | .to("websocket://0.0.0.0:9090/chat-room?sendToAll=true&staticResources=classpath:webapp"); 30 | 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /feeder/src/main/config/users.properties: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # Licensed to the Apache Software Foundation (ASF) under one or more 4 | # contributor license agreements. See the NOTICE file distributed with 5 | # this work for additional information regarding copyright ownership. 6 | # The ASF licenses this file to You under the Apache License, Version 2.0 7 | # (the "License"); you may not use this file except in compliance with 8 | # the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | ################################################################################ 19 | 20 | # 21 | # This file contains the valid users who can log into FuseMQ. Each line have to be of 22 | # the format: 23 | # 24 | # USER=PASSWORD,ROLE1,ROLE2,... 25 | # 26 | # All users and roles entered in this file are available after JBoss A-MQ startup 27 | # and modifiable via the JAAS command group. These users reside in a JAAS domain 28 | # with the name "karaf".. 29 | # 30 | # You must have at least one users to be able to access JBoss A-MQ resources 31 | 32 | admin=admin,admin 33 | guest=password,admin -------------------------------------------------------------------------------- /camel-ws/src/main/java/com/fusesource/examples/camel/websocket/WebSocketNewsRoute.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.fusesource.examples.camel.websocket; 18 | 19 | import org.apache.camel.LoggingLevel; 20 | import org.apache.camel.builder.RouteBuilder; 21 | import org.apache.camel.component.jms.JmsComponent; 22 | import org.apache.camel.component.websocket.WebsocketComponent; 23 | 24 | import javax.jms.ConnectionFactory; 25 | 26 | public class WebSocketNewsRoute extends RouteBuilder { 27 | 28 | @Override 29 | public void configure() throws Exception { 30 | 31 | from("activemq:topic:newsTopic").routeId("fromJMStoWebSocketNews") 32 | .log(LoggingLevel.DEBUG,">> News info received : ${body}") 33 | .delay(5000) 34 | .to("websocket://0.0.0.0:9090/newsTopic?sendToAll=true&staticResources=classpath:webapp"); 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /camel-ws/src/main/java/com/fusesource/examples/camel/websocket/WebSocketStockPricesRoute.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.fusesource.examples.camel.websocket; 18 | 19 | import org.apache.camel.LoggingLevel; 20 | import org.apache.camel.builder.RouteBuilder; 21 | import org.apache.camel.component.jms.JmsComponent; 22 | import org.apache.camel.component.websocket.WebsocketComponent; 23 | 24 | import javax.jms.ConnectionFactory; 25 | 26 | public class WebSocketStockPricesRoute extends RouteBuilder { 27 | 28 | @Override 29 | public void configure() throws Exception { 30 | 31 | from("activemq:topic:stockQuoteTopic").routeId("fromJMStoWebSocketQuotes") 32 | .log(LoggingLevel.DEBUG,">> Stock price received : ${body}") 33 | .to("websocket://0.0.0.0:9090/stockQuoteTopic?sendToAll=true&staticResources=classpath:webapp"); 34 | 35 | } 36 | } 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/java/com/fusesource/examples/camel/websocket/secure/WebSocketWSSNewsRoute.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.fusesource.examples.camel.websocket.secure; 18 | 19 | import org.apache.camel.LoggingLevel; 20 | import org.apache.camel.builder.RouteBuilder; 21 | 22 | public class WebSocketWSSNewsRoute extends RouteBuilder { 23 | 24 | @Override 25 | public void configure() throws Exception { 26 | 27 | from("activemq:topic:newsTopic").routeId("fromJMStoWebSocketSecureNews") 28 | .log(LoggingLevel.DEBUG, ">> News info received : ${body}") 29 | .delay(5000) 30 | .to("websocket://0.0.0.0:8443/newsTopic?sendToAll=true" + 31 | "&sslContextParametersRef=#sslContextParameters&staticResources=classpath:webapp"); 32 | 33 | // TO BE TESTED 34 | // crossOriginFilterOn=true&allowedOrigins=*&filterPath=wss& 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /camel-ws/src/main/resources/spring/broker-camel.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /feeder/src/main/java/com/fusesource/examples/activemq/websocket/feed/JavaFeed.java: -------------------------------------------------------------------------------- 1 | package com.fusesource.examples.activemq.websocket.feed; 2 | 3 | /** 4 | * Copyright 2011 FuseSource 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import com.fusesource.examples.activemq.websocket.marketdata.News; 20 | import com.fusesource.examples.activemq.websocket.marketdata.Stock; 21 | 22 | import javax.jms.Message; 23 | import javax.jms.Session; 24 | 25 | /** 26 | * 27 | * @author kmccormack 28 | */ 29 | public class JavaFeed { 30 | 31 | public static void main(String args[]) { 32 | JavaFeed feed = new JavaFeed(); 33 | feed.start(); 34 | } 35 | 36 | private static FeedThread thread = new FeedThread() { 37 | @Override 38 | Message createStockMessage(Session session, Stock updatedStock) throws Exception { 39 | return session.createObjectMessage(updatedStock); 40 | } 41 | @Override 42 | Message createNewsMessage(Session session, News news) throws Exception { 43 | return session.createObjectMessage(news); 44 | } 45 | 46 | }; 47 | 48 | public void start() { 49 | thread.start(); 50 | } 51 | 52 | public void stop() { 53 | thread.running = false; 54 | thread = null; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /camel-ws/src/main/resources/META-INF/spring/camel-context.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 21 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | com.fusesource.examples.camel.websocket 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /feeder/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | ## --------------------------------------------------------------------------- 2 | ## Licensed to the Apache Software Foundation (ASF) under one or more 3 | ## contributor license agreements. See the NOTICE file distributed with 4 | ## this work for additional information regarding copyright ownership. 5 | ## The ASF licenses this file to You under the Apache License, Version 2.0 6 | ## (the "License"); you may not use this file except in compliance with 7 | ## the License. You may obtain a copy of the License at 8 | ## 9 | ## http://www.apache.org/licenses/LICENSE-2.0 10 | ## 11 | ## Unless required by applicable law or agreed to in writing, software 12 | ## distributed under the License is distributed on an "AS IS" BASIS, 13 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ## See the License for the specific language governing permissions and 15 | ## limitations under the License. 16 | ## --------------------------------------------------------------------------- 17 | 18 | # 19 | # The logging properties used by the standalone ActiveMQ broker 20 | # 21 | log4j.rootLogger=INFO, stdout, logfile 22 | 23 | # CONSOLE appender 24 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 25 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 26 | log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss} %-5p %m%n 27 | 28 | # Log File appender 29 | log4j.appender.logfile=org.apache.log4j.FileAppender 30 | log4j.appender.logfile.layout=org.apache.log4j.PatternLayout 31 | log4j.appender.logfile.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n 32 | log4j.appender.logfile.file=./target/log/activemq.log 33 | log4j.appender.logfile.append=true 34 | 35 | # 36 | # You can change logger levels here. 37 | # 38 | log4j.logger.org.apache.activemq=INFO 39 | log4j.logger.org.apache.activemq.spring=WARN -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/news-camel-wss.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | News - Camel WebSocket - wss 5 | 6 | 7 | 8 | 9 | 10 | 20 | 21 | 22 | 23 |
24 |
25 |
26 |
27 |
28 |
 
29 |
30 |
31 |
32 |
33 |
34 |
35 | 36 |
37 |
38 | 39 |
40 |
41 | 42 |
43 |

 

44 |
45 |

 

46 |

News list

47 |

 

48 |
49 | 50 |
51 | 54 |
55 |

56 | 57 |

61 |
62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /features/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | project 7 | com.fusesource.examples.activemq.websocket 8 | 1.0 9 | 10 | 4.0.0 11 | 12 | com.fusesource.examples.websocket 13 | features 14 | pom 15 | FuseSource :: WebSocket :: Features for Karaf 16 | 17 | 18 | 19 | 20 | src/main/resources 21 | true 22 | 23 | 24 | 25 | 26 | org.apache.maven.plugins 27 | maven-resources-plugin 28 | 29 | 30 | filter 31 | generate-resources 32 | 33 | resources 34 | 35 | 36 | 37 | 38 | 39 | org.codehaus.mojo 40 | build-helper-maven-plugin 41 | 42 | 43 | attach-artifacts 44 | package 45 | 46 | attach-artifact 47 | 48 | 49 | 50 | 51 | target/classes/features.xml 52 | xml 53 | features 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/stocks-camel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Stock Quote - Camel WebSocket 5 | 6 | 7 | 8 | 18 | 19 | 20 | 21 |
22 |
23 |
24 |
25 |
26 |
 
27 |
28 |
29 |
30 |
31 |
32 |
33 | 34 |
35 |
36 | 37 |
38 |
39 | 40 | 41 |
42 |

Stock prices

43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 |
SymbolOpenLastChangeHighLow% Percent
59 |
60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/META-INF/spring/camel-context-ssl.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 36 | 39 | 40 | 41 | 44 | 45 | 46 | 47 | 48 | 49 | com.fusesource.examples.camel.websocket.secure 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /feeder/src/main/java/com/fusesource/examples/activemq/websocket/marketdata/Stock.java: -------------------------------------------------------------------------------- 1 | package com.fusesource.examples.activemq.websocket.marketdata; 2 | 3 | /** 4 | * Copyright 2011 FuseSource 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import java.util.Date; 20 | import java.io.Serializable; 21 | 22 | public class Stock implements Serializable { 23 | 24 | private static final long serialVersionUID = -8334804402463267285L; 25 | 26 | protected String symbol; 27 | protected String name; 28 | protected double low; 29 | protected double high; 30 | protected double open; 31 | protected double last; 32 | protected double change; 33 | protected Date date; 34 | 35 | public double getChange() { 36 | return change; 37 | } 38 | public void setChange(double change) { 39 | this.change = change; 40 | } 41 | public double getHigh() { 42 | return high; 43 | } 44 | public void setHigh(double high) { 45 | this.high = high; 46 | } 47 | public double getLast() { 48 | return last; 49 | } 50 | public void setLast(double last) { 51 | this.last = last; 52 | } 53 | public double getLow() { 54 | return low; 55 | } 56 | public void setLow(double low) { 57 | this.low = low; 58 | } 59 | public String getName() { 60 | return name; 61 | } 62 | public void setName(String name) { 63 | this.name = name; 64 | } 65 | public double getOpen() { 66 | return open; 67 | } 68 | public void setOpen(double open) { 69 | this.open = open; 70 | } 71 | public String getSymbol() { 72 | return symbol; 73 | } 74 | public void setSymbol(String symbol) { 75 | this.symbol = symbol; 76 | } 77 | public Date getDate() { 78 | return date; 79 | } 80 | public void setDate(Date date) { 81 | this.date = date; 82 | } 83 | 84 | } -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/js/news-camel-wss.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | 3 | var socket; 4 | 5 | $('#connect_form').submit(function () { 6 | 7 | var host = $("#url").val(); 8 | 9 | socket = new WebSocket(host); 10 | 11 | $('#connect').fadeOut({ duration:'fast' }); 12 | $('#disconnect').fadeIn(); 13 | $('#send_form_input').removeAttr('disabled'); 14 | 15 | // Add a connect listener 16 | socket.onopen = function () { 17 | $('#msg').append('

Socket News Status: ' + socket.readyState + ' (open)

'); 18 | } 19 | 20 | socket.onmessage = function (msg) { 21 | 22 | // $('#msg').append('

Received: ' + msg.data + "

"); 23 | 24 | var news = JSON.parse(msg.data); 25 | 26 | // extract the news fields 27 | var symbol = news.symbol; 28 | var title = news.title; 29 | var picture = news.picture; 30 | var info = news.info; 31 | 32 | var $res = $("
  • "); 33 | $res.append(""); 34 | $res.append(" " + symbol + " : " + title + "

    "); 35 | $res.append("Description : " + info); 36 | $res.append("

  • "); 37 | $res.appendTo('#news'); 38 | 39 | 40 | setInterval(function(){ tickNews () }, 5000); 41 | $('#newsList').show(); 42 | 43 | } 44 | 45 | socket.onclose = function () { 46 | $('#msg').append('

    Socket News Status: ' + socket.readyState + ' (Closed)

    '); 47 | } 48 | 49 | socket.onerror = function () { 50 | $('#msg').append('

    An error has occured

    '); 51 | } 52 | 53 | return false; 54 | }); 55 | 56 | $('#disconnect_form').submit(function () { 57 | 58 | socket.close(); 59 | 60 | $('#msg').append('

    Socket News Status: ' + socket.readyState + ' (Closed)

    '); 61 | 62 | $('#disconnect').fadeOut({ duration:'fast' }); 63 | $('#connect').fadeIn(); 64 | $('#send_form_input').addAttr('disabled'); 65 | 66 | return false; 67 | }); 68 | 69 | }); 70 | function tickNews() { 71 | $('#news li:first').slideUp(function () { 72 | $(this).appendTo($('#news')).slideDown(); 73 | }); 74 | } 75 | 76 | $(function() { 77 | $( "#tabs" ).tabs(); 78 | }); -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/js/news-camel-wss.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | 3 | var socket; 4 | 5 | $('#connect_form').submit(function () { 6 | 7 | var host = $("#url").val(); 8 | 9 | socket = new WebSocket(host); 10 | 11 | $('#connect').fadeOut({ duration:'fast' }); 12 | $('#disconnect').fadeIn(); 13 | $('#send_form_input').removeAttr('disabled'); 14 | 15 | // Add a connect listener 16 | socket.onopen = function () { 17 | $('#msg').append('

    Socket News Status: ' + socket.readyState + ' (open)

    '); 18 | } 19 | 20 | socket.onmessage = function (msg) { 21 | 22 | // $('#msg').append('

    Received: ' + msg.data + "

    "); 23 | 24 | var news = JSON.parse(msg.data); 25 | 26 | // extract the news fields 27 | var symbol = news.symbol; 28 | var title = news.title; 29 | var picture = news.picture; 30 | var info = news.info; 31 | 32 | var $res = $("
  • "); 33 | $res.append(""); 34 | $res.append(" " + symbol + " : " + title + "

    "); 35 | $res.append("Description : " + info); 36 | $res.append("

  • "); 37 | $res.appendTo('#news'); 38 | 39 | 40 | setInterval(function(){ tickNews () }, 5000); 41 | $('#newsList').show(); 42 | 43 | } 44 | 45 | socket.onclose = function () { 46 | $('#msg').append('

    Socket News Status: ' + socket.readyState + ' (Closed)

    '); 47 | } 48 | 49 | socket.onerror = function () { 50 | $('#msg').append('

    An error has occured

    '); 51 | } 52 | 53 | return false; 54 | }); 55 | 56 | $('#disconnect_form').submit(function () { 57 | 58 | socket.close(); 59 | 60 | $('#msg').append('

    Socket News Status: ' + socket.readyState + ' (Closed)

    '); 61 | 62 | $('#disconnect').fadeOut({ duration:'fast' }); 63 | $('#connect').fadeIn(); 64 | $('#send_form_input').addAttr('disabled'); 65 | 66 | return false; 67 | }); 68 | 69 | }); 70 | function tickNews() { 71 | $('#news li:first').slideUp(function () { 72 | $(this).appendTo($('#news')).slideDown(); 73 | }); 74 | } 75 | 76 | $(function() { 77 | $( "#tabs" ).tabs(); 78 | }); -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/news-camel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | News - Camel WebSocket - ws 5 | 6 | 7 | 8 | 9 | 10 | 20 | 21 | 22 | 23 |
    24 |
    25 |
    26 |
    27 |
    28 |
    29 |
     
    30 |
    31 |
    32 |
    33 |
    34 |
    35 |
    36 | 37 |
    38 |
    39 | 40 |
    41 |
    42 | 43 |
    44 |

     

    45 |
    46 |

     

    47 |

    News list

    48 |

     

    49 |
    50 | 51 |
    52 | 56 |
    57 |

    58 | 59 |

    63 |
    64 |

    65 | 66 |

    70 |
    71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /feeder/src/main/config/activemq-websocket.xml: -------------------------------------------------------------------------------- 1 | 17 | 25 | 26 | 27 | 28 | file:${activemq.base}/conf/credentials.properties 29 | 30 | 31 | 32 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /camel-ws/src/main/java/com/fusesource/examples/camel/websocket/TwitterRoute.java: -------------------------------------------------------------------------------- 1 | package com.fusesource.examples.camel.websocket; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.net.URL; 6 | import java.util.Properties; 7 | 8 | import org.apache.camel.builder.RouteBuilder; 9 | 10 | public class TwitterRoute extends RouteBuilder { 11 | 12 | protected String consumerKey; 13 | protected String consumerSecret; 14 | protected String accessToken; 15 | protected String accessTokenSecret; 16 | 17 | public TwitterRoute() { 18 | URL url = getClass().getResource("/twitter-options.properties"); 19 | 20 | InputStream inStream; 21 | try { 22 | inStream = url.openStream(); 23 | } catch (IOException e) { 24 | e.printStackTrace(); 25 | throw new IllegalAccessError("twitter-options.properties could not be found"); 26 | } 27 | 28 | Properties properties = new Properties(); 29 | try { 30 | properties.load(inStream); 31 | } catch (IOException e) { 32 | e.printStackTrace(); 33 | throw new IllegalAccessError("twitter-options.properties could not be found"); 34 | } 35 | 36 | consumerKey = properties.get("consumer.key").toString(); 37 | consumerSecret = properties.get("consumer.secret").toString(); 38 | accessToken = properties.get("access.token").toString(); 39 | accessTokenSecret = properties.get("access.token.secret").toString(); 40 | } 41 | 42 | @Override 43 | public void configure() { 44 | 45 | from("twitter://search?type=polling&delay=5&keywords=jfj2013&" + getUriTokens()) 46 | .routeId("fromTwittertoWebSocketTweet") 47 | .transform(body().convertToString()) 48 | .delay(5000) 49 | .log(">> Results received : ${body}") 50 | .bean(TwitterRoute.class,"tweetToJSON") 51 | .log(">> Response prepared : ${body}") 52 | .to("websocket://0.0.0.0:9090/tweetTopic?sendToAll=true&staticResources=classpath:webapp"); 53 | 54 | } 55 | 56 | protected String getUriTokens() { 57 | return "consumerKey=" + consumerKey + "&consumerSecret=" + consumerSecret + "&accessToken=" 58 | + accessToken + "&accessTokenSecret=" + accessTokenSecret; 59 | } 60 | 61 | public String tweetToJSON(String message) { 62 | StringBuilder builder = new StringBuilder(); 63 | builder.append("{\"tweet\":\""); 64 | builder.append(message); 65 | builder.append("\"}"); 66 | return builder.toString(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/stocks-activemq.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Stock Quote - Stomp Over WebSocket 5 | 6 | 7 | 8 | 9 | 19 | 20 | 21 | 22 |
    23 |
    24 |
    25 |
    26 |
    27 |
    28 |
    29 |
    30 |
    31 |
    32 |
    33 |
     
    34 |
    35 |
    36 |
    37 |
    38 |
    39 |
    40 | 41 |
    42 |
    43 | 44 | 45 |
    46 |

    Stock prices

    47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    SymbolOpenLastChangeHighLow% Percent
    63 |
    64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /web/src/main/webapp/stocks-activemq.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Stock Quote Example Using Stomp Over WebSocket 5 | 6 | 7 | 8 | 9 | 19 | 20 | 21 | 22 |
    23 |
    24 |
    25 |
    26 |
    27 |
    28 |
    29 |
    30 |
    31 |
    32 |
    33 |
     
    34 |
    35 |
    36 |
    37 |
    38 |
    39 |
    40 | 41 |
    42 |
    43 | 44 | 45 |
    46 |

    Stock prices

    47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    SymbolOpenLastChangeHighLow% Percent
    63 |
    64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /feeder/src/main/resources/portfolio.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | XOM 5 | Exxon Mobile Corp 6 | 61.56 7 | 8 | 9 | 10 | WMT 11 | Wal-Mart Stores 12 | 45.62 13 | 14 | 15 | 16 | GM 17 | General Motors Corporation 18 | 19.8 19 | 20 | 21 | 22 | CVX 23 | Chevron Corp New 24 | 58.95 25 | 26 | 27 | 28 | COP 29 | Conocophillips 30 | 67.14 31 | 32 | 33 | 34 | GE 35 | General Electric Company 36 | 33.61 37 | 38 | 39 | 40 | C 41 | Citigroup Inc 42 | 48.18 43 | 44 | 45 | 46 | AIG 47 | American International Group Inc 48 | 62.92 49 | 50 | 51 | 52 | GOOG 53 | Google Inc 54 | 417.93 55 | 56 | 57 | 58 | ADBE 59 | Adobe Systems Incorporated 60 | 39.20 61 | 62 | 63 | 64 | JBLU 65 | JetBlue Airways Corporation 66 | 10.57 67 | 68 | 69 | 70 | COKE 71 | Coca-Cola Bottling Co. Consolidated 72 | 48.20 73 | 74 | 75 | 76 | GENZ 77 | Genzyme Corporation 78 | 61.16 79 | 80 | 81 | 82 | YHOO 83 | Yahoo Inc. 84 | 32.78 85 | 86 | 87 | 88 | IBM 89 | International Business Machines Corp. 90 | 82.34 91 | 92 | 93 | 94 | BA 95 | Boeing Company 96 | 83.45 97 | 98 | 99 | 100 | SAP 101 | SAP AG 102 | 54.63 103 | 104 | 105 | 106 | MOT 107 | Motorola, Inc. 108 | 21.35 109 | 110 | 111 | 112 | VZ 113 | Verizon Communications 114 | 33.03 115 | 116 | 117 | 118 | MCD 119 | McDonald's Corporation 120 | 34.57 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /feeder/src/main/java/com/fusesource/examples/activemq/websocket/feed/JSONFeed.java: -------------------------------------------------------------------------------- 1 | package com.fusesource.examples.activemq.websocket.feed; 2 | 3 | /** 4 | * Copyright 2011 FuseSource 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import com.fusesource.examples.activemq.websocket.marketdata.News; 20 | import com.fusesource.examples.activemq.websocket.marketdata.Stock; 21 | 22 | import javax.jms.Message; 23 | import javax.jms.Session; 24 | 25 | /** 26 | * 27 | * @author kmccormack 28 | */ 29 | public class JSONFeed { 30 | 31 | public static void main(String args[]) { 32 | JSONFeed feed = new JSONFeed(); 33 | feed.start(); 34 | } 35 | 36 | private static FeedThread thread = new FeedThread() { 37 | @Override 38 | Message createStockMessage(Session session, Stock updatedStock) throws Exception { 39 | String msgText = new StringBuffer() 40 | .append("{") 41 | .append("\"symbol\": \"" + updatedStock.getSymbol() + "\",\n") 42 | .append("\"name\": \"" + updatedStock.getName() + "\",\n") 43 | .append("\"low\": " + updatedStock.getLow() + ",\n") 44 | .append("\"high\": " + updatedStock.getHigh() + ",\n") 45 | .append("\"open\": " + updatedStock.getOpen() + ",\n") 46 | .append("\"last\": " + updatedStock.getLast() + ",\n") 47 | .append("\"change\": " + updatedStock.getLast() + "") 48 | .append("}\n") 49 | .toString(); 50 | System.out.println(msgText); 51 | return session.createTextMessage(msgText); 52 | } 53 | 54 | @Override 55 | Message createNewsMessage(Session session, News news) throws Exception { 56 | String msgText = new StringBuffer() 57 | .append("{") 58 | .append("\"symbol\": \"" + news.getSymbol() + "\",\n") 59 | .append("\"title\": \"" + news.getTitle() + "\",\n") 60 | .append("\"picture\": \"" + news.getPicture() + "\",\n") 61 | .append("\"info\": \"" + news.getInfo() + "\"") 62 | .append("}\n") 63 | .toString(); 64 | System.out.println(msgText); 65 | return session.createTextMessage(msgText); 66 | } 67 | }; 68 | 69 | public void start() { 70 | thread.start(); 71 | } 72 | 73 | public void stop() { 74 | thread.running = false; 75 | thread = null; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /feeder/src/main/java/com/fusesource/examples/activemq/websocket/feed/XmlFeed.java: -------------------------------------------------------------------------------- 1 | package com.fusesource.examples.activemq.websocket.feed; 2 | 3 | /** 4 | * Copyright 2011 FuseSource 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import com.fusesource.examples.activemq.websocket.marketdata.News; 20 | import com.fusesource.examples.activemq.websocket.marketdata.Stock; 21 | 22 | import javax.jms.Message; 23 | import javax.jms.Session; 24 | 25 | /** 26 | * @author kmccormack 27 | */ 28 | public class XmlFeed { 29 | 30 | public static void main(String args[]) { 31 | XmlFeed feed = new XmlFeed(); 32 | feed.start(); 33 | } 34 | 35 | private static FeedThread thread = new FeedThread() { 36 | @Override 37 | Message createStockMessage(Session session, Stock updatedStock) throws Exception { 38 | String msgText = new StringBuffer() 39 | .append("") 40 | .append("" + updatedStock.getSymbol() + "") 41 | .append("" + updatedStock.getName() + "") 42 | .append("" + updatedStock.getLow() + "") 43 | .append("" + updatedStock.getHigh() + "") 44 | .append("" + updatedStock.getOpen() + "") 45 | .append("" + updatedStock.getLast() + "") 46 | .append("" + updatedStock.getLast() + "") 47 | .append("") 48 | .toString(); 49 | return session.createTextMessage(msgText); 50 | } 51 | 52 | @Override 53 | Message createNewsMessage(Session session, News news) throws Exception { 54 | String msgText = new StringBuffer() 55 | .append("") 56 | .append("" + news.getSymbol() + "") 57 | .append("" + news.getTitle() + "") 58 | .append("" + news.getTitle() + "") 59 | .append("" + news.getInfo() + "") 60 | .append("") 61 | .toString(); 62 | return session.createTextMessage(msgText); 63 | } 64 | 65 | }; 66 | 67 | public void start() { 68 | thread.start(); 69 | } 70 | 71 | public void stop() { 72 | thread.running = false; 73 | thread = null; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.fusesource.examples.activemq.websocket 5 | project 6 | pom 7 | 1.0 8 | FuseSource :: WebSocket :: ActiveMQ & Camel Project 9 | 10 | 11 | 2.15.1.redhat-621026 12 | 5.11.0.redhat-621026 13 | 1.7.10 14 | 1.2.17 15 | 16 | 7.6.8.v20121106 17 | 18 | 19 | 20 | feeder 21 | web 22 | camel-ws 23 | camel-ws-ssl 24 | features 25 | 26 | 27 | 28 | 29 | org.apache.activemq 30 | activemq-all 31 | ${activemq.version} 32 | 33 | 34 | org.slf4j 35 | slf4j-api 36 | ${slf4j.version} 37 | 38 | 39 | 40 | 41 | 42 | fusesource.releases 43 | FuseSource Release Repository 44 | https://repository.jboss.org/nexus/content/repositories/fs-releases/ 45 | 46 | true 47 | 48 | 49 | false 50 | 51 | 52 | 53 | fusesource.ea 54 | FuseSource Early Access Release Repository 55 | https://repository.jboss.org/nexus/content/groups/ea/ 56 | 57 | false 58 | 59 | 60 | true 61 | 62 | 63 | 64 | 65 | 66 | fusesource.releases 67 | FuseSource Release Repository 68 | https://repository.jboss.org/nexus/content/repositories/fs-releases/ 69 | 70 | true 71 | 72 | 73 | false 74 | 75 | 76 | 77 | fusesource.ea 78 | FuseSource Early Access Release Repository 79 | https://repository.jboss.org/nexus/content/groups/ea/ 80 | 81 | false 82 | 83 | 84 | true 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /feeder/src/main/config/fuseamq-websocket.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/js/news-camel.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | 3 | var socket1, socket2; 4 | 5 | $('#connect_form').submit(function () { 6 | 7 | var host1 = $("#url1").val(); 8 | var host2 = $("#url2").val(); 9 | 10 | socket1 = new WebSocket(host1); 11 | socket2 = new WebSocket(host2); 12 | 13 | $('#connect').fadeOut({ duration:'fast' }); 14 | $('#disconnect').fadeIn(); 15 | $('#send_form_input').removeAttr('disabled'); 16 | 17 | // Add a connect listener 18 | socket1.onopen = function () { 19 | $('#msg').append('

    Socket News Status: ' + socket1.readyState + ' (open)

    '); 20 | } 21 | socket2.onopen = function () { 22 | $('#msg').append('

    Socket Tweet Status: ' + socket2.readyState + ' (open)

    '); 23 | } 24 | 25 | socket1.onmessage = function (msg) { 26 | 27 | // $('#msg').append('

    Received: ' + msg.data + "

    "); 28 | 29 | var news = JSON.parse(msg.data); 30 | 31 | // extract the news fields 32 | var symbol = news.symbol; 33 | var title = news.title; 34 | var picture = news.picture; 35 | var info = news.info; 36 | 37 | var $res = $("
  • "); 38 | $res.append(""); 39 | $res.append(" " + symbol + " : " + title + "

    "); 40 | $res.append("Description : " + info); 41 | $res.append("

  • "); 42 | $res.appendTo('#news'); 43 | 44 | 45 | setInterval(function(){ tickNews () }, 5000); 46 | $('#newsList').show(); 47 | 48 | } 49 | 50 | socket2.onmessage = function (msg) { 51 | 52 | // $('#msg').append('

    Received: ' + msg.data + "

    "); 53 | 54 | var message = JSON.parse(msg.data); 55 | 56 | // extract the tweets 57 | var txt = message.tweet; 58 | 59 | var $res = $("
  • "); 60 | $res.append(txt); 61 | $res.appendTo($('#tweet')); 62 | 63 | setInterval(function () { 64 | tickTweet() 65 | }, 5000); 66 | $('#tweetList').show(); 67 | 68 | } 69 | 70 | socket1.onclose = function () { 71 | $('#msg').append('

    Socket News Status: ' + socket1.readyState + ' (Closed)

    '); 72 | } 73 | 74 | socket2.onclose = function () { 75 | $('#msg').append('

    Socket Tweet Status: ' + socket2.readyState + ' (Closed)

    '); 76 | } 77 | 78 | 79 | return false; 80 | }); 81 | 82 | $('#disconnect_form').submit(function () { 83 | 84 | socket1.close(); 85 | socket2.close(); 86 | 87 | $('#msg').append('

    Socket News Status: ' + socket1.readyState + ' (Closed)

    '); 88 | $('#msg').append('

    Socket Tweet Status: ' + socket2.readyState + ' (Closed)

    '); 89 | 90 | $('#disconnect').fadeOut({ duration:'fast' }); 91 | $('#connect').fadeIn(); 92 | $('#send_form_input').addAttr('disabled'); 93 | 94 | return false; 95 | }); 96 | 97 | }); 98 | function tickNews() { 99 | $('#news li:first').slideUp(function () { 100 | $(this).appendTo($('#news')).slideDown(); 101 | }); 102 | } 103 | 104 | function tickTweet() { 105 | $('#tweet li:first').slideUp(function () { 106 | $(this).appendTo($('#tweet')).slideDown(); 107 | }); 108 | } 109 | 110 | $(function() { 111 | $( "#tabs" ).tabs(); 112 | }); -------------------------------------------------------------------------------- /feeder/src/main/resources/news.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | FUSE 4 | CamelOne Brings Integration and Messaging Experts to Boston 5 | http://si0.twimg.com/profile_images/1152103417/fuseicon_pb.jpg 6 | FuseSource Corp., experts in open source integration and messaging, today announced some of the many celebrated experts and enterprises that will share success stories and best practices at CamelOne – the only event designed for enterprise users of open source integration and messaging. CamelOne 2012 will be held in Boston, Massachusetts from May 15-16, 2012 at the Sheraton Boston Hotel. 7 | 8 | 9 | FUSE 10 | Lynden Uses FuseSource’s Enterprise-Class Open Source Distributions 11 | http://si0.twimg.com/profile_images/1152103417/fuseicon_pb.jpg 12 | Lynden Uses FuseSource’s Enterprise-Class Distributions of Open Source Integration and Messaging Solutions to Improve Shipment Tracking and Reporting for High Volume Customers. 13 | 14 | 15 | APPLE 16 | Apple earnings: Will big numbers rev up its stock? 17 | http://asset3.cbsistatic.com/cnwk.1d/i/tim/2012/02/06/appleearnings.jpg 18 | Apple reports its second quarter results tomorrow, and bigger sales of iPhones and iPads may help reverse AAPL's recent downward stock trajectory. 19 | 20 | 21 | APPLE 22 | Apple iPad 3 expected on 7 March following press event 23 | http://news.bbcimg.co.uk/media/images/58774000/jpg/_58774106_58773429.jpg 24 | Apple has announced an event on 7 March at which the company is expected to launch its latest iPad tablet. Invitations sent to journalists read: We have something you really have to see. And touch. While not officially confirming the product's launch, the message was accompanied by an image showing what looked to be an iPad touchscreen. 25 | 26 | 27 | FUSE 28 | FuseSource Launches Beta Program for New Open Source Integration and Messaging Platforms 29 | http://si0.twimg.com/profile_images/1152103417/fuseicon_pb.jpg 30 | FuseSource Corp., experts in open source integration and messaging, today invited enterprise software developers, architects and DevOps professionals to participate in a beta program for two new platforms that deliver the capabilities enterprises need to use open-source technology for all of their integration and messaging needs. Both products reflect the low cost and flexibility inherent in open source and build on FuseSource™ enterprise-class offerings based on popular Apache Software Foundation projects Apache ServiceMix, ActiveMQ, Camel, and CXF. 31 | 32 | 33 | GOOGLE 34 | Google to launch online storage service for consumers 35 | http://znn.india.com/Img/2012/4/24/googlei.jpg 36 | San Francisco: Google Inc is preparing to roll out a service to let consumers store photos and other content online, a source familiar with the matter said, pushing into a market now dominated by the likes of Dropbox and Box.The service, to be called Google Drive, could be announced as soon as Tuesday and would be offered with both free and premium for-pay versions, the source said. 37 | 38 | 39 | FUSE 40 | In Mid-May, CamelOne Event Explores Surge in Open Source Integration by Large Enterprises 41 | http://si0.twimg.com/profile_images/1152103417/fuseicon_pb.jpg 42 | The growing role of open source middleware, even in large-scale enterprises, will be on display at FuseSource’s CamelOne event in Boston, May 15-16. Attendees will see FuseSource’s latest offerings based on Apache’s top open source middleware projects, hear from top Apache committers and learn the latest best practices that are driving a new wave of open source-based integration. 43 | 44 | 45 | -------------------------------------------------------------------------------- /feeder/src/main/java/com/fusesource/examples/activemq/websocket/marketdata/Portfolio.java: -------------------------------------------------------------------------------- 1 | package com.fusesource.examples.activemq.websocket.marketdata; 2 | 3 | /** 4 | * Copyright 2011 FuseSource 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import org.w3c.dom.Document; 20 | import org.w3c.dom.Element; 21 | import org.w3c.dom.Node; 22 | import org.w3c.dom.NodeList; 23 | 24 | import javax.xml.parsers.DocumentBuilderFactory; 25 | import java.io.File; 26 | import java.net.URLDecoder; 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | 30 | public class Portfolio { 31 | 32 | public static void main(String[] args) { 33 | Portfolio stockFeed = new Portfolio(); 34 | stockFeed.getStocks(); 35 | stockFeed.getNews(); 36 | } 37 | 38 | public List getStocks() { 39 | 40 | List list = new ArrayList(); 41 | 42 | try { 43 | String filePath = URLDecoder.decode(getClass().getClassLoader().getResource("portfolio.xml").getFile(), "UTF-8"); 44 | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 45 | factory.setValidating(false); 46 | Document doc = factory.newDocumentBuilder().parse(new File(filePath)); 47 | NodeList stockNodes = doc.getElementsByTagName("stock"); 48 | int length = stockNodes.getLength(); 49 | Stock stock; 50 | Node stockNode; 51 | for (int i=0; iSocket Status: ' + socket.readyState + ' (open)

    '); 19 | } 20 | 21 | socket.onmessage = function (msg) { 22 | // $('#msg').append('

    Received: ' + msg.data + "

    "); 23 | 24 | var quote = JSON.parse(msg.data); 25 | 26 | // extract the stock data fields 27 | var symbol = quote.symbol; 28 | var open = quote.open.toFixed(2); 29 | var last = quote.last.toFixed(2); 30 | var high = quote.high.toFixed(2); 31 | var low = quote.low.toFixed(2); 32 | var newPrice = quote.change.toFixed(2); 33 | 34 | // lookup the table row 35 | var stockRowIndex = stockRowIndexes[symbol]; 36 | var stockRow = stockTable.rows[stockRowIndex]; 37 | 38 | // lazily populate the table row, with 6 cells 39 | if (stockRow === undefined) { 40 | var stockRowIndex = stockTable.rows.length; 41 | stockRow = stockTable.insertRow(stockRowIndex); 42 | for (var cell = 0; cell < 7; cell++) { 43 | stockRow.insertCell(cell); 44 | } 45 | stockRow.cells[0].className = 'symbol'; 46 | stockRow.cells[1].className = 'open'; 47 | stockRow.cells[2].className = 'last'; 48 | stockRow.cells[3].className = 'change'; 49 | stockRow.cells[4].className = 'high'; 50 | stockRow.cells[5].className = 'low'; 51 | stockRow.cells[6].className = 'percent'; 52 | stockRowIndexes[symbol] = stockRowIndex; 53 | } 54 | 55 | 56 | // detect price change 57 | var oldPrice = Number(stockRow.cells[2].innerHTML); 58 | var oldChange = Number(stockRow.cells[3].innerHTML); 59 | var change = ((oldPrice != 0) ? (newPrice - oldPrice) : 0).toFixed(2); 60 | var percent = ((oldPrice != 0) ? (change / oldPrice * 100) : 0).toFixed(1); 61 | 62 | // update the table row cell data 63 | stockRow.cells[0].innerHTML = symbol; 64 | stockRow.cells[1].innerHTML = open; 65 | stockRow.cells[2].innerHTML = last; 66 | stockRow.cells[3].innerHTML = change; 67 | stockRow.cells[4].innerHTML = high; 68 | stockRow.cells[5].innerHTML = low; 69 | stockRow.cells[6].innerHTML = percent; 70 | 71 | // update the table row cell styles 72 | var oldSign = (oldChange != 0) ? oldChange / Math.abs(oldChange) : 0; 73 | var sign = (change != 0) ? change / Math.abs(change) : 0; 74 | if (sign != oldSign) { 75 | switch (sign) { 76 | case 1: 77 | stockRow.cells[3].className = 'upChange'; 78 | stockRow.cells[4].className = 'upPercent'; 79 | break; 80 | case -1: 81 | stockRow.cells[3].className = 'downChange'; 82 | stockRow.cells[4].className = 'downPercent'; 83 | break; 84 | } 85 | } 86 | 87 | 88 | } 89 | 90 | socket.onclose = function () { 91 | $('#msg').append('

    Socket Status: ' + socket.readyState + ' (Closed)

    '); 92 | } 93 | 94 | return false; 95 | }); 96 | 97 | $('#disconnect_form').submit(function () { 98 | 99 | socket.close(); 100 | 101 | $('#msg').append('

    Socket Status: ' + socket.readyState + ' (Closed)

    '); 102 | $('#disconnect').fadeOut({ duration:'fast' }); 103 | $('#connect').fadeIn(); 104 | $('#send_form_input').addAttr('disabled'); 105 | 106 | return false; 107 | }); 108 | 109 | }); 110 | -------------------------------------------------------------------------------- /web/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | com.fusesource.examples.activemq.websocket 7 | project 8 | 1.0 9 | 10 | 11 | com.fusesource.examples.websocket 12 | web 13 | war 14 | 1.0 15 | FuseSource :: WebSocket :: ActiveMQ :: Web 16 | 17 | 18 | 19 | org.apache.activemq 20 | activemq-all 21 | ${activemq.version} 22 | provided 23 | 24 | 25 | org.slf4j 26 | slf4j-api 27 | ${slf4j.version} 28 | provided 29 | 30 | 31 | 32 | 33 | 34 | 35 | org.apache.maven.plugins 36 | maven-war-plugin 37 | 2.2 38 | 39 | 40 | 41 | 42 | org.codehaus.mojo 43 | keytool-maven-plugin 44 | 1.1 45 | 46 | 47 | generate-resources 48 | clean 49 | 50 | clean 51 | 52 | 53 | 54 | generate-resources 55 | genkey 56 | 57 | genkey 58 | 59 | 60 | 61 | 62 | ${project.build.directory}/jetty-ssl.keystore 63 | cn=com.fusesource.example 64 | jetty-ws 65 | jetty-ws 66 | jetty-ws 67 | RSA 68 | 69 | 70 | 71 | 72 | 73 | org.mortbay.jetty 74 | jetty-maven-plugin 75 | ${jetty.maven.plugin.version} 76 | 77 | 78 | 79 | 80 | 8282 81 | 60000 82 | 83 | 84 | 8449 85 | 60000 86 | ${project.build.directory}/jetty-ssl.keystore 87 | jetty-ws 88 | jetty-ws 89 | 92 | 93 | 94 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /feeder/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | com.fusesource.examples.activemq.websocket 7 | project 8 | 1.0 9 | ../pom.xml 10 | 11 | 12 | com.fusesource.examples.websocket 13 | trader 14 | jar 15 | 1.0 16 | FuseSource :: WebSocket :: ActiveMQ :: Trader 17 | 18 | 19 | 20 | run-trader 21 | 22 | package 23 | 24 | 25 | org.codehaus.mojo 26 | exec-maven-plugin 27 | 1.2 28 | 29 | 30 | 31 | java 32 | 33 | package 34 | 35 | com.fusesource.examples.activemq.websocket.feed.JSONFeed 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | run-activemq 45 | 46 | 47 | 48 | org.apache.activemq.tooling 49 | maven-activemq-plugin 50 | ${activemq.version} 51 | 52 | 53 | 54 | run 55 | 56 | package 57 | 58 | 59 | 60 | xbean:file:${basedir}/src/main/config/activemq-websocket.xml 61 | false 62 | 63 | 64 | org.apache.activemq.default.directory.prefix 65 | ./target/ 66 | 67 | 68 | 69 | 70 | 71 | org.apache.xbean 72 | xbean-spring 73 | 3.5 74 | 75 | 76 | org.apache.activemq 77 | activemq-optional 78 | ${activemq.version} 79 | 80 | 81 | org.slf4j 82 | slf4j-log4j12 83 | ${slf4j.version} 84 | 85 | 86 | org.slf4j 87 | slf4j-api 88 | 1.6.4 89 | 90 | 91 | log4j 92 | log4j 93 | ${log4j.version} 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /feeder/src/main/java/com/fusesource/examples/activemq/websocket/feed/FeedThread.java: -------------------------------------------------------------------------------- 1 | package com.fusesource.examples.activemq.websocket.feed; 2 | 3 | /** 4 | * Copyright 2011 FuseSource 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | import com.fusesource.examples.activemq.websocket.marketdata.News; 20 | import com.fusesource.examples.activemq.websocket.marketdata.Portfolio; 21 | import com.fusesource.examples.activemq.websocket.marketdata.Stock; 22 | import org.apache.activemq.ActiveMQConnectionFactory; 23 | 24 | import javax.jms.*; 25 | import java.util.Date; 26 | import java.util.Iterator; 27 | import java.util.List; 28 | import java.util.Random; 29 | 30 | /** 31 | * @author kmccormack 32 | */ 33 | public abstract class FeedThread extends Thread { 34 | 35 | public boolean running = true; 36 | private Random random; 37 | 38 | abstract Message createStockMessage(Session session, Stock updatedStock) throws Exception; 39 | 40 | abstract Message createNewsMessage(Session session, News news) throws Exception; 41 | 42 | public void run() { 43 | try { 44 | 45 | // create the connection factory 46 | ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616"); 47 | Connection connection = connectionFactory.createConnection("guest", "password"); 48 | //Connection connection = connectionFactory.createConnection(); 49 | connection.start(); 50 | 51 | // Create the session and topic 52 | Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 53 | Topic quoteTopic = session.createTopic("stockQuoteTopic"); 54 | Topic newsTopic = session.createTopic("newsTopic"); 55 | MessageProducer quotesProducer = session.createProducer(quoteTopic); 56 | MessageProducer newsProducer = session.createProducer(newsTopic); 57 | quotesProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); 58 | newsProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); 59 | 60 | // load in the portfolio of stocks 61 | Portfolio portfolio = new Portfolio(); 62 | List stocksList = portfolio.getStocks(); 63 | List newsList = portfolio.getNews(); 64 | 65 | random = new Random(); 66 | 67 | while (running) { 68 | 69 | Iterator i = stocksList.iterator(); 70 | while (i.hasNext()) { 71 | Stock stock = i.next(); 72 | simulateChange(stock); 73 | Message msg = createStockMessage(session, stock); 74 | msg.setStringProperty("symbol", stock.getSymbol()); 75 | quotesProducer.send(msg); 76 | try { 77 | Thread.sleep(500); 78 | } catch (InterruptedException e) { 79 | } 80 | } 81 | 82 | Iterator ii = newsList.iterator(); 83 | while (ii.hasNext()) { 84 | News news = ii.next(); 85 | Message msg = createNewsMessage(session, news); 86 | msg.setStringProperty("symbol", news.getSymbol()); 87 | newsProducer.send(msg); 88 | try { 89 | Thread.sleep(500); 90 | } catch (InterruptedException e) { 91 | } 92 | } 93 | } 94 | } catch (Exception ex) { 95 | System.out.println("Problem creating feed"); 96 | ex.printStackTrace(); 97 | } 98 | } 99 | 100 | private void simulateChange(Stock stock) { 101 | 102 | double maxChange = stock.getOpen() * 0.005; 103 | double change = maxChange - random.nextDouble() * maxChange * 2; 104 | stock.setChange(change); 105 | double last = stock.getLast() + change; 106 | 107 | if (last < stock.getOpen() + stock.getOpen() * 0.15 && last > stock.getOpen() - stock.getOpen() * 0.15) { 108 | stock.setLast(last); 109 | } else { 110 | stock.setLast(stock.getLast() - change); 111 | } 112 | 113 | if (stock.getLast() > stock.getHigh()) { 114 | stock.setHigh(stock.getLast()); 115 | } else if (stock.getLast() < stock.getLow()) { 116 | stock.setLow(stock.getLast()); 117 | } 118 | stock.setDate(new Date()); 119 | 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /web/src/main/webapp/js/stock-quote.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | 3 | var client, destinationQuotes; 4 | 5 | $('#connect_form').submit(function() { 6 | var url = $("#connect_url").val(); 7 | var login = $("#connect_login").val(); 8 | var passcode = $("#connect_passcode").val(); 9 | destinationQuotes = $("#destinationQuotes").val(); 10 | 11 | client = Stomp.client(url); 12 | 13 | // this allows to display debug logs directly on the web page 14 | client.debug = function(str) { 15 | $("#debug").append(str + "\n"); 16 | }; 17 | // the client is notified when it is connected to the server. 18 | var onconnect = function(frame) { 19 | client.debug("connected to Stomp"); 20 | $('#connect').fadeOut({ duration: 'fast' }); 21 | $('#disconnect').fadeIn(); 22 | $('#send_form_input').removeAttr('disabled'); 23 | 24 | var stockTable = document.getElementById("stockTable"); 25 | var stockRowIndexes = {}; 26 | 27 | client.subscribe(destinationQuotes, function(message) { 28 | var quote = JSON.parse(message.body); 29 | $('.' + "stock-" + quote.symbol).replaceWith("" + 30 | "" + quote.symbol + "" + 31 | "" + quote.open.toFixed(2) + "" + 32 | "" + quote.last.toFixed(2) + "" + 33 | "" + quote.change.toFixed(2) + "" + 34 | "" + quote.high.toFixed(2) + "" + 35 | "" + quote.low.toFixed(2) + "" + 36 | ""); 37 | 38 | // extract the stock data fields 39 | var symbol = quote.symbol; 40 | var open = quote.open.toFixed(2); 41 | var last = quote.last.toFixed(2); 42 | var high = quote.high.toFixed(2); 43 | var low = quote.low.toFixed(2); 44 | var newPrice = quote.change.toFixed(2); 45 | 46 | // lookup the table row 47 | var stockRowIndex = stockRowIndexes[symbol]; 48 | var stockRow = stockTable.rows[stockRowIndex]; 49 | 50 | // lazily populate the table row, with 6 cells 51 | if (stockRow === undefined) { 52 | var stockRowIndex = stockTable.rows.length; 53 | stockRow = stockTable.insertRow(stockRowIndex); 54 | for (var cell=0; cell < 7; cell++) { 55 | stockRow.insertCell(cell); 56 | } 57 | stockRow.cells[0].className = 'symbol'; 58 | stockRow.cells[1].className = 'open'; 59 | stockRow.cells[2].className = 'last'; 60 | stockRow.cells[3].className = 'change'; 61 | stockRow.cells[4].className = 'high'; 62 | stockRow.cells[5].className = 'low'; 63 | stockRow.cells[6].className = 'percent'; 64 | stockRowIndexes[symbol] = stockRowIndex; 65 | } 66 | 67 | 68 | // detect price change 69 | var oldPrice = Number(stockRow.cells[2].innerHTML); 70 | var oldChange = Number(stockRow.cells[3].innerHTML); 71 | var change = ((oldPrice != 0) ? (newPrice - oldPrice) : 0).toFixed(2); 72 | var percent = ((oldPrice != 0) ? (change / oldPrice * 100) : 0).toFixed(1); 73 | 74 | // update the table row cell data 75 | stockRow.cells[0].innerHTML = symbol; 76 | stockRow.cells[1].innerHTML = open; 77 | stockRow.cells[2].innerHTML = last; 78 | stockRow.cells[3].innerHTML = change; 79 | stockRow.cells[4].innerHTML = high; 80 | stockRow.cells[5].innerHTML = low; 81 | stockRow.cells[6].innerHTML = percent; 82 | 83 | // update the table row cell styles 84 | var oldSign = (oldChange != 0) ? oldChange / Math.abs(oldChange) : 0; 85 | var sign = (change != 0) ? change / Math.abs(change) : 0; 86 | if (sign != oldSign) { 87 | switch (sign) { 88 | case 1: 89 | stockRow.cells[3].className = 'upChange'; 90 | stockRow.cells[4].className = 'upPercent'; 91 | break; 92 | case -1: 93 | stockRow.cells[3].className = 'downChange'; 94 | stockRow.cells[4].className = 'downPercent'; 95 | break; 96 | } 97 | } 98 | 99 | 100 | }); 101 | 102 | }; 103 | client.connect(login, passcode, onconnect); 104 | 105 | return false; 106 | }); 107 | 108 | $('#disconnect_form').submit(function() { 109 | client.disconnect(function() { 110 | $('#disconnect').fadeOut({ duration: 'fast' }); 111 | $('#connect').fadeIn(); 112 | $('#send_form_input').addAttr('disabled'); 113 | }); 114 | return false; 115 | }); 116 | 117 | $('#send_form').submit(function() { 118 | var text = $('#send_form_input').val(); 119 | if (text) { 120 | client.send(destination, {foo: 1}, text); 121 | $('#send_form_input').val(""); 122 | } 123 | return false; 124 | }); 125 | 126 | }); 127 | -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/js/stock-quote.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | 3 | var client, destinationQuotes; 4 | 5 | $('#connect_form').submit(function() { 6 | var url = $("#connect_url").val(); 7 | var login = $("#connect_login").val(); 8 | var passcode = $("#connect_passcode").val(); 9 | destinationQuotes = $("#destinationQuotes").val(); 10 | 11 | client = Stomp.client(url); 12 | 13 | // this allows to display debug logs directly on the web page 14 | client.debug = function(str) { 15 | $("#debug").append(str + "\n"); 16 | }; 17 | // the client is notified when it is connected to the server. 18 | var onconnect = function(frame) { 19 | client.debug("connected to Stomp"); 20 | $('#connect').fadeOut({ duration: 'fast' }); 21 | $('#disconnect').fadeIn(); 22 | $('#send_form_input').removeAttr('disabled'); 23 | 24 | var stockTable = document.getElementById("stockTable"); 25 | var stockRowIndexes = {}; 26 | 27 | client.subscribe(destinationQuotes, function(message) { 28 | var quote = JSON.parse(message.body); 29 | $('.' + "stock-" + quote.symbol).replaceWith("" + 30 | "" + quote.symbol + "" + 31 | "" + quote.open.toFixed(2) + "" + 32 | "" + quote.last.toFixed(2) + "" + 33 | "" + quote.change.toFixed(2) + "" + 34 | "" + quote.high.toFixed(2) + "" + 35 | "" + quote.low.toFixed(2) + "" + 36 | ""); 37 | 38 | // extract the stock data fields 39 | var symbol = quote.symbol; 40 | var open = quote.open.toFixed(2); 41 | var last = quote.last.toFixed(2); 42 | var high = quote.high.toFixed(2); 43 | var low = quote.low.toFixed(2); 44 | var newPrice = quote.change.toFixed(2); 45 | 46 | // lookup the table row 47 | var stockRowIndex = stockRowIndexes[symbol]; 48 | var stockRow = stockTable.rows[stockRowIndex]; 49 | 50 | // lazily populate the table row, with 6 cells 51 | if (stockRow === undefined) { 52 | var stockRowIndex = stockTable.rows.length; 53 | stockRow = stockTable.insertRow(stockRowIndex); 54 | for (var cell=0; cell < 7; cell++) { 55 | stockRow.insertCell(cell); 56 | } 57 | stockRow.cells[0].className = 'symbol'; 58 | stockRow.cells[1].className = 'open'; 59 | stockRow.cells[2].className = 'last'; 60 | stockRow.cells[3].className = 'change'; 61 | stockRow.cells[4].className = 'high'; 62 | stockRow.cells[5].className = 'low'; 63 | stockRow.cells[6].className = 'percent'; 64 | stockRowIndexes[symbol] = stockRowIndex; 65 | } 66 | 67 | 68 | // detect price change 69 | var oldPrice = Number(stockRow.cells[2].innerHTML); 70 | var oldChange = Number(stockRow.cells[3].innerHTML); 71 | var change = ((oldPrice != 0) ? (newPrice - oldPrice) : 0).toFixed(2); 72 | var percent = ((oldPrice != 0) ? (change / oldPrice * 100) : 0).toFixed(1); 73 | 74 | // update the table row cell data 75 | stockRow.cells[0].innerHTML = symbol; 76 | stockRow.cells[1].innerHTML = open; 77 | stockRow.cells[2].innerHTML = last; 78 | stockRow.cells[3].innerHTML = change; 79 | stockRow.cells[4].innerHTML = high; 80 | stockRow.cells[5].innerHTML = low; 81 | stockRow.cells[6].innerHTML = percent; 82 | 83 | // update the table row cell styles 84 | var oldSign = (oldChange != 0) ? oldChange / Math.abs(oldChange) : 0; 85 | var sign = (change != 0) ? change / Math.abs(change) : 0; 86 | if (sign != oldSign) { 87 | switch (sign) { 88 | case 1: 89 | stockRow.cells[3].className = 'upChange'; 90 | stockRow.cells[4].className = 'upPercent'; 91 | break; 92 | case -1: 93 | stockRow.cells[3].className = 'downChange'; 94 | stockRow.cells[4].className = 'downPercent'; 95 | break; 96 | } 97 | } 98 | 99 | 100 | }); 101 | 102 | }; 103 | client.connect(login, passcode, onconnect); 104 | 105 | return false; 106 | }); 107 | 108 | $('#disconnect_form').submit(function() { 109 | client.disconnect(function() { 110 | $('#disconnect').fadeOut({ duration: 'fast' }); 111 | $('#connect').fadeIn(); 112 | $('#send_form_input').addAttr('disabled'); 113 | }); 114 | return false; 115 | }); 116 | 117 | $('#send_form').submit(function() { 118 | var text = $('#send_form_input').val(); 119 | if (text) { 120 | client.send(destination, {foo: 1}, text); 121 | $('#send_form_input').val(""); 122 | } 123 | return false; 124 | }); 125 | 126 | }); 127 | -------------------------------------------------------------------------------- /web/src/main/webapp/css/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | padding: 10px; 8 | } 9 | 10 | p, h1, h2, h3, th, td, a { 11 | font-family: Arial, sans-serif; 12 | font-size: 11px; 13 | } 14 | 15 | div.main { 16 | background: #66a3c2; 17 | border: 1px solid #aeb3b6; 18 | padding: 15px; 19 | float: left; 20 | position: fixed; 21 | z-index: 99999; 22 | /*--CSS3 Rounded Corners--*/ 23 | -webkit-border-radius: 10px; 24 | -moz-border-radius: 10px; 25 | border-radius: 10px; 26 | width: 400px; 27 | height: 800px; 28 | 29 | } 30 | 31 | table { 32 | font-family: Arial, sans-serif; 33 | width: 100%; 34 | background: #fff; 35 | text-align: left; 36 | border-spacing: 0px; 37 | border: 1px solid #aeb3b6; 38 | border-collapse: collapse; 39 | /*--CSS3 Box Shadows--*/ 40 | -webkit-box-shadow: 0px 3px 7px #000; 41 | -moz-box-shadow: 0px 3px 7px #000; 42 | box-shadow: 0px 3px 7px #000; 43 | 44 | } 45 | 46 | .feedTitle { 47 | font-size: 15px; 48 | text-align: center; 49 | vertical-align: middle; 50 | } 51 | 52 | th { 53 | border-left: 1px solid #aeb3b6; 54 | border-right: 1px solid #aeb3b6; 55 | background-color: #dbdbdb; 56 | text-align: right; 57 | height: 10px; 58 | vertical-align: center; 59 | padding: 5px 5px; 60 | } 61 | 62 | td { 63 | border-left: 1px solid #aeb3b6; 64 | border-right: 1px solid #aeb3b6; 65 | padding: 10px 10px; 66 | text-align: right; 67 | height: 10px; 68 | vertical-align: center; 69 | padding: 5px 5px; 70 | } 71 | 72 | td.green { 73 | color: green; 74 | } 75 | 76 | .stockTable { 77 | font-size: 14px; 78 | border-color: #44687d; 79 | border-bottom-width: 1px solid; 80 | } 81 | 82 | .stockTable th { 83 | color: #ffffff; 84 | background-color: #ff5113; 85 | border-color: #cccccc; 86 | border-width: 0px 1px 1px 0px; 87 | border-style: solid; 88 | padding-bottom: 3px; 89 | } 90 | 91 | .stockTable tr td { 92 | height: 22px; 93 | border-color: #cccccc; 94 | border-width: 0px 0px 1px 0px; 95 | border-style: solid; 96 | } 97 | 98 | .news { 99 | width: 1000px; 100 | height: 100px; 101 | overflow: hidden; 102 | border: 1px solid #DDD; 103 | margin: 0; 104 | padding: 0; 105 | list-style: none; 106 | border-radius: 5px; 107 | box-shadow: 0px 0px 5px #DDD; 108 | } 109 | 110 | .news li { 111 | font-size: 15px; 112 | height: 30px; 113 | border-bottom: 1px dotted #DDD; 114 | padding: 5px; 115 | margin: 0px 5px; 116 | } 117 | 118 | #news { 119 | height: 300px; 120 | } 121 | 122 | #news li { 123 | height: 80px; 124 | overflow: hidden; 125 | } 126 | 127 | 128 | #newsList { display: none;} 129 | 130 | .tweet { 131 | width: 1000px; 132 | height: 50px; 133 | overflow: hidden; 134 | border: 1px solid #DDD; 135 | margin: 0; 136 | padding: 0; 137 | list-style: none; 138 | border-radius: 5px; 139 | box-shadow: 0px 0px 5px #DDD; 140 | } 141 | 142 | .tweet li { 143 | font-size: 15px; 144 | height: 30px; 145 | border-bottom: 1px dotted #DDD; 146 | padding: 5px; 147 | margin: 0px 5px; 148 | } 149 | 150 | #tweet { 151 | height: 300px; 152 | } 153 | 154 | #tweet li { 155 | height: 40px; 156 | overflow: hidden; 157 | } 158 | 159 | #tweetList { display: none;} 160 | 161 | #rss { 162 | height: 300px; 163 | } 164 | 165 | #rss li { 166 | height: 80px; 167 | overflow: hidden; 168 | } 169 | 170 | #rssList { display: none;} 171 | 172 | 173 | .newsTable { 174 | font-size: 14px; 175 | border-color: #44687d; 176 | border-bottom-width: 1px solid; 177 | } 178 | 179 | .newsTable th { 180 | color: #ffffff; 181 | background-color: #ff5113; 182 | border-color: #cccccc; 183 | border-width: 0px 1px 1px 0px; 184 | border-style: solid; 185 | padding-bottom: 3px; 186 | } 187 | 188 | .newsTable tr td { 189 | height: 22px; 190 | border-color: #cccccc; 191 | border-width: 0px 0px 1px 0px; 192 | border-style: solid; 193 | } 194 | 195 | .symbol { 196 | text-align: left; 197 | padding-left: 10px; 198 | } 199 | 200 | .title { 201 | text-align: left; 202 | padding-left: 5px; 203 | } 204 | 205 | .info { 206 | text-align: left; 207 | padding-left: 5px; 208 | } 209 | 210 | .open { 211 | text-align: left; 212 | padding-left: 10px; 213 | } 214 | 215 | .last { 216 | text-align: right; 217 | padding-right: 10px; 218 | } 219 | 220 | .change { 221 | text-align: right; 222 | padding-right: 10px; 223 | } 224 | 225 | .high { 226 | text-align: right; 227 | padding-right: 10px; 228 | } 229 | 230 | .low { 231 | text-align: right; 232 | padding-right: 10px; 233 | } 234 | 235 | .percent { 236 | text-align: right; 237 | font-weight: bold; 238 | padding-right: 20px; 239 | } 240 | 241 | .upChange { 242 | background: url(/images/stock_index_up.jpg) center left no-repeat; 243 | background-size: 10px; 244 | position: relative; 245 | font-weight: bold; 246 | color: green; 247 | text-align: right; 248 | padding-right: 10px; 249 | } 250 | 251 | .downChange { 252 | background: url(/images/stock_index_down.jpg) center left no-repeat; 253 | background-size: 10px; 254 | position: relative; 255 | font-weight: bold; 256 | color: red; 257 | text-align: right; 258 | padding-right: 10px; 259 | } 260 | 261 | .upPercent { 262 | font-weight: bold; 263 | color: green; 264 | text-align: right; 265 | padding-right: 10px; 266 | } 267 | 268 | .downPercent { 269 | font-weight: bold; 270 | color: red; 271 | text-align: right; 272 | padding-right: 10px; 273 | } 274 | -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/css/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | padding: 10px; 8 | } 9 | 10 | p, h1, h2, h3, th, td, a { 11 | font-family: Arial, sans-serif; 12 | font-size: 11px; 13 | } 14 | 15 | div.main { 16 | background: #66a3c2; 17 | border: 1px solid #aeb3b6; 18 | padding: 15px; 19 | float: left; 20 | position: fixed; 21 | z-index: 99999; 22 | /*--CSS3 Rounded Corners--*/ 23 | -webkit-border-radius: 10px; 24 | -moz-border-radius: 10px; 25 | border-radius: 10px; 26 | width: 400px; 27 | height: 800px; 28 | 29 | } 30 | 31 | table { 32 | font-family: Arial, sans-serif; 33 | width: 100%; 34 | background: #fff; 35 | text-align: left; 36 | border-spacing: 0px; 37 | border: 1px solid #aeb3b6; 38 | border-collapse: collapse; 39 | /*--CSS3 Box Shadows--*/ 40 | -webkit-box-shadow: 0px 3px 7px #000; 41 | -moz-box-shadow: 0px 3px 7px #000; 42 | box-shadow: 0px 3px 7px #000; 43 | 44 | } 45 | 46 | .feedTitle { 47 | font-size: 15px; 48 | text-align: center; 49 | vertical-align: middle; 50 | } 51 | 52 | th { 53 | border-left: 1px solid #aeb3b6; 54 | border-right: 1px solid #aeb3b6; 55 | background-color: #dbdbdb; 56 | text-align: right; 57 | height: 10px; 58 | vertical-align: center; 59 | padding: 5px 5px; 60 | } 61 | 62 | td { 63 | border-left: 1px solid #aeb3b6; 64 | border-right: 1px solid #aeb3b6; 65 | padding: 10px 10px; 66 | text-align: right; 67 | height: 10px; 68 | vertical-align: center; 69 | padding: 5px 5px; 70 | } 71 | 72 | td.green { 73 | color: green; 74 | } 75 | 76 | .stockTable { 77 | font-size: 14px; 78 | border-color: #44687d; 79 | border-bottom-width: 1px solid; 80 | } 81 | 82 | .stockTable th { 83 | color: #ffffff; 84 | background-color: #ff5113; 85 | border-color: #cccccc; 86 | border-width: 0px 1px 1px 0px; 87 | border-style: solid; 88 | padding-bottom: 3px; 89 | } 90 | 91 | .stockTable tr td { 92 | height: 22px; 93 | border-color: #cccccc; 94 | border-width: 0px 0px 1px 0px; 95 | border-style: solid; 96 | } 97 | 98 | .news { 99 | width: 1000px; 100 | height: 100px; 101 | overflow: hidden; 102 | border: 1px solid #DDD; 103 | margin: 0; 104 | padding: 0; 105 | list-style: none; 106 | border-radius: 5px; 107 | box-shadow: 0px 0px 5px #DDD; 108 | } 109 | 110 | .news li { 111 | font-size: 15px; 112 | height: 30px; 113 | border-bottom: 1px dotted #DDD; 114 | padding: 5px; 115 | margin: 0px 5px; 116 | } 117 | 118 | #news { 119 | height: 300px; 120 | } 121 | 122 | #news li { 123 | height: 80px; 124 | overflow: hidden; 125 | } 126 | 127 | 128 | #newsList { display: none;} 129 | 130 | .tweet { 131 | width: 1000px; 132 | height: 50px; 133 | overflow: hidden; 134 | border: 1px solid #DDD; 135 | margin: 0; 136 | padding: 0; 137 | list-style: none; 138 | border-radius: 5px; 139 | box-shadow: 0px 0px 5px #DDD; 140 | } 141 | 142 | .tweet li { 143 | font-size: 15px; 144 | height: 30px; 145 | border-bottom: 1px dotted #DDD; 146 | padding: 5px; 147 | margin: 0px 5px; 148 | } 149 | 150 | #tweet { 151 | height: 300px; 152 | } 153 | 154 | #tweet li { 155 | height: 40px; 156 | overflow: hidden; 157 | } 158 | 159 | #tweetList { display: none;} 160 | 161 | #rss { 162 | height: 300px; 163 | } 164 | 165 | #rss li { 166 | height: 80px; 167 | overflow: hidden; 168 | } 169 | 170 | #rssList { display: none;} 171 | 172 | 173 | .newsTable { 174 | font-size: 14px; 175 | border-color: #44687d; 176 | border-bottom-width: 1px solid; 177 | } 178 | 179 | .newsTable th { 180 | color: #ffffff; 181 | background-color: #ff5113; 182 | border-color: #cccccc; 183 | border-width: 0px 1px 1px 0px; 184 | border-style: solid; 185 | padding-bottom: 3px; 186 | } 187 | 188 | .newsTable tr td { 189 | height: 22px; 190 | border-color: #cccccc; 191 | border-width: 0px 0px 1px 0px; 192 | border-style: solid; 193 | } 194 | 195 | .symbol { 196 | text-align: left; 197 | padding-left: 10px; 198 | } 199 | 200 | .title { 201 | text-align: left; 202 | padding-left: 5px; 203 | } 204 | 205 | .info { 206 | text-align: left; 207 | padding-left: 5px; 208 | } 209 | 210 | .open { 211 | text-align: left; 212 | padding-left: 10px; 213 | } 214 | 215 | .last { 216 | text-align: right; 217 | padding-right: 10px; 218 | } 219 | 220 | .change { 221 | text-align: right; 222 | padding-right: 10px; 223 | } 224 | 225 | .high { 226 | text-align: right; 227 | padding-right: 10px; 228 | } 229 | 230 | .low { 231 | text-align: right; 232 | padding-right: 10px; 233 | } 234 | 235 | .percent { 236 | text-align: right; 237 | font-weight: bold; 238 | padding-right: 20px; 239 | } 240 | 241 | .upChange { 242 | background: url(/images/stock_index_up.jpg) center left no-repeat; 243 | background-size: 10px; 244 | position: relative; 245 | font-weight: bold; 246 | color: green; 247 | text-align: right; 248 | padding-right: 10px; 249 | } 250 | 251 | .downChange { 252 | background: url(/images/stock_index_down.jpg) center left no-repeat; 253 | background-size: 10px; 254 | position: relative; 255 | font-weight: bold; 256 | color: red; 257 | text-align: right; 258 | padding-right: 10px; 259 | } 260 | 261 | .upPercent { 262 | font-weight: bold; 263 | color: green; 264 | text-align: right; 265 | padding-right: 10px; 266 | } 267 | 268 | .downPercent { 269 | font-weight: bold; 270 | color: red; 271 | text-align: right; 272 | padding-right: 10px; 273 | } 274 | -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/css/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | padding: 10px; 8 | } 9 | 10 | p, h1, h2, h3, th, td, a { 11 | font-family: Arial, sans-serif; 12 | font-size: 11px; 13 | } 14 | 15 | div.main { 16 | background: #66a3c2; 17 | border: 1px solid #aeb3b6; 18 | padding: 15px; 19 | float: left; 20 | position: fixed; 21 | z-index: 99999; 22 | /*--CSS3 Rounded Corners--*/ 23 | -webkit-border-radius: 10px; 24 | -moz-border-radius: 10px; 25 | border-radius: 10px; 26 | width: 400px; 27 | height: 800px; 28 | 29 | } 30 | 31 | table { 32 | font-family: Arial, sans-serif; 33 | width: 100%; 34 | background: #fff; 35 | text-align: left; 36 | border-spacing: 0px; 37 | border: 1px solid #aeb3b6; 38 | border-collapse: collapse; 39 | /*--CSS3 Box Shadows--*/ 40 | -webkit-box-shadow: 0px 3px 7px #000; 41 | -moz-box-shadow: 0px 3px 7px #000; 42 | box-shadow: 0px 3px 7px #000; 43 | 44 | } 45 | 46 | .feedTitle { 47 | font-size: 15px; 48 | text-align: center; 49 | vertical-align: middle; 50 | } 51 | 52 | th { 53 | border-left: 1px solid #aeb3b6; 54 | border-right: 1px solid #aeb3b6; 55 | background-color: #dbdbdb; 56 | text-align: right; 57 | height: 10px; 58 | vertical-align: center; 59 | padding: 5px 5px; 60 | } 61 | 62 | td { 63 | border-left: 1px solid #aeb3b6; 64 | border-right: 1px solid #aeb3b6; 65 | padding: 10px 10px; 66 | text-align: right; 67 | height: 10px; 68 | vertical-align: center; 69 | padding: 5px 5px; 70 | } 71 | 72 | td.green { 73 | color: green; 74 | } 75 | 76 | .stockTable { 77 | font-size: 14px; 78 | border-color: #44687d; 79 | border-bottom-width: 1px solid; 80 | } 81 | 82 | .stockTable th { 83 | color: #ffffff; 84 | background-color: #ff5113; 85 | border-color: #cccccc; 86 | border-width: 0px 1px 1px 0px; 87 | border-style: solid; 88 | padding-bottom: 3px; 89 | } 90 | 91 | .stockTable tr td { 92 | height: 22px; 93 | border-color: #cccccc; 94 | border-width: 0px 0px 1px 0px; 95 | border-style: solid; 96 | } 97 | 98 | .news { 99 | width: 1000px; 100 | height: 100px; 101 | overflow: hidden; 102 | border: 1px solid #DDD; 103 | margin: 0; 104 | padding: 0; 105 | list-style: none; 106 | border-radius: 5px; 107 | box-shadow: 0px 0px 5px #DDD; 108 | } 109 | 110 | .news li { 111 | font-size: 15px; 112 | height: 30px; 113 | border-bottom: 1px dotted #DDD; 114 | padding: 5px; 115 | margin: 0px 5px; 116 | } 117 | 118 | #news { 119 | height: 300px; 120 | } 121 | 122 | #news li { 123 | height: 80px; 124 | overflow: hidden; 125 | } 126 | 127 | 128 | #newsList { display: none;} 129 | 130 | .tweet { 131 | width: 1000px; 132 | height: 50px; 133 | overflow: hidden; 134 | border: 1px solid #DDD; 135 | margin: 0; 136 | padding: 0; 137 | list-style: none; 138 | border-radius: 5px; 139 | box-shadow: 0px 0px 5px #DDD; 140 | } 141 | 142 | .tweet li { 143 | font-size: 15px; 144 | height: 30px; 145 | border-bottom: 1px dotted #DDD; 146 | padding: 5px; 147 | margin: 0px 5px; 148 | } 149 | 150 | #tweet { 151 | height: 300px; 152 | } 153 | 154 | #tweet li { 155 | height: 40px; 156 | overflow: hidden; 157 | } 158 | 159 | #tweetList { display: none;} 160 | 161 | #rss { 162 | height: 300px; 163 | } 164 | 165 | #rss li { 166 | height: 80px; 167 | overflow: hidden; 168 | } 169 | 170 | #rssList { display: none;} 171 | 172 | 173 | .newsTable { 174 | font-size: 14px; 175 | border-color: #44687d; 176 | border-bottom-width: 1px solid; 177 | } 178 | 179 | .newsTable th { 180 | color: #ffffff; 181 | background-color: #ff5113; 182 | border-color: #cccccc; 183 | border-width: 0px 1px 1px 0px; 184 | border-style: solid; 185 | padding-bottom: 3px; 186 | } 187 | 188 | .newsTable tr td { 189 | height: 22px; 190 | border-color: #cccccc; 191 | border-width: 0px 0px 1px 0px; 192 | border-style: solid; 193 | } 194 | 195 | .symbol { 196 | text-align: left; 197 | padding-left: 10px; 198 | } 199 | 200 | .title { 201 | text-align: left; 202 | padding-left: 5px; 203 | } 204 | 205 | .info { 206 | text-align: left; 207 | padding-left: 5px; 208 | } 209 | 210 | .open { 211 | text-align: left; 212 | padding-left: 10px; 213 | } 214 | 215 | .last { 216 | text-align: right; 217 | padding-right: 10px; 218 | } 219 | 220 | .change { 221 | text-align: right; 222 | padding-right: 10px; 223 | } 224 | 225 | .high { 226 | text-align: right; 227 | padding-right: 10px; 228 | } 229 | 230 | .low { 231 | text-align: right; 232 | padding-right: 10px; 233 | } 234 | 235 | .percent { 236 | text-align: right; 237 | font-weight: bold; 238 | padding-right: 20px; 239 | } 240 | 241 | .upChange { 242 | background: url(/webapp/images/stock_index_up.jpg) center left no-repeat; 243 | background-size: 10px; 244 | position: relative; 245 | font-weight: bold; 246 | color: green; 247 | text-align: right; 248 | padding-right: 10px; 249 | } 250 | 251 | .downChange { 252 | background: url(/webapp/images/stock_index_down.jpg) center left no-repeat; 253 | background-size: 10px; 254 | position: relative; 255 | font-weight: bold; 256 | color: red; 257 | text-align: right; 258 | padding-right: 10px; 259 | } 260 | 261 | .upPercent { 262 | font-weight: bold; 263 | color: green; 264 | text-align: right; 265 | padding-right: 10px; 266 | } 267 | 268 | .downPercent { 269 | font-weight: bold; 270 | color: red; 271 | text-align: right; 272 | padding-right: 10px; 273 | } 274 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | NOTE: This project is not supported on JBoss Fuse version 6.3 or later 2 | ----------------------------------------------------------------------- 3 | 4 | # Example showing How to use WebSocket HTML 5 with ActiveMQ and Camel 5 | 6 | ## ActiveMQ 7 | 8 | 1) Download ActiveMQ 5.9 from this location 9 | http://repo.fusesource.com/nexus/content/repositories/releases/org/apache/activemq/apache-activemq/5.9.0.redhat-610312/ 10 | 11 | or using Apache Release 12 | 13 | http://repo1.maven.org/maven2/org/apache/activemq/apache-activemq/5.9.0/ 14 | 15 | 2) start Jetty Web Server 16 | 17 | cd websocket-activemq-camel/web 18 | mvn jetty:run 19 | 20 | 3) Start ActiveMQ 5.x using the config provided in feeder/src/main/config directory 21 | 22 | cd ~/fuse/servers/apache-activemq-5.x/bin 23 | ./activemq console xbean:file:~/Fuse/fuse-by-examples/websocket-activemq-camel/feeder/src/main/config/activemq-websocket.xml 24 | 25 | 4) Compile and start Feed application 26 | 27 | cd websocket-activemq-camel/feed 28 | mvn -P run-trader 29 | 30 | 5) Open your web browser at this address 31 | 32 | http://localhost:8282/stocks-activemq.html 33 | 34 | and click on connect button 35 | 36 | Remark : To connect from the web page to the ActiveMQ broker, the login to be used is guest & password is password 37 | 38 | ## Camel 39 | 40 | 1) Start Apache Camel Routes (without using wss://) 41 | 42 | cd websocket-activemq-camel/camel-ws 43 | mvn camel:run 44 | 45 | 2) Compile and Start Feed application 46 | 47 | cd websocket-activemq-camel/feed 48 | mvn -P run-trader 49 | 50 | 3) Verify stock and news websockets in your browser 51 | 52 | http://localhost:9090/stocks-camel.html 53 | http://localhost:9090/news-camel.html 54 | 55 | and click on connect button 56 | 57 | To test SSL & wss:// protocol, execute the follownig command 58 | 59 | 1) Start Apache Camel Routes (with wss:// & HTTPS) 60 | 61 | cd websocket-activemq-camel/camel-ws-ssl 62 | mvn camel:run 63 | 64 | 2) Compile and Start Feed application 65 | 66 | cd websocket-activemq-camel/feed 67 | mvn -P run-trader 68 | 69 | 3) Verify stock and news websockets in your browser 70 | 71 | https://localhost:8443/news-camel-wss.html 72 | 73 | and click on connect button 74 | 75 | 76 | ## JBoss A-MQ 77 | 78 | 1) Download JBoss A-MQ (https://access.redhat.com/downloads/) and unzip/untar the project locally 79 | 80 | 2) Copy ActiveMQ config file containing ActiveMQ WebSocket transports connectors 81 | 82 | cp ~/Fuse/fuse-by-examples/websocket-activemq-camel/feeder/src/main/config/fuseamq-websocket.xml ~/Fuse/servers/jboss-a-mq-6.1.0.redhat-312/etc/activemq.xml 83 | 84 | OR 85 | 86 | cp ~/Fuse/fuse-by-examples/websocket-activemq-camel/feeder/src/main/config/org.fusesource.mq.fabric.server-default.cfg ~/Fuse/servers/jboss-a-mq-6.1.0.redhat-312/etc 87 | cp ~/Fuse/fuse-by-examples/websocket-activemq-camel/feeder/src/main/config/fuseamq-websocket.xml ~/Fuse/servers/jboss-a-mq-6.1.0.redhat-312/etc/ 88 | 89 | 3)) Add user guest and password password into the file etc/users.properties 90 | guest=password,admin 91 | 92 | cp /Users/chmoulli/Fuse/fuse-by-examples/websocket-activemq-camel/feeder/src/main/config/users.properties ~/Fuse/servers/jboss-a-mq-6.1.0.redhat-312/etc 93 | 94 | 4) Start JBoss A-MQ and install the web project 95 | 96 | install -s webbundle:mvn:com.fusesource.examples.websocket/web/1.0/war?Web-ContextPath=/activemq-websocket 97 | 98 | 5) Connect to the web site http://localhost:8181/activemq-websocket/stocks-activemq.html 99 | 100 | ## JBoss Fuse 101 | 102 | ! Twitter Demo does not work with current Camel 2.10 release as Twitter API 1.0 has been retired 103 | ! Camel 2.11 is required 104 | 105 | 1) Download JBoss Fuse (https://access.redhat.com/downloads/) and unzip/untar the project locally 106 | 107 | 2) Install features & bundles 108 | 109 | Remark : bug discovered with websocket & static resources (https://issues.apache.org/jira/browse/CAMEL-6432) + ssl (https://issues.apache.org/jira/browse/CAMEL-6433) 110 | 111 | First, install the XML resources file containing the definition about the modules to be deployed. This features file contains for each module (= a feature), the bundles, configurationss and parameters of the applications to be deployed and also references to others features/modules like `camel`, `camel-twitter` ... 112 | 113 | features:addurl mvn:com.fusesource.examples.websocket/features/1.0/xml/features 114 | features:install websocket-demo 115 | 116 | The project can also be installed without using the features file created for this project but, in this case, using what is provisioned out of the box on JBoss Fuse platform. 117 | 118 | features:install camel 119 | features:install camel-websocket 120 | features:install camel-twitter 121 | features:install activemq-camel 122 | install -s mvn:com.fusesource.examples.activemq.websocket/camel-ws/1.0 123 | 124 | 3) Compile and Start Feed application 125 | 126 | cd websocket-activemq-camel/feed 127 | mvn -P run-trader 128 | 129 | 3) Connect to the web site using these addresses : 130 | 131 | http://localhost:9090/news-camel.html 132 | http://localhost:9090/stocks-camel.html 133 | http://localhost:9090/chat-camel.html 134 | 135 | 136 | ## Apache Karaf 137 | 138 | 1) Download Apache Karaf (http://karaf.apache.org/index/community/download.html) and unzip/untar the project locally 139 | 140 | 2) Install features & bundles 141 | 142 | features:addurl mvn:com.fusesource.examples.websocket/features/1.0/xml/features 143 | features:install websocket-demo 144 | 145 | 3) Compile and Start Feed application 146 | 147 | cd websocket-activemq-camel/feed 148 | mvn -P run-trader 149 | 150 | 3) Connect to the web site using these addresses : 151 | 152 | http://localhost:9090/news-camel.html 153 | http://localhost:9090/stocks-camel.html 154 | http://localhost:9090/chat-camel.html 155 | -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/chat-camel.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Camel Chat WebSocket 6 | 88 | 134 | 135 | 136 |
    137 |
    138 |
    139 | Username:  140 | 141 | 142 |
    143 | 148 |
    149 | 179 | 180 |

    181 | This is a CamelOne Demo of the camel-websocket component. 182 |

    183 | 184 | -------------------------------------------------------------------------------- /camel-ws-ssl/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 22 | 23 | project 24 | com.fusesource.examples.activemq.websocket 25 | 1.0 26 | 27 | 28 | 4.0.0 29 | 30 | com.fusesource.examples.websocket 31 | camel-ws-ssl 32 | jar 33 | FuseSource :: WebSocket SSL :: Camel 34 | 35 | 36 | 37 | org.apache.camel 38 | camel-core 39 | ${camel.version} 40 | 41 | 42 | org.apache.camel 43 | camel-spring 44 | ${camel.version} 45 | 46 | 47 | org.apache.camel 48 | camel-websocket 49 | ${camel.version} 50 | 51 | 52 | org.apache.camel 53 | camel-jms 54 | ${camel.version} 55 | 56 | 57 | org.apache.camel 58 | camel-jackson 59 | ${camel.version} 60 | 61 | 62 | org.apache.camel 63 | camel-twitter 64 | ${camel.version} 65 | 66 | 67 | org.codehaus.jackson 68 | jackson-mapper-asl 69 | 1.9.5 70 | 71 | 72 | org.json 73 | json 74 | 20090211 75 | 76 | 77 | 78 | org.apache.activemq 79 | activemq-all 80 | ${activemq.version} 81 | 82 | 83 | org.apache.xbean 84 | xbean-spring 85 | 3.5 86 | 87 | 88 | org.apache.activemq 89 | activemq-camel 90 | ${activemq.version} 91 | 92 | 93 | 94 | org.apache.camel 95 | camel-test 96 | ${camel.version} 97 | test 98 | 99 | 100 | 101 | org.slf4j 102 | slf4j-api 103 | 1.6.1 104 | 105 | 106 | org.slf4j 107 | slf4j-log4j12 108 | 1.6.1 109 | 110 | 111 | log4j 112 | log4j 113 | 1.2.16 114 | 115 | 116 | 117 | 118 | install 119 | 120 | 121 | 122 | org.apache.maven.plugins 123 | maven-compiler-plugin 124 | 2.3.2 125 | 126 | 1.6 127 | 1.6 128 | 129 | 130 | 131 | 132 | org.codehaus.mojo 133 | exec-maven-plugin 134 | 1.2 135 | 136 | com.fusesource.examples.camel.websocket.CamelWebSocketMain 137 | false 138 | 139 | 140 | 141 | 142 | org.apache.camel 143 | camel-maven-plugin 144 | ${camel.version} 145 | 146 | 147 | spring/broker-camel.xml 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | bundle 156 | 157 | 158 | 159 | src/main/resources 160 | true 161 | 162 | spring/*.xml 163 | 164 | 165 | 166 | 167 | 168 | maven-jar-plugin 169 | 170 | 171 | ${project.build.outputDirectory}/META-INF/MANIFEST.MF 172 | 173 | 174 | 175 | 176 | org.apache.felix 177 | maven-bundle-plugin 178 | 2.3.7 179 | 180 | 181 | bundle-manifest 182 | process-classes 183 | 184 | manifest 185 | 186 | 187 | 188 | 189 | 190 | jar 191 | 192 | 193 | ${project.artifactId} 194 | ${project.name} 195 | ${project.version} 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /camel-ws/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 22 | 23 | project 24 | com.fusesource.examples.activemq.websocket 25 | 1.0 26 | 27 | 28 | 4.0.0 29 | 30 | com.fusesource.examples.websocket 31 | camel-ws 32 | jar 33 | FuseSource :: WebSocket :: Camel 34 | 35 | 36 | 37 | org.apache.camel 38 | camel-core 39 | ${camel.version} 40 | 41 | 42 | org.apache.camel 43 | camel-spring 44 | ${camel.version} 45 | 46 | 47 | org.apache.camel 48 | camel-websocket 49 | ${camel.version} 50 | 51 | 52 | org.apache.camel 53 | camel-jms 54 | ${camel.version} 55 | 56 | 57 | org.apache.camel 58 | camel-jackson 59 | ${camel.version} 60 | 61 | 62 | org.apache.camel 63 | camel-twitter 64 | ${camel.version} 65 | 66 | 67 | org.codehaus.jackson 68 | jackson-mapper-asl 69 | 1.9.5 70 | 71 | 72 | org.json 73 | json 74 | 20090211 75 | 76 | 77 | 78 | 79 | org.apache.activemq 80 | activemq-all 81 | ${activemq.version} 82 | 83 | 84 | org.slf4j 85 | slf4j-api 86 | 87 | 88 | 89 | 90 | org.apache.xbean 91 | xbean-spring 92 | 3.5 93 | 94 | 95 | org.apache.activemq 96 | activemq-camel 97 | ${activemq.version} 98 | 99 | 100 | 101 | 102 | org.twitter4j 103 | twitter4j-core 104 | 3.0.1 105 | 106 | 107 | 108 | 109 | org.apache.camel 110 | camel-test 111 | ${camel.version} 112 | test 113 | 114 | 115 | 116 | org.slf4j 117 | slf4j-api 118 | 1.6.1 119 | 120 | 121 | org.slf4j 122 | slf4j-log4j12 123 | 1.6.1 124 | 125 | 126 | log4j 127 | log4j 128 | 1.2.16 129 | 130 | 131 | 132 | 133 | install 134 | 135 | 136 | 137 | org.apache.maven.plugins 138 | maven-compiler-plugin 139 | 2.3.2 140 | 141 | 1.6 142 | 1.6 143 | 144 | 145 | 146 | 147 | org.codehaus.mojo 148 | exec-maven-plugin 149 | 1.2.1 150 | 151 | com.fusesource.examples.camel.websocket.SearchTweets 152 | true 153 | 154 | 155 | 156 | 157 | 158 | org.apache.camel 159 | camel-maven-plugin 160 | ${camel.version} 161 | 162 | 163 | spring/broker-camel.xml 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | bundle 173 | 174 | 175 | 176 | src/main/resources 177 | true 178 | 179 | spring/*.xml 180 | 181 | 182 | 183 | 184 | 185 | maven-jar-plugin 186 | 187 | 188 | ${project.build.outputDirectory}/META-INF/MANIFEST.MF 189 | 190 | 191 | 192 | 193 | org.apache.felix 194 | maven-bundle-plugin 195 | 2.3.7 196 | 197 | 198 | bundle-manifest 199 | process-classes 200 | 201 | manifest 202 | 203 | 204 | 205 | 206 | 207 | jar 208 | 209 | 210 | ${project.artifactId} 211 | ${project.name} 212 | ${project.version} 213 | 214 | org.apache.activemq.camel.component, 215 | * 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | -------------------------------------------------------------------------------- /web/src/main/webapp/js/stomp.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2010 Jeff Mesnil -- http://jmesnil.net/ 3 | Copyright (C) 2012 FuseSource, Inc. -- http://fusesource.com 4 | */ 5 | 6 | 7 | (function() { 8 | var Client, Stomp, WebSocketStompMock, 9 | __hasProp = {}.hasOwnProperty; 10 | 11 | Stomp = { 12 | frame: function(command, headers, body) { 13 | if (headers == null) { 14 | headers = []; 15 | } 16 | if (body == null) { 17 | body = ''; 18 | } 19 | return { 20 | command: command, 21 | headers: headers, 22 | body: body, 23 | id: headers.id, 24 | receipt: headers.receipt, 25 | transaction: headers.transaction, 26 | destination: headers.destination, 27 | subscription: headers.subscription, 28 | error: null, 29 | toString: function() { 30 | var lines, name, value; 31 | lines = [command]; 32 | for (name in headers) { 33 | if (!__hasProp.call(headers, name)) continue; 34 | value = headers[name]; 35 | lines.push("" + name + ":" + value); 36 | } 37 | lines.push('\n' + body); 38 | return lines.join('\n'); 39 | } 40 | }; 41 | }, 42 | unmarshal: function(data) { 43 | var body, chr, command, divider, headerLines, headers, i, idx, line, trim, _i, _j, _ref, _ref1, _ref2; 44 | divider = data.search(/\n\n/); 45 | headerLines = data.substring(0, divider).split('\n'); 46 | command = headerLines.shift(); 47 | headers = {}; 48 | body = ''; 49 | trim = function(str) { 50 | return str.replace(/^\s+/g, '').replace(/\s+$/g, ''); 51 | }; 52 | line = idx = null; 53 | for (i = _i = 0, _ref = headerLines.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { 54 | line = headerLines[i]; 55 | idx = line.indexOf(':'); 56 | headers[trim(line.substring(0, idx))] = trim(line.substring(idx + 1)); 57 | } 58 | chr = null; 59 | for (i = _j = _ref1 = divider + 2, _ref2 = data.length; _ref1 <= _ref2 ? _j < _ref2 : _j > _ref2; i = _ref1 <= _ref2 ? ++_j : --_j) { 60 | chr = data.charAt(i); 61 | if (chr === '\x00') { 62 | break; 63 | } 64 | body += chr; 65 | } 66 | return Stomp.frame(command, headers, body); 67 | }, 68 | marshal: function(command, headers, body) { 69 | return Stomp.frame(command, headers, body).toString() + '\x00'; 70 | }, 71 | client: function(url) { 72 | return new Client(url); 73 | } 74 | }; 75 | 76 | Client = (function() { 77 | 78 | Client.name = 'Client'; 79 | 80 | function Client(url) { 81 | this.url = url; 82 | this.counter = 0; 83 | this.connected = false; 84 | this.subscriptions = {}; 85 | } 86 | 87 | Client.prototype._transmit = function(command, headers, body) { 88 | var out; 89 | out = Stomp.marshal(command, headers, body); 90 | if (typeof this.debug === "function") { 91 | this.debug(">>> " + out); 92 | } 93 | return this.ws.send(out); 94 | }; 95 | 96 | Client.prototype.connect = function(login_, passcode_, connectCallback, errorCallback) { 97 | var klass, 98 | _this = this; 99 | if (typeof this.debug === "function") { 100 | this.debug("Opening Web Socket..."); 101 | } 102 | klass = WebSocketStompMock || WebSocket; 103 | this.ws = new klass(this.url); 104 | this.ws.binaryType = "arraybuffer"; 105 | this.ws.onmessage = function(evt) { 106 | var data, frame, i, onreceive, view; 107 | data = (function() { 108 | var _i, _len; 109 | if (evt.data instanceof ArrayBuffer) { 110 | view = new Uint8Array(evt.data); 111 | if (typeof this.debug === "function") { 112 | this.debug('--- got data length: ' + view.length); 113 | } 114 | data = ""; 115 | for (_i = 0, _len = view.length; _i < _len; _i++) { 116 | i = view[_i]; 117 | data += String.fromCharCode(i); 118 | } 119 | return data; 120 | } else { 121 | return evt.data; 122 | } 123 | }).call(_this); 124 | if (typeof _this.debug === "function") { 125 | _this.debug('<<< ' + data); 126 | } 127 | frame = Stomp.unmarshal(data); 128 | if (frame.command === "CONNECTED" && connectCallback) { 129 | _this.connected = true; 130 | return connectCallback(frame); 131 | } else if (frame.command === "MESSAGE") { 132 | onreceive = _this.subscriptions[frame.headers.subscription]; 133 | return typeof onreceive === "function" ? onreceive(frame) : void 0; 134 | } else if (frame.command === "ERROR") { 135 | return typeof errorCallback === "function" ? errorCallback(msg) : void 0; 136 | } else { 137 | return typeof _this.debug === "function" ? _this.debug("Unhandled frame: " + frame) : void 0; 138 | } 139 | }; 140 | this.ws.onclose = function() { 141 | var msg; 142 | msg = "Whoops! Lost connection to " + _this.url; 143 | if (typeof _this.debug === "function") { 144 | _this.debug(msg); 145 | } 146 | return typeof errorCallback === "function" ? errorCallback(msg) : void 0; 147 | }; 148 | this.ws.onerror = function(event) { 149 | return typeof errorCallback === "function" ? errorCallback(event) : void 0; 150 | }; 151 | this.ws.onopen = function() { 152 | if (typeof _this.debug === "function") { 153 | _this.debug('Web Socket Opened...'); 154 | } 155 | return _this._transmit("CONNECT", { 156 | login: login_, 157 | passcode: passcode_ 158 | }); 159 | }; 160 | return this.connectCallback = connectCallback; 161 | }; 162 | 163 | Client.prototype.disconnect = function(disconnectCallback) { 164 | this._transmit("DISCONNECT"); 165 | this.ws.close(); 166 | this.connected = false; 167 | return typeof disconnectCallback === "function" ? disconnectCallback() : void 0; 168 | }; 169 | 170 | Client.prototype.send = function(destination, headers, body) { 171 | if (headers == null) { 172 | headers = {}; 173 | } 174 | if (body == null) { 175 | body = ''; 176 | } 177 | headers.destination = destination; 178 | return this._transmit("SEND", headers, body); 179 | }; 180 | 181 | Client.prototype.subscribe = function(destination, callback, headers) { 182 | var id; 183 | if (headers == null) { 184 | headers = {}; 185 | } 186 | id = "sub-" + this.counter++; 187 | headers.destination = destination; 188 | headers.id = id; 189 | this.subscriptions[id] = callback; 190 | this._transmit("SUBSCRIBE", headers); 191 | return id; 192 | }; 193 | 194 | Client.prototype.unsubscribe = function(id, headers) { 195 | if (headers == null) { 196 | headers = {}; 197 | } 198 | headers.id = id; 199 | delete this.subscriptions[id]; 200 | return this._transmit("UNSUBSCRIBE", headers); 201 | }; 202 | 203 | Client.prototype.begin = function(transaction, headers) { 204 | if (headers == null) { 205 | headers = {}; 206 | } 207 | headers.transaction = transaction; 208 | return this._transmit("BEGIN", headers); 209 | }; 210 | 211 | Client.prototype.commit = function(transaction, headers) { 212 | if (headers == null) { 213 | headers = {}; 214 | } 215 | headers.transaction = transaction; 216 | return this._transmit("COMMIT", headers); 217 | }; 218 | 219 | Client.prototype.abort = function(transaction, headers) { 220 | if (headers == null) { 221 | headers = {}; 222 | } 223 | headers.transaction = transaction; 224 | return this._transmit("ABORT", headers); 225 | }; 226 | 227 | Client.prototype.ack = function(message_id, headers) { 228 | if (headers == null) { 229 | headers = {}; 230 | } 231 | headers["message-id"] = message_id; 232 | return this._transmit("ACK", headers); 233 | }; 234 | 235 | return Client; 236 | 237 | })(); 238 | 239 | if (typeof window !== "undefined" && window !== null) { 240 | window.Stomp = Stomp; 241 | } else { 242 | exports.Stomp = Stomp; 243 | WebSocketStompMock = require('./test/server.mock.js').StompServerMock; 244 | } 245 | 246 | }).call(this); -------------------------------------------------------------------------------- /camel-ws/src/main/resources/webapp/js/stomp.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2010 Jeff Mesnil -- http://jmesnil.net/ 3 | Copyright (C) 2012 FuseSource, Inc. -- http://fusesource.com 4 | */ 5 | 6 | 7 | (function() { 8 | var Client, Stomp, WebSocketStompMock, 9 | __hasProp = {}.hasOwnProperty; 10 | 11 | Stomp = { 12 | frame: function(command, headers, body) { 13 | if (headers == null) { 14 | headers = []; 15 | } 16 | if (body == null) { 17 | body = ''; 18 | } 19 | return { 20 | command: command, 21 | headers: headers, 22 | body: body, 23 | id: headers.id, 24 | receipt: headers.receipt, 25 | transaction: headers.transaction, 26 | destination: headers.destination, 27 | subscription: headers.subscription, 28 | error: null, 29 | toString: function() { 30 | var lines, name, value; 31 | lines = [command]; 32 | for (name in headers) { 33 | if (!__hasProp.call(headers, name)) continue; 34 | value = headers[name]; 35 | lines.push("" + name + ":" + value); 36 | } 37 | lines.push('\n' + body); 38 | return lines.join('\n'); 39 | } 40 | }; 41 | }, 42 | unmarshal: function(data) { 43 | var body, chr, command, divider, headerLines, headers, i, idx, line, trim, _i, _j, _ref, _ref1, _ref2; 44 | divider = data.search(/\n\n/); 45 | headerLines = data.substring(0, divider).split('\n'); 46 | command = headerLines.shift(); 47 | headers = {}; 48 | body = ''; 49 | trim = function(str) { 50 | return str.replace(/^\s+/g, '').replace(/\s+$/g, ''); 51 | }; 52 | line = idx = null; 53 | for (i = _i = 0, _ref = headerLines.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { 54 | line = headerLines[i]; 55 | idx = line.indexOf(':'); 56 | headers[trim(line.substring(0, idx))] = trim(line.substring(idx + 1)); 57 | } 58 | chr = null; 59 | for (i = _j = _ref1 = divider + 2, _ref2 = data.length; _ref1 <= _ref2 ? _j < _ref2 : _j > _ref2; i = _ref1 <= _ref2 ? ++_j : --_j) { 60 | chr = data.charAt(i); 61 | if (chr === '\x00') { 62 | break; 63 | } 64 | body += chr; 65 | } 66 | return Stomp.frame(command, headers, body); 67 | }, 68 | marshal: function(command, headers, body) { 69 | return Stomp.frame(command, headers, body).toString() + '\x00'; 70 | }, 71 | client: function(url) { 72 | return new Client(url); 73 | } 74 | }; 75 | 76 | Client = (function() { 77 | 78 | Client.name = 'Client'; 79 | 80 | function Client(url) { 81 | this.url = url; 82 | this.counter = 0; 83 | this.connected = false; 84 | this.subscriptions = {}; 85 | } 86 | 87 | Client.prototype._transmit = function(command, headers, body) { 88 | var out; 89 | out = Stomp.marshal(command, headers, body); 90 | if (typeof this.debug === "function") { 91 | this.debug(">>> " + out); 92 | } 93 | return this.ws.send(out); 94 | }; 95 | 96 | Client.prototype.connect = function(login_, passcode_, connectCallback, errorCallback) { 97 | var klass, 98 | _this = this; 99 | if (typeof this.debug === "function") { 100 | this.debug("Opening Web Socket..."); 101 | } 102 | klass = WebSocketStompMock || WebSocket; 103 | this.ws = new klass(this.url); 104 | this.ws.binaryType = "arraybuffer"; 105 | this.ws.onmessage = function(evt) { 106 | var data, frame, i, onreceive, view; 107 | data = (function() { 108 | var _i, _len; 109 | if (evt.data instanceof ArrayBuffer) { 110 | view = new Uint8Array(evt.data); 111 | if (typeof this.debug === "function") { 112 | this.debug('--- got data length: ' + view.length); 113 | } 114 | data = ""; 115 | for (_i = 0, _len = view.length; _i < _len; _i++) { 116 | i = view[_i]; 117 | data += String.fromCharCode(i); 118 | } 119 | return data; 120 | } else { 121 | return evt.data; 122 | } 123 | }).call(_this); 124 | if (typeof _this.debug === "function") { 125 | _this.debug('<<< ' + data); 126 | } 127 | frame = Stomp.unmarshal(data); 128 | if (frame.command === "CONNECTED" && connectCallback) { 129 | _this.connected = true; 130 | return connectCallback(frame); 131 | } else if (frame.command === "MESSAGE") { 132 | onreceive = _this.subscriptions[frame.headers.subscription]; 133 | return typeof onreceive === "function" ? onreceive(frame) : void 0; 134 | } else if (frame.command === "ERROR") { 135 | return typeof errorCallback === "function" ? errorCallback(msg) : void 0; 136 | } else { 137 | return typeof _this.debug === "function" ? _this.debug("Unhandled frame: " + frame) : void 0; 138 | } 139 | }; 140 | this.ws.onclose = function() { 141 | var msg; 142 | msg = "Whoops! Lost connection to " + _this.url; 143 | if (typeof _this.debug === "function") { 144 | _this.debug(msg); 145 | } 146 | return typeof errorCallback === "function" ? errorCallback(msg) : void 0; 147 | }; 148 | this.ws.onerror = function(event) { 149 | return typeof errorCallback === "function" ? errorCallback(event) : void 0; 150 | }; 151 | this.ws.onopen = function() { 152 | if (typeof _this.debug === "function") { 153 | _this.debug('Web Socket Opened...'); 154 | } 155 | return _this._transmit("CONNECT", { 156 | login: login_, 157 | passcode: passcode_ 158 | }); 159 | }; 160 | return this.connectCallback = connectCallback; 161 | }; 162 | 163 | Client.prototype.disconnect = function(disconnectCallback) { 164 | this._transmit("DISCONNECT"); 165 | this.ws.close(); 166 | this.connected = false; 167 | return typeof disconnectCallback === "function" ? disconnectCallback() : void 0; 168 | }; 169 | 170 | Client.prototype.send = function(destination, headers, body) { 171 | if (headers == null) { 172 | headers = {}; 173 | } 174 | if (body == null) { 175 | body = ''; 176 | } 177 | headers.destination = destination; 178 | return this._transmit("SEND", headers, body); 179 | }; 180 | 181 | Client.prototype.subscribe = function(destination, callback, headers) { 182 | var id; 183 | if (headers == null) { 184 | headers = {}; 185 | } 186 | id = "sub-" + this.counter++; 187 | headers.destination = destination; 188 | headers.id = id; 189 | this.subscriptions[id] = callback; 190 | this._transmit("SUBSCRIBE", headers); 191 | return id; 192 | }; 193 | 194 | Client.prototype.unsubscribe = function(id, headers) { 195 | if (headers == null) { 196 | headers = {}; 197 | } 198 | headers.id = id; 199 | delete this.subscriptions[id]; 200 | return this._transmit("UNSUBSCRIBE", headers); 201 | }; 202 | 203 | Client.prototype.begin = function(transaction, headers) { 204 | if (headers == null) { 205 | headers = {}; 206 | } 207 | headers.transaction = transaction; 208 | return this._transmit("BEGIN", headers); 209 | }; 210 | 211 | Client.prototype.commit = function(transaction, headers) { 212 | if (headers == null) { 213 | headers = {}; 214 | } 215 | headers.transaction = transaction; 216 | return this._transmit("COMMIT", headers); 217 | }; 218 | 219 | Client.prototype.abort = function(transaction, headers) { 220 | if (headers == null) { 221 | headers = {}; 222 | } 223 | headers.transaction = transaction; 224 | return this._transmit("ABORT", headers); 225 | }; 226 | 227 | Client.prototype.ack = function(message_id, headers) { 228 | if (headers == null) { 229 | headers = {}; 230 | } 231 | headers["message-id"] = message_id; 232 | return this._transmit("ACK", headers); 233 | }; 234 | 235 | return Client; 236 | 237 | })(); 238 | 239 | if (typeof window !== "undefined" && window !== null) { 240 | window.Stomp = Stomp; 241 | } else { 242 | exports.Stomp = Stomp; 243 | WebSocketStompMock = require('./test/server.mock.js').StompServerMock; 244 | } 245 | 246 | }).call(this); -------------------------------------------------------------------------------- /camel-ws-ssl/src/main/resources/webapp/js/stomp.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2010 Jeff Mesnil -- http://jmesnil.net/ 3 | Copyright (C) 2012 FuseSource, Inc. -- http://fusesource.com 4 | */ 5 | 6 | 7 | (function() { 8 | var Client, Stomp, WebSocketStompMock, 9 | __hasProp = {}.hasOwnProperty; 10 | 11 | Stomp = { 12 | frame: function(command, headers, body) { 13 | if (headers == null) { 14 | headers = []; 15 | } 16 | if (body == null) { 17 | body = ''; 18 | } 19 | return { 20 | command: command, 21 | headers: headers, 22 | body: body, 23 | id: headers.id, 24 | receipt: headers.receipt, 25 | transaction: headers.transaction, 26 | destination: headers.destination, 27 | subscription: headers.subscription, 28 | error: null, 29 | toString: function() { 30 | var lines, name, value; 31 | lines = [command]; 32 | for (name in headers) { 33 | if (!__hasProp.call(headers, name)) continue; 34 | value = headers[name]; 35 | lines.push("" + name + ":" + value); 36 | } 37 | lines.push('\n' + body); 38 | return lines.join('\n'); 39 | } 40 | }; 41 | }, 42 | unmarshal: function(data) { 43 | var body, chr, command, divider, headerLines, headers, i, idx, line, trim, _i, _j, _ref, _ref1, _ref2; 44 | divider = data.search(/\n\n/); 45 | headerLines = data.substring(0, divider).split('\n'); 46 | command = headerLines.shift(); 47 | headers = {}; 48 | body = ''; 49 | trim = function(str) { 50 | return str.replace(/^\s+/g, '').replace(/\s+$/g, ''); 51 | }; 52 | line = idx = null; 53 | for (i = _i = 0, _ref = headerLines.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { 54 | line = headerLines[i]; 55 | idx = line.indexOf(':'); 56 | headers[trim(line.substring(0, idx))] = trim(line.substring(idx + 1)); 57 | } 58 | chr = null; 59 | for (i = _j = _ref1 = divider + 2, _ref2 = data.length; _ref1 <= _ref2 ? _j < _ref2 : _j > _ref2; i = _ref1 <= _ref2 ? ++_j : --_j) { 60 | chr = data.charAt(i); 61 | if (chr === '\x00') { 62 | break; 63 | } 64 | body += chr; 65 | } 66 | return Stomp.frame(command, headers, body); 67 | }, 68 | marshal: function(command, headers, body) { 69 | return Stomp.frame(command, headers, body).toString() + '\x00'; 70 | }, 71 | client: function(url) { 72 | return new Client(url); 73 | } 74 | }; 75 | 76 | Client = (function() { 77 | 78 | Client.name = 'Client'; 79 | 80 | function Client(url) { 81 | this.url = url; 82 | this.counter = 0; 83 | this.connected = false; 84 | this.subscriptions = {}; 85 | } 86 | 87 | Client.prototype._transmit = function(command, headers, body) { 88 | var out; 89 | out = Stomp.marshal(command, headers, body); 90 | if (typeof this.debug === "function") { 91 | this.debug(">>> " + out); 92 | } 93 | return this.ws.send(out); 94 | }; 95 | 96 | Client.prototype.connect = function(login_, passcode_, connectCallback, errorCallback) { 97 | var klass, 98 | _this = this; 99 | if (typeof this.debug === "function") { 100 | this.debug("Opening Web Socket..."); 101 | } 102 | klass = WebSocketStompMock || WebSocket; 103 | this.ws = new klass(this.url); 104 | this.ws.binaryType = "arraybuffer"; 105 | this.ws.onmessage = function(evt) { 106 | var data, frame, i, onreceive, view; 107 | data = (function() { 108 | var _i, _len; 109 | if (evt.data instanceof ArrayBuffer) { 110 | view = new Uint8Array(evt.data); 111 | if (typeof this.debug === "function") { 112 | this.debug('--- got data length: ' + view.length); 113 | } 114 | data = ""; 115 | for (_i = 0, _len = view.length; _i < _len; _i++) { 116 | i = view[_i]; 117 | data += String.fromCharCode(i); 118 | } 119 | return data; 120 | } else { 121 | return evt.data; 122 | } 123 | }).call(_this); 124 | if (typeof _this.debug === "function") { 125 | _this.debug('<<< ' + data); 126 | } 127 | frame = Stomp.unmarshal(data); 128 | if (frame.command === "CONNECTED" && connectCallback) { 129 | _this.connected = true; 130 | return connectCallback(frame); 131 | } else if (frame.command === "MESSAGE") { 132 | onreceive = _this.subscriptions[frame.headers.subscription]; 133 | return typeof onreceive === "function" ? onreceive(frame) : void 0; 134 | } else if (frame.command === "ERROR") { 135 | return typeof errorCallback === "function" ? errorCallback(msg) : void 0; 136 | } else { 137 | return typeof _this.debug === "function" ? _this.debug("Unhandled frame: " + frame) : void 0; 138 | } 139 | }; 140 | this.ws.onclose = function() { 141 | var msg; 142 | msg = "Whoops! Lost connection to " + _this.url; 143 | if (typeof _this.debug === "function") { 144 | _this.debug(msg); 145 | } 146 | return typeof errorCallback === "function" ? errorCallback(msg) : void 0; 147 | }; 148 | this.ws.onerror = function(event) { 149 | return typeof errorCallback === "function" ? errorCallback(event) : void 0; 150 | }; 151 | this.ws.onopen = function() { 152 | if (typeof _this.debug === "function") { 153 | _this.debug('Web Socket Opened...'); 154 | } 155 | return _this._transmit("CONNECT", { 156 | login: login_, 157 | passcode: passcode_ 158 | }); 159 | }; 160 | return this.connectCallback = connectCallback; 161 | }; 162 | 163 | Client.prototype.disconnect = function(disconnectCallback) { 164 | this._transmit("DISCONNECT"); 165 | this.ws.close(); 166 | this.connected = false; 167 | return typeof disconnectCallback === "function" ? disconnectCallback() : void 0; 168 | }; 169 | 170 | Client.prototype.send = function(destination, headers, body) { 171 | if (headers == null) { 172 | headers = {}; 173 | } 174 | if (body == null) { 175 | body = ''; 176 | } 177 | headers.destination = destination; 178 | return this._transmit("SEND", headers, body); 179 | }; 180 | 181 | Client.prototype.subscribe = function(destination, callback, headers) { 182 | var id; 183 | if (headers == null) { 184 | headers = {}; 185 | } 186 | id = "sub-" + this.counter++; 187 | headers.destination = destination; 188 | headers.id = id; 189 | this.subscriptions[id] = callback; 190 | this._transmit("SUBSCRIBE", headers); 191 | return id; 192 | }; 193 | 194 | Client.prototype.unsubscribe = function(id, headers) { 195 | if (headers == null) { 196 | headers = {}; 197 | } 198 | headers.id = id; 199 | delete this.subscriptions[id]; 200 | return this._transmit("UNSUBSCRIBE", headers); 201 | }; 202 | 203 | Client.prototype.begin = function(transaction, headers) { 204 | if (headers == null) { 205 | headers = {}; 206 | } 207 | headers.transaction = transaction; 208 | return this._transmit("BEGIN", headers); 209 | }; 210 | 211 | Client.prototype.commit = function(transaction, headers) { 212 | if (headers == null) { 213 | headers = {}; 214 | } 215 | headers.transaction = transaction; 216 | return this._transmit("COMMIT", headers); 217 | }; 218 | 219 | Client.prototype.abort = function(transaction, headers) { 220 | if (headers == null) { 221 | headers = {}; 222 | } 223 | headers.transaction = transaction; 224 | return this._transmit("ABORT", headers); 225 | }; 226 | 227 | Client.prototype.ack = function(message_id, headers) { 228 | if (headers == null) { 229 | headers = {}; 230 | } 231 | headers["message-id"] = message_id; 232 | return this._transmit("ACK", headers); 233 | }; 234 | 235 | return Client; 236 | 237 | })(); 238 | 239 | if (typeof window !== "undefined" && window !== null) { 240 | window.Stomp = Stomp; 241 | } else { 242 | exports.Stomp = Stomp; 243 | WebSocketStompMock = require('./test/server.mock.js').StompServerMock; 244 | } 245 | 246 | }).call(this); --------------------------------------------------------------------------------