Habréã§ã¯ãVert.xã
one ã
two ãããã³èª€ã£ãŠèšç®ãããèšäºã¯ããã»ã©å€ããããŸããã ãã®ãããVert.x 3ã䜿çšããŠç°¡åãªãã£ãããäœæããæ¹æ³ã説æããçãã¬ãã¹ã³ãæäŸããå
¬éããããšã«ããŸããã

å
容
- Vert.xãšã¯äœã§ããïŒ
- ãã£ããã«ã€ããŠ
- ãããžã§ã¯ãæ§é
- ãµãŒããŒ
- ã客æ§
- ãã¹ãäž
- å®è¡å¯èœã¢ãžã¥ãŒã«ããã«ãããŠå®è¡ãã
- å®å
šãªãœãŒã¹ã³ãŒã
- æçšãªãªãœãŒã¹
Vert.xãšã¯äœã§ããïŒ
Vert.xã¯ãJVMäžã§å®è¡ãããã€ãã³ãé§ååãã¬ãŒã ã¯ãŒã¯ã§ãã çŸæç¹ã§ã¯ããã®ãã¬ãŒã ã¯ãŒã¯ã®ææ°ããŒãžã§ã³ã¯3.2ã§ãã Vert.x 3ã¯æ¬¡ã®æ©èœãæäŸããŸãã
- å€èšèªäž»çŸ© ã ã¢ããªã±ãŒã·ã§ã³ã³ã³ããŒãã³ãã¯ãJavaãJavaScriptãScalaãPythonãRubyãGroovyãããã³Clojureã§éçºã§ããŸãã
- äžŠè¡æ§ ãã«ãã¹ã¬ããããã°ã©ãã³ã°ã®æéãçããéåžžã«åçŽãªåæå®è¡ã¢ãã«ã
- éåææ§ ã ãããã¯ããªãéåæçžäºäœçšã®åçŽãªã¢ãã«ã
- 忣ã€ãã³ããã¹ ã ã¯ã©ã€ã¢ã³ãåŽãšãµãŒããŒåŽã®äž¡æ¹ãå«ã¿ãŸãã ãã£ããã®äž»ãªåœ¹å²ãçŽæ¥æãããŸãã
- Java 8 ã Vert.x 3ã«ã¯JavaããŒãžã§ã³8以éãå¿
èŠã§ãã
ãã£ããã®è©³çް
ã¢ããªã±ãŒã·ã§ã³ã¯ãµãŒããŒäžã§å®è¡ãããå±éåŸãå¿åãã£ããã®ã¢ãã¬ã¹ãå
¬éãããŸããããã¯ä»»æã®ãã©ãŠã¶ãŒããåå ã§ããŸãã ãã®ã¢ãã¬ã¹ã§ãã¢ããªã±ãŒã·ã§ã³ã¯ãã¹ãŠã®ãŠãŒã¶ãŒãããªã¢ã«ã¿ã€ã ã§ã¡ãã»ãŒãžããããŒããã£ã¹ãããŸãã

è¡ããïŒ
éçºã¯ãIntelliJ IDEA 15ãååãª
ã³ãã¥ããã£ããŒãžã§ã³ã§è¡ãããŸãã
ãããžã§ã¯ãæ§é
Mavenãããžã§ã¯ããäœæããŸãã æ®å¿µãªãããvert.x 3ã®æ¢æã®ã¢ãŒãã¿ã€ãã¯ãããŸããïŒ2ã®å Žåã¯ååšããŸãïŒã®ã§ãéåžžã®Mavenãããžã§ã¯ããçæããŸãã æçµçãªæ§é ã¯æ¬¡ã®ãšããã§ãã
æ§é src +---main | +---java | | | Server.java | | | VerticleLoader.java | | | | | \---webroot | | date-format.js | | index.html | | vertx-eventbus.js | | | \---resources \---test \---java ChatTest.java
pom.xmlã§ã¯ã次ã®äŸåé¢ä¿ãå®çŸ©ããŸãã
vertx-core Verticlesãã©ã€ãã©ãªããµããŒãããŠããå ŽåïŒè©³çްã¯äœã§ããããããå°ã詳ããïŒã
vertx- web-ãŠããããã¹ãã«ã€ãã³ããã³ãã©ãŒïŒã ãã§ãªãïŒãš
vertx-unitã䜿çšã§ããŸãã
pom.xml <dependencies> <dependency> <groupId>io.vertx</groupId> <artifactId>vertx-core</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>io.vertx</groupId> <artifactId>vertx-web</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>io.vertx</groupId> <artifactId>vertx-unit</artifactId> <version>3.0.0</version> <scope>test</scope> </dependency> </dependencies>
ãµãŒããŒ
ãã®ãã¬ãŒã ã¯ãŒã¯ã®ç¹åŸŽã¯ããã¹ãŠã®ã³ã³ããŒãã³ããé ç¹ã®åœ¢ã§æç€ºããå¿
èŠãããããšã§ãã
Verticleã¯ããµãŒãã¬ããã®é¡äŒŒç©ã§ããããããã€ã¡ã³ãã®åååäœã§ãã éçºè
èªèº«ã¯ãVerticleãã¢ã¯ã¿ãŒã¢ãã«ã®ã¢ã¯ã¿ãŒã«äŒŒããã®ãšããŠèª¬æããŠããŸãã å®éããã®èšèšã«ãããVert.xã§æåãªé«åºŠãªäžŠåæ§ãšéåææ§ãæŽçã§ããŸãã ãµãŒããŒå®è£
ã§ã¯ãAbstractVerticleæœè±¡ã¯ã©ã¹ãç¶æ¿ããŸãã
ãªãŒããŒã©ã€ãããstartïŒïŒã¡ãœããã¯ãããã°ã©ã ãžã®ãšã³ããªãã€ã³ãã§ãã æåã«ãã¢ããªã±ãŒã·ã§ã³ããããã€ãããŸã-deployïŒïŒé¢æ°ã次ã«ãã³ãã©ãŒããã³ã°ã¢ããããŸã-handleïŒïŒã¡ãœããã
Server.java public class Server extends AbstractVerticle { private Logger log = LoggerFactory.getLogger(Server.class); private SockJSHandler handler = null; private AtomicInteger online = new AtomicInteger(0);
ã¢ããªã±ãŒã·ã§ã³ããããã€ããã«ã¯ã空ãããŒããååŸããå¿
èŠããããŸããååŸã§ããªãå Žåã¯ãhostPortã«è² ã®å€ããããŸãã æ¬¡ã«ãã«ãŒã¿ãŒãäœæãããã®åä¿¡è
ã®ã¢ãã¬ã¹ãæå®ããŠããã³ãã©ãŒãåæããŸãã æåŸã«ãã¢ã¯ã»ã¹å¯èœãªããŒãã§HTTPãµãŒããŒãå®è¡ããŸãã
空ãããŒããååŸããããã»ã¹ã¯ã以äžã®ã³ãŒãã¹ããããã«ç€ºãããŠããŸãã æåã«ãéçãã£ãŒã«ãPROCESS_ARGSã§ã¢ããªã±ãŒã·ã§ã³ãèµ·åããããã®åŒæ°ããã§ãã¯ãããŸãããã®åŒæ°ã®1ã€ã¯ããŠãŒã¶ãŒãæå®ããã¢ããªã±ãŒã·ã§ã³ãããã€ã¡ã³ãããŒãã§ãã ããŒããæå®ãããªãã£ãå Žåãããã©ã«ãã®ããŒã8080ã䜿çšãããŸãã
å€ã0ã®ãã©ã¡ãŒã¿ãŒããœã±ãããäœæããããã®ã³ã³ã¹ãã©ã¯ã¿ãŒã®åŒæ°ãšããŠæå®ãããŠããå Žåãã©ã³ãã ãªç©ºãããŒããçºè¡ãããŸãã
ããŒãããã§ã«äœ¿çšãããŠããå ŽåïŒããšãã°ãããŒã8080ãå¥ã®ã¢ããªã±ãŒã·ã§ã³ã«ãã£ãŠæ¢ã«äœ¿çšãããŠããããåæã«ãçŸåšã®ã¢ããªã±ãŒã·ã§ã³ãèµ·åããåŒæ°ãšããŠç€ºãããŠããå ŽåïŒãBindExceptionãã¹ããŒãããŸãããã®å Žåã空ãããŒãã®ååŸãç¹°ãè¿ã詊è¡ãããŸãã
Server.java private int getFreePort(int hostPort) { try { ServerSocket socket = new ServerSocket(hostPort); int port = socket.getLocalPort(); socket.close(); return port; } catch (BindException e) {
å±éãæåããå Žåãã€ãã³ããã¹ã®ãªã¹ãã³ã°ã¯ãchat.to.serverïŒçä¿¡ã€ãã³ãïŒããã³chat.to.clientïŒçºä¿¡ã€ãã³ãïŒããå§ãŸããŸãã
ãã¹äžã®æ¬¡ã®ã€ãã³ããåŠçããåŸããã®ã€ãã³ãã確èªããå¿
èŠããããŸãã
Server.java private void handle() { BridgeOptions opts = new BridgeOptions() .addInboundPermitted(new PermittedOptions().setAddress("chat.to.server")) .addOutboundPermitted(new PermittedOptions().setAddress("chat.to.client"));
ãã¹ã§çºçããã€ãã³ãã¯ã次ã®7ã€ã®ã¿ã€ãã§è¡šãããšãã§ããŸãã
çš®é¡ | ã€ãã³ã |
---|
SOCKET_CREATED | ãœã±ããã®äœææã«çºçãã |
SOCKET_CLOSED | ãœã±ãããéãããšã |
éä¿¡ | ã¯ã©ã€ã¢ã³ããããµãŒããŒã«ã¡ãã»ãŒãžãéä¿¡ããããšããŸã |
å
¬éãã | ãµãŒããŒã®ã¯ã©ã€ã¢ã³ãæçš¿ |
åä¿¡ãã | é
ä¿¡ãããã¡ãã»ãŒãžã«é¢ãããµãŒããŒããã®éç¥ |
ç»é²ãã | ãã³ãã©ãŒãç»é²ããã |
ç»é²è§£é€ | ç»é²ããããã³ãã©ãŒããã£ã³ã»ã«ããããšãã |
ãã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãPUBLISHãREGISTERãããã³SOCKET_CLOSEDã¿ã€ãã®ã€ãã³ãã®ã¿ãåŠçããå¿
èŠããããŸãã
ã¿ã€ãPUBLISHã®ã€ãã³ãã¯ããŠãŒã¶ãŒã®1人ããã£ããã«ã¡ãã»ãŒãžãéä¿¡ãããšããªã¬ãŒãããŸãã
REGISTER-ãŠãŒã¶ãŒããã³ãã©ãŒãç»é²ãããšããªã¬ãŒãããŸãã SOCKET_CREATEDãéžã°ãªãã®ã¯ãªãã§ããïŒ ãªããªããã¿ã€ãSOCKET_CREATEDã®ã€ãã³ãã¯REGISTERã®åã«ããããããŠãã¡ãããã¯ã©ã€ã¢ã³ãããã³ãã©ãŒãç»é²ãããŸã§ãã€ãã³ããåãåãããšãã§ããªãããã§ãã
SOCKET_CLOSED-ãŠãŒã¶ãŒããã£ãããé¢ãããšãããŸãã¯äºæããªãç¶æ³ãçºçãããšãã«çºçããŸãã
ã¡ãã»ãŒãžãå
¬éããããšããã³ãã©ãŒãèµ·åããpublishEventã¡ãœãããåŒã³åºããŸãã å®å
ã¢ãã¬ã¹ããã§ãã¯ããããããæ£ããå Žåãã¡ãã»ãŒãžãååŸããããã¹ãŠã®ã¯ã©ã€ã¢ã³ãïŒéä¿¡è
ãå«ãïŒã®ã€ãã³ããã¹ã§ãã§ãã¯ããã³å
¬éãããŸãã
Server.java private boolean publishEvent(BridgeEvent event) { if (event.rawMessage() != null && event.rawMessage().getString("address").equals("chat.to.server")) { String message = event.rawMessage().getString("body"); if (!verifyMessage(message)) return false; String host = event.socket().remoteAddress().host(); int port = event.socket().remoteAddress().port(); Map<String, Object> publicNotice = createPublicNotice(host, port, message); vertx.eventBus().publish("chat.to.client", new Gson().toJson(publicNotice)); return true; } else return false; }
転èšã®éç¥çæã¯æ¬¡ã®ãšããã§ãã
ãã£ããã§ã®ãŠãŒã¶ãŒã®ãã°ã€ã³ãšãã°ã¢ãŠãã¯ãæ¬¡ã®æ¹æ³ã§åŠçãããŸãã
å
¬éãããã¡ãã»ãŒãžã®ç¢ºèªã¯éåžžã«åå§çã§ãããããšãã°ããã§ååã§ãã ããšãã°ãã¡ãã»ãŒãžããã®ä»ã®ããã¯ã®åœ¢ã§ã¹ã¯ãªããã®éä¿¡ã確èªããããšã§ãèªåã§è€éã«ããããšãã§ããŸãã
Server.java private boolean verifyMessage(String msg) { return msg.length() > 0 && msg.length() <= 140; }
JSON圢åŒã¯ããŒã¿äº€æã«äœ¿çšããããããpom.xmlãã¡ã€ã«ã¯æ¬¡ã®äŸåé¢ä¿ã远å ããŠæŽæ°ããå¿
èŠããããŸãã
pom.xml <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.3.1</version> </dependency>
ãŸãããã£ããã§ã¯ããªã³ã©ã€ã³ãŠãŒã¶ãŒæ°ã®ã«ãŠã³ã¿ãŒã衚瀺ãããŸãã ã¢ããªã±ãŒã·ã§ã³ã¯ãã«ãã¹ã¬ããã§ãããããã¹ã¬ããã»ãŒãã§ããããšãä¿èšŒããå¿
èŠããããŸãããããã£ãŠãã«ãŠã³ã¿ãŒã
AtomicIntegerãšããŠå®£èšããæãç°¡åãªæ¹æ³
ã§ã ã
ã客æ§
èšäºã®åé ã®æ§é ã«ç€ºãããŠããããã«ãwebrootã»ã¯ã·ã§ã³ã«index.htmlãäœæããŸãã ãµãŒããŒãšããŸãã¯ã€ãã³ããã¹ãšéä¿¡ããã«ã¯ã
vertx-eventbus.jsã©ã€ãã©ãªã䜿çšããŸãã
æ¥ä»ããã©ãŒãããããã«ã¯ãããªãã·ã³ãã«ã§äŸ¿å©ãª
date-format.jsã©ã€ãã©ãªã䜿çšã
ãŸã ã ããã«ãhtmlãã¶ã€ã³ãšããŠãvertx-eventbus.jsã©ã€ãã©ãªãšjqueryããŒãžã§ã³1.11.3ã«å¿
èŠãªããŒãã¹ãã©ããããŒãžã§ã³3.3.5ãsockjs.jsããŒãžã§ã³0.3.4ã䜿çšããŸãã
ã¯ã©ã€ã¢ã³ãåŽã€ãã³ããã¹ãã³ãã©ã¯æ¬¡ã®ãšããã§ãã
ã€ãã³ãã®ã¿ã€ãããããªãã·ã¥ïŒã€ãŸããã¡ãã»ãŒãžã®ãããªã±ãŒã·ã§ã³ïŒã®å Žåãã€ãã³ãããã®ããŒã¿ã¯ã¿ãã«ã«åœ¢æãããã¡ãã»ãŒãžããŒãã«ã«æ·»ä»ãããŸãã ãã以å€ã®å Žåãã€ãã³ãã®çš®é¡ãæ°èŠãŸãã¯éå»ãããŠãŒã¶ãŒã«å¯Ÿå¿ããå Žåããªã³ã©ã€ã³ãŠãŒã¶ãŒã«ãŠã³ã¿ãŒã¯åã«æŽæ°ãããŸãã ã¡ãã»ãŒãžã远å ããæ©èœã¯éåžžã«ç°¡åã§ãã
ã¡ãã»ãŒãžãéä¿¡ãããšããæåã«ãchat.to.serverãã§å
¬éããããµãŒããŒããããåŠçããŸããã¡ãã»ãŒãžãæ€èšŒã«åæ Œããå Žåãã¡ãã»ãŒãžã¯ãã¹ãŠã®ã¯ã©ã€ã¢ã³ãã«éä¿¡ãããŸãã ãããŠéä¿¡è
ã«ã
index.html $(document).ready(function() {
ãããŠæåŸã«ãæ¡ä»¶ã«ãã£ãŠãå
¥åãããæåæ°ãåŠçããæåŸã®æ¹æ³ã¯ããŠãŒã¶ãŒã140æåãè¶
ããã¡ãã»ãŒãžãå
¥åã§ããªãããšã§ãã
ããŒã¯ã¢ãããå«ãindex.htmlã®å®å
šçã¯ãèšäºã®æåŸã«ãããŸãã
ãµãŒããŒãšã¯ã©ã€ã¢ã³ãã®éšåãäœæããåŸãã¢ããªã±ãŒã·ã§ã³ãèµ·åããŸããã èµ·åãšäŸ¿å©ãªãããã°ã®ããã«ãç¬èªã®VerticleããŒããŒãäœæããããšããå§ãããŸãããããç°¡åãªä»£æ¿ææ®µããããŸããããã«ã€ããŠã¯åŸã§èª¬æããŸãã
dir倿°ãåæåããå¯äžã®å€ã¯é¢é£ããå¿
èŠããããŸã å®éããã®ãããªãã¹ãååšããå¿
èŠããããŸãã ãŸããverticleID倿°ã¯ãèµ·åãããããŒãã£ã¯ã«ã¯ã©ã¹ã®ååã§åæåããå¿
èŠããããŸããä»ã®ãã¹ãŠã®ã³ãŒãã¯å€æŽã§ããŸããã
VerticleLoader.java public class VerticleLoader { private static Vertx vertx; public static Vertx getVertx() { return vertx; } public static void load() { load(null); } public static void load(Handler<AsyncResult<String>> completionHandler) { VertxOptions options = new VertxOptions().setClustered(false);
ããŒãããŒããŒã®æºåãã§ããããèµ·åæ§æãäœæããŸããå®è¡-æ§æã®ç·šé...-æ°ããæ§æã®è¿œå ïŒAlt + InsertïŒ-ã¢ããªã±ãŒã·ã§ã³ã ã¡ã€ã³ã¯ã©ã¹ãVerticleLoaderãšããŠæå®ããæ§æãä¿åããŠå®è¡ããŸãã
å©çïŒçŽæãããä»£æ¿æ¡ã
ä»£æ¿æ§æå³ã«ç€ºãããã«ãèµ·åæ§æãäœæããå¿
èŠããããŸãã å®éãStarterã¯ã©ã¹ã¯ã¡ã€ã³ã¯ã©ã¹ã§ãããã¢ããªã±ãŒã·ã§ã³ã®ãšã³ããªãã€ã³ãã§ããmainã¡ãœãããå«ãŸããŠããŸãã

ãã¹ãäž
éçºããã¢ããªã±ãŒã·ã§ã³ããã¹ãããŸãããã JUnitã䜿çšããŠãããè¡ããããpom.xmlãå床éããæ¬¡ã®äŸåé¢ä¿ã远å ããå¿
èŠããããŸãã
pom.xml <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
setUpã§ã¯ãVertxãã€ã³ã¹ã¿ã³ã¹åããVerticleããããã€ããŸãã åŸæ¥ã®JUnitã¡ãœãããšã¯ç°ãªããçŸåšã®ãã¹ãŠã®ã¡ãœããã¯å¥ã®TestContextãååŸããŸãã ãã®ãªããžã§ã¯ãã®ã¿ã¹ã¯ã¯ããã¹ãã®éåææ§ã芳å¯ããããšã§ãã
TestContextãªããžã§ã¯ãã®tearDownïŒïŒã¡ãœããã§ã¯ãasyncAssertSuccessïŒïŒãåŒã³åºãããVerticleã®ã·ã£ããããŠã³äžã«åé¡ããããšå€±æããŸãã
ChatTest.java @RunWith(VertxUnitRunner.class) public class ChatTest { private Vertx vertx; private int port = 8080; private Logger log = LoggerFactory.getLogger(ChatTest.class);
loadVerticleTestã¡ãœããã§ãã¢ããªã±ãŒã·ã§ã³ã®èªã¿èŸŒã¿ã確èªããŸãã ã¯ã©ã€ã¢ã³ããäœæããæå®ãããã¢ãã¬ã¹ã«ãããã€ãããã¢ããªã±ãŒã·ã§ã³ãå©çšå¯èœã§ããããšã確èªããããšããŸãã æåãããšãã¹ããŒã¿ã¹ã³ãŒã200ãåãåããŸãã
次ã«ãããŒãžã®ã³ã³ãã³ãã®ååŸã詊ã¿ãŸããããŒãžã®ã¿ã€ãã«ã«ã¯ããã£ããããšããããã¹ããå«ããå¿
èŠããããŸãã
èŠæ±ãšå¿çã¯éåææäœã§ããããããã¹ãã®å®äºæã«äœããã®æ¹æ³ã§éç¥ãå¶åŸ¡ããã³åä¿¡ããå¿
èŠããããŸããããã«ã¯éåæãªããžã§ã¯ãã䜿çšãããåžžã«completeïŒïŒã¡ãœãããåŒã³åºããŠãã¹ããå®äºããŸãã
ChatTest.java @Test public void loadVerticleTest(TestContext context) { log.info("*** loadVerticleTest ***"); Async async = context.async(); vertx.createHttpClient().getNow(port, "localhost", "/", response -> { context.assertEquals(response.statusCode(), 200); context.assertEquals(response.headers().get("content-type"), "text/html"); response.bodyHandler(body -> { context.assertTrue(body.toString().contains("<title>Chat</title>")); async.complete(); }); }); }
eventBusTestã¡ãœããã§ã¯ãã€ãã³ããã¹ã¯ã©ã€ã¢ã³ããäœæããããã³ãã©ãŒããã³ã°ããŸãã ã¯ã©ã€ã¢ã³ãããã¹äžã®ã€ãã³ããåŸ
ã£ãŠããéãã¡ãã»ãŒãžãçºè¡ãããŸãã ãã³ãã©ãŒã¯ããã«å¿çããçä¿¡ã€ãã³ãã®æ¬æã®ç䟡æ§ããã§ãã¯ããŸã;æ€èšŒãæåããå Žåããã¹ãã¯async.completeïŒïŒã®åŒã³åºãã§çµäºããŸãã
ChatTest.java @Test public void eventBusTest(TestContext context) { log.info("*** eventBusTest ***"); Async async = context.async(); EventBus eb = vertx.eventBus(); eb.consumer("chat.to.server").handler(message -> { String getMsg = message.body().toString(); context.assertEquals(getMsg, "hello"); async.complete(); }); eb.publish("chat.to.server", "hello"); }
ãã¹ããå®è¡ããŸãã
æ¹æ³ãèŠã...ã¿ãMavenãããžã§ã¯ã-ã©ã€ããµã€ã¯ã«-ãã¹ã-å®è¡[ãã¹ã]ã

å®è¡å¯èœã¢ãžã¥ãŒã«ããã«ãããŠå®è¡ãã
ãããè¡ãã«ã¯ãpom.xmlã«
maven-shade-pluginãã©ã°ã€ã³ã远å ããŸãã ç§ãã¡ã®å ŽåãMain-Verticleã
Serverã¯ã©ã¹ãæãå Žæã
pom.xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.3</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>io.vertx.core.Starter</Main-Class> <Main-Verticle>Server</Main-Verticle> </manifestEntries> </transformer> </transformers> <artifactSet/> <outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar</outputFile> </configuration> </execution> </executions> </plugin>
Run Maven Buildã³ãã³ããå®è¡ãããšãchat-1.0-fat.jarãã¿ãŒã²ãããã£ã¬ã¯ããªã«è¡šç€ºãããŸãã ã¢ããªã±ãŒã·ã§ã³ãå®è¡ããã«ã¯ãå®è¡å¯èœã¢ãžã¥ãŒã«ãšwebrootãã©ã«ããŒãåããã£ã¬ã¯ããªã«ããå¿
èŠããããŸãã ããŒã12345ã§ã¢ããªã±ãŒã·ã§ã³ããããã€ããã«ã¯ã次ã®ã³ãã³ããå®è¡ããå¿
èŠããããŸãã
java -jar chat-1.0-fat.jar 12345
ããã ãã§ã é 匵ã£ãŠïŒ
å®å
šãªãœãŒã¹ã³ãŒã
Server.java import com.google.gson.Gson; import io.vertx.core.AbstractVerticle; import io.vertx.core.Starter; import io.vertx.core.logging.Logger; import io.vertx.core.logging.LoggerFactory; import io.vertx.ext.web.Router; import io.vertx.ext.web.handler.StaticHandler; import io.vertx.ext.web.handler.sockjs.BridgeEvent; import io.vertx.ext.web.handler.sockjs.BridgeOptions; import io.vertx.ext.web.handler.sockjs.PermittedOptions; import io.vertx.ext.web.handler.sockjs.SockJSHandler; import java.io.IOException; import java.net.BindException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.UnknownHostException; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import static io.vertx.ext.web.handler.sockjs.BridgeEvent.Type.*; public class Server extends AbstractVerticle { private Logger log = LoggerFactory.getLogger(Server.class); private SockJSHandler handler = null; private AtomicInteger online = new AtomicInteger(0);
VerticleLoader.java import io.vertx.core.AsyncResult; import io.vertx.core.Handler; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import io.vertx.core.impl.StringEscapeUtils; import java.io.File; import java.io.IOException; import java.util.function.Consumer; public class VerticleLoader { private static Vertx vertx; public static Vertx getVertx() { return vertx; } public static void load() { load(null); } public static void load(Handler<AsyncResult<String>> completionHandler) { VertxOptions options = new VertxOptions().setClustered(false);
ChatTest.java import io.vertx.core.Vertx; import io.vertx.core.eventbus.EventBus; import io.vertx.core.logging.Logger; import io.vertx.core.logging.LoggerFactory; import io.vertx.ext.unit.Async; import io.vertx.ext.unit.TestContext; import io.vertx.ext.unit.junit.VertxUnitRunner; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.io.IOException; @RunWith(VertxUnitRunner.class) public class ChatTest { private Vertx vertx; private int port = 8080; private Logger log = LoggerFactory.getLogger(ChatTest.class);
index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Chat</title> <meta charset="windows-1251"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="//cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js"></script> <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> <script src="date-format.js"></script> <script src="vertx-eventbus.js"></script> <style type="text/css"> body { padding-top: 40px; padding-bottom: 40px; background-color: #f5f5f5; } .received{ width: 160px; font-size: 10px; } input[type=text]:focus, textarea:focus{ box-shadow: 0 0 5px #4cae4c; border: 1px solid #4cae4c; } .tab-content{ padding:5px } </style> <script> var online = 0; // -. var eb = new EventBus("/eventbus/"); // . eb.onopen = function() { // . eb.registerHandler("chat.to.client", eventChatProcessing); }; // . function eventChatProcessing(err, msg) { var event = jQuery.parseJSON(msg.body); if (event.type == 'publish') {//. var time = Date.parse(event.time); var formattedTime = dateFormat(time, "dd.mm.yy HH:MM:ss"); // . appendMsg(event.host, event.port, event.message, formattedTime); } else { // . //type: register close. online = event.online; $('#online').text(online); } }; // . function appendMsg(host, port, message, formattedTime){ var $msg = $('<tr bgcolor="#dff0d8"><td align="left">' + formattedTime + '</td><td align="left">' + host + ' [' + port + ']' + '</td><td>' + message + '</td></tr>'); var countMsg = $('#messages tr').length; if (countMsg == 0) $('#messages').append($msg); else $('#messages > tbody > tr:first').before($msg); } $(document).ready(function() { // . $('#chatForm').submit(function(evt) { evt.preventDefault(); var message = $('#message').val(); if (message.length > 0) { // . eb.publish("chat.to.server", message); $('#message').val("").focus(); countChar(); } }); }); // . function countChar() { var len = $('#message').val().length; if (len > 140) { var msg = $('#message').val().substring(0, 140); $('#message').val(msg); } else { $('#charNum').text(140 - len); var per = 100 / 140 * len; $('#charNumProgressBar').css('width', per+'%').attr('aria-valuenow', per); } }; </script> </head> <body> <div class="container chat-wrapper"> <form id="chatForm"> <h2 align="center" class="alert alert-success">CHAT ROOM</h2> <fieldset> <div class="input-group input-group-lg"> <span class="input-group-addon" id="onlineIco"> <span class="glyphicon glyphicon-eye-open"></span> </span> <span class="input-group-addon" id="online"> <span class="glyphicon glyphicon-option-horizontal"></span> </span> <input type="text" maxlength="141" autocomplete="off" class="form-control" placeholder="What's new?" id="message" aria-describedby="sizing-addon1" onkeyup="countChar()"/> <span class="input-group-btn"> <button class="btn btn-success" type="submit"> <span class="glyphicon glyphicon-send"></span> </button> </span> </div> </fieldset> <h3 id="charNum">140</h3> <div class="progress"> <div id="charNumProgressBar" class="progress-bar progress-bar-success active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%"> <span class="sr-only">100% Complete</span> </div> </div> <div class="panel panel-success"> <div class="panel-heading"><h3>New messages</h3></div> <table id="messages" class="table table-hover" width="100%"> <colgroup> <col style="width:10%"> <col style="width:10%"> <col style="width:10%"> </colgroup> </table> </div> </form> </div> </body> </html>
æçšãªãªãœãŒã¹