Java EEエヴァンジェリストによる!EE 8最新動向!に行ってきました!
Java EEエヴァンジェリストによる!EE 8最新動向! - connpassに行ってきました。
JavaOne 2015 サンフランシスコ サマリー
@itakashさんによるJavaOneのお話。
現場での裏話(ケーキのお話とか、蟹パーティー)もあったりして楽しかったです。
それとJavaチャンピオン、JCP、などJavaに関するお話もあって初めて勉強会に参加した方がJavaに関心を持ってくれたのも嬉しかったです!
(実際1週間前に別のイベントOsaka Satellite: Rakuten Technology Conference 2015 on Nov. 21st - Mitsuyuki.Shiibaでお会いした学生さん@yfujita0929 ]が参加してJavaEEに興味を持っていただいて良かったです)
Java EE 8 最新動向
@delabasseeさんによるJavaEE8のお話。
JavaEE8で追加される機能の紹介で、JSON, HTTP2, Server Sent Eventなど盛りだくさんでした。
David Delabassee’s Presentations on SlideShare
最後に質問タイムがあって、質問者にはJavaOneのTシャツがプレゼントされました。
でServer Sent Event はJerseyですでに実装されているとお聞きしたので早速試してみました。
Chapter 15. Server-Sent Events (SSE) Supportとjersey/examples/server-sent-events at master · jersey/jersey · GitHubを参考にサーバ側を実装。
HTML5 Server-Sent Eventsを参考にクライアント側を実装。
Server Sent Event を試してみました
- 画面1(URLを指定しただけ)
- 画面2(JavaScriptで処理)
- サーバ側
EventOutput、OutboundEventなど初めて知りました。勉強しないといけないことが沢山です。(汗)
package com.mycompany.sseserversample; import java.io.IOException; import java.net.URI; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; import org.glassfish.jersey.media.sse.EventOutput; import org.glassfish.jersey.media.sse.OutboundEvent; import org.glassfish.jersey.media.sse.SseFeature; import org.glassfish.jersey.server.ResourceConfig; /** * Sever Sent Event Sample. * * @author tomo */ @Path("event/{task-cnt}/{task-interval}") public class ServerSample { public static void main(String... args) throws IOException, InterruptedException{ ResourceConfig config = new ResourceConfig(ServerSample.class, SseFeature.class); URI uri = URI.create("http://localhost:8080/"); HttpServer server = GrizzlyHttpServerFactory.createHttpServer(uri, config, false); Runtime.getRuntime().addShutdownHook(new Thread(() -> { server.shutdownNow(); })); server.start(); System.out.println("Server started. Stop the Application using CTR-C"); Thread.currentThread().join(); System.out.println("Server end."); } @GET @Produces(SseFeature.SERVER_SENT_EVENTS) public EventOutput getServerSentEvents(@PathParam("task-cnt") int taskCnt, @PathParam("task-interval") int taskInterval){ System.out.println("*taskcnt=" + taskCnt +", " + taskInterval); final EventOutput eventOutput = new EventOutput(); new Thread(() -> { try { for (int i = 0; i < taskCnt; i++) { TimeUnit.SECONDS.sleep(taskInterval); final OutboundEvent.Builder eventBuilder = new OutboundEvent.Builder(); eventBuilder.name("message-client"); eventBuilder.data(String.class, "Hello world " + i); eventBuilder.comment("comment"+ i); eventBuilder.id("id"+ i); final OutboundEvent event = eventBuilder.build(); eventOutput.write(event); } } catch (IOException | InterruptedException ex) { Logger.getLogger(ServerSample.class.getName()).log(Level.SEVERE, null, ex); } finally { try { eventOutput.close(); } catch (IOException ex) { Logger.getLogger(ServerSample.class.getName()).log(Level.SEVERE, null, ex); } } }).start(); return eventOutput; } }
- クライアント側
EventSource初めて知りました。本当に次々新しい機能があって楽しいです!
<!DOCTYPE html> <html> <head> <title>Server Sent Event Sample</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <h2>Server Sent Event Sample</h2> <div> <label>Task count:</label> <input type="number" id="task_count" /> <label>Task interval:</label> <input type="number" id="task_interval" /> </div> <div> <button id="sendBtn">Server Send Event Start</button> <button id="closeBtn">Server Send Event Close</button> </div> <div> <h3>Received Messages</h3> <output id="result"></output> </div> <script> 'usestrict'; (function(){ var sendBtn = document.getElementById('sendBtn'); var closeBtn = document.getElementById('closeBtn'); var result = document.getElementById('result'); var eventSource = null; // close button click event closeBtn.addEventListener('click', function(){ if (eventSource){ eventSource.close(); } }); // start button click event sendBtn.addEventListener('click', function(){ if (typeof (EventSource) !== void 0){ //EventSource がサポートされている場合 result.insertAdjacentHTML('beforeend', '<li>EventSource supported!</li>'); var taskCnt = document.getElementById('task_count').value; var taskInterval = document.getElementById('task_interval').value; var url = 'http://localhost:8080/event/' + taskCnt + '/' + taskInterval + '/'; eventSource = new EventSource(url); eventSource.addEventListener('message-client', function(event){ result.insertAdjacentHTML('beforeend', '<li>' + event.data + '</li>'); }); eventSource.onerror = function(){ result.insertAdjacentHTML('beforeend', '<li>EventSource Error!</li>'); eventSource.close(); }; } else { //EventSource がサポートされていない場合 result.insertAdjacentHTML('beforeend', '<li>not support EventSource</li>'); } }); }()); </script> </body> </html>
サーバ側はここGitHub - tomoTaka01/SseServerSample: Server Send Event Server Sampleにアップ
クライアントのHTMLはここHTML file for Server Sent Event JavaScript Sample · GitHubにアップ
参加者全員にJava20年のステッカーいただきました!
スタッフの方々、参加者の皆さんお疲れさまでした。とても楽しく有意義な時間を過ごせました!!!